From 6be0ad686cf13785b6b4c1fe8ef241fa8875845b Mon Sep 17 00:00:00 2001 From: david Date: Sun, 9 Nov 2025 12:05:33 +0100 Subject: [PATCH] . --- .../web/components/editor/invoice-totals.tsx | 94 ++++++------- .../components/editor/items/items-editor.tsx | 125 +++++++++--------- 2 files changed, 110 insertions(+), 109 deletions(-) diff --git a/modules/customer-invoices/src/web/components/editor/invoice-totals.tsx b/modules/customer-invoices/src/web/components/editor/invoice-totals.tsx index 1cb17346..a7694deb 100644 --- a/modules/customer-invoices/src/web/components/editor/invoice-totals.tsx +++ b/modules/customer-invoices/src/web/components/editor/invoice-totals.tsx @@ -1,6 +1,12 @@ import { formatCurrency } from "@erp/core"; -import { FieldDescription, FieldGroup, FieldLegend, FieldSet, Separator } from '@repo/shadcn-ui/components'; -import { cn } from '@repo/shadcn-ui/lib/utils'; +import { + FieldDescription, + FieldGroup, + FieldLegend, + FieldSet, + Separator, +} from "@repo/shadcn-ui/components"; +import { cn } from "@repo/shadcn-ui/lib/utils"; import { ReceiptIcon } from "lucide-react"; import { ComponentProps } from "react"; import { useFormContext, useWatch } from "react-hook-form"; @@ -20,46 +26,55 @@ export const InvoiceTotals = (props: ComponentProps<"fieldset">) => { defaultValue: [], }); + const subtotal_amount = useWatch({ + control, + name: "subtotal_amount", + defaultValue: 0, + }); return (
- {t("form_groups.totals.title")} + + {t("form_groups.totals.title")} {t("form_groups.totals.description")} -
{/* Sección: Subtotal y Descuentos */} -
- Subtotal sin descuento - - {formatCurrency(getValues('subtotal_amount'), 2, currency_code, language_code)} +
+ Subtotal sin descuento + + {formatCurrency(subtotal_amount, 2, currency_code, language_code)}
-
-
- Descuento global +
+
+ Descuento global
- -{formatCurrency(getValues("discount_amount"), 2, currency_code, language_code)} + + -{formatCurrency(getValues("discount_amount"), 2, currency_code, language_code)} +
- {/* Sección: Base Imponible */} -
- Base imponible - - {formatCurrency(getValues('taxable_amount'), 2, currency_code, language_code)} +
+ Base imponible + + {formatCurrency(getValues("taxable_amount"), 2, currency_code, language_code)}
@@ -67,10 +82,8 @@ export const InvoiceTotals = (props: ComponentProps<"fieldset">) => { {/* Sección: Impuestos */} -
-

+
+

Impuestos y retenciones

@@ -88,9 +101,7 @@ export const InvoiceTotals = (props: ComponentProps<"fieldset">) => { if (taxesInGroup?.length === 0) return null; return ( - - -
+
{taxesInGroup?.map((item) => { const tax = taxCatalog.findByCode(item.tax_code).match( (t) => t, @@ -99,43 +110,36 @@ export const InvoiceTotals = (props: ComponentProps<"fieldset">) => { return (
- {tax?.name} - - {formatCurrency( - item.taxes_amount, - 2, - currency_code, - language_code - )} + {tax?.name} + + {formatCurrency(item.taxes_amount, 2, currency_code, language_code)}
); })}
- ); })} -
- Total de impuestos - - {formatCurrency(getValues('taxes_amount'), 2, currency_code, language_code)} +
+ Total de impuestos + + {formatCurrency(getValues("taxes_amount"), 2, currency_code, language_code)}
-
- Total de la factura - - {formatCurrency(getValues('total_amount'), 2, currency_code, language_code)} +
+ Total de la factura + + {formatCurrency(getValues("total_amount"), 2, currency_code, language_code)}
- -

+ ); }; diff --git a/modules/customer-invoices/src/web/components/editor/items/items-editor.tsx b/modules/customer-invoices/src/web/components/editor/items/items-editor.tsx index 303feb9a..02a64016 100644 --- a/modules/customer-invoices/src/web/components/editor/items/items-editor.tsx +++ b/modules/customer-invoices/src/web/components/editor/items/items-editor.tsx @@ -1,49 +1,47 @@ -import { DataTable, useWithRowSelection } from '@repo/rdx-ui/components'; -import { useMemo } from 'react'; +import { DataTable, useWithRowSelection } from "@repo/rdx-ui/components"; +import { useMemo } from "react"; import { useFieldArray, useFormContext } from "react-hook-form"; -import { useInvoiceContext } from '../../../context'; -import { useInvoiceAutoRecalc } from '../../../hooks'; -import { useTranslation } from '../../../i18n'; -import { InvoiceFormData, defaultCustomerInvoiceItemFormData } from '../../../schemas'; -import { debugIdCol } from './debug-id-col'; -import { ItemRowEditor } from './item-row-editor'; -import { useItemsColumns } from './use-items-columns'; - +import { useInvoiceContext } from "../../../context"; +import { useInvoiceAutoRecalc } from "../../../hooks"; +import { useTranslation } from "../../../i18n"; +import { defaultCustomerInvoiceItemFormData, InvoiceFormData } from "../../../schemas"; +import { debugIdCol } from "./debug-id-col"; +import { ItemRowEditor } from "./item-row-editor"; +import { useItemsColumns } from "./use-items-columns"; const createEmptyItem = () => defaultCustomerInvoiceItemFormData; export const ItemsEditor = () => { - const { t } = useTranslation(); - const context = useInvoiceContext(); - const form = useFormContext(); - const { control, getValues } = form; + const { t } = useTranslation(); + const context = useInvoiceContext(); + const form = useFormContext(); + const { control, getValues } = form; - useInvoiceAutoRecalc(form, context); + useInvoiceAutoRecalc(form, context); - const { fields, append, remove, move, insert, update } = useFieldArray({ - control, - name: "items", - }); + const { fields, append, remove, move, insert, update } = useFieldArray({ + control, + name: "items", + }); - const baseColumns = useWithRowSelection(useItemsColumns(), true); - const columns = useMemo( - () => [...baseColumns, debugIdCol], - [baseColumns] - ); + const baseColumns = useWithRowSelection(useItemsColumns(), true); + const columns = useMemo(() => [...baseColumns, debugIdCol], [baseColumns]); - return ( -
- append({ ...createEmptyItem() }), - //appendItem: (item: any) => append(item), - }, - rowOps: { - remove: (i: number) => remove(i), - move: (from: number, to: number) => move(from, to), - //insertItem: (index: number, item: any) => insert(index, item), - /*duplicateItems: (indexes: number[], table: Table) => { + return ( +
+ append({ ...createEmptyItem() }), + //appendItem: (item: any) => append(item), + }, + rowOps: { + remove: (i: number) => remove(i), + move: (from: number, to: number) => move(from, to), + //insertItem: (index: number, item: any) => insert(index, item), + /*duplicateItems: (indexes: number[], table: Table) => { const items = getValues("items") || []; // duplicate in descending order to keep indexes stable [...indexes].sort((a, b) => b - a).forEach(i => { @@ -54,34 +52,33 @@ export const ItemsEditor = () => { } }); },*/ - /*deleteItems: (indexes: number[]) => { + /*deleteItems: (indexes: number[]) => { // remove in descending order to avoid shifting issues [...indexes].sort((a, b) => b - a).forEach(i => remove(i)); },*/ - //updateItem: (index: number, item: any) => update(index, item), - }, - bulkOps: { - duplicateSelected: (indexes, table) => { - const originalData = indexes.map((i) => { - const { id, ...original } = table.getRowModel().rows[i].original; - return original; - }); - - insert(indexes[indexes.length - 1] + 1, originalData, { shouldFocus: true }); - table.resetRowSelection(); - }, - removeSelected: (indexes) => indexes.sort((a, b) => b - a).forEach(remove), - moveSelectedUp: (indexes) => indexes.forEach((i) => move(i, i - 1)), - moveSelectedDown: (indexes) => [...indexes].reverse().forEach((i) => move(i, i + 1)), - } - }} - enableRowSelection - enablePagination={false} - pageSize={999} - readOnly={false} - EditorComponent={ItemRowEditor} - /> -
- ); -} + //updateItem: (index: number, item: any) => update(index, item), + }, + bulkOps: { + duplicateSelected: (indexes, table) => { + const originalData = indexes.map((i) => { + const { id, ...original } = table.getRowModel().rows[i].original; + return original; + }); + insert(indexes[indexes.length - 1] + 1, originalData, { shouldFocus: true }); + table.resetRowSelection(); + }, + removeSelected: (indexes) => indexes.sort((a, b) => b - a).forEach(remove), + moveSelectedUp: (indexes) => indexes.forEach((i) => move(i, i - 1)), + moveSelectedDown: (indexes) => [...indexes].reverse().forEach((i) => move(i, i + 1)), + }, + }} + enableRowSelection + enablePagination={false} + pageSize={999} + readOnly={false} + EditorComponent={ItemRowEditor} + /> +
+ ); +};