diff --git a/modules/customer-invoices/src/web/proformas/adapters/index.ts b/modules/customer-invoices/src/web/proformas/adapters/index.ts deleted file mode 100644 index 22d61455..00000000 --- a/modules/customer-invoices/src/web/proformas/adapters/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./proforma-dto.adapter"; -export * from "./proforma-summary-dto.adapter"; diff --git a/modules/customer-invoices/src/web/proformas/adapters/proforma-dto.adapter.ts b/modules/customer-invoices/src/web/proformas/adapters/proforma-dto.adapter.ts deleted file mode 100644 index c707d2e3..00000000 --- a/modules/customer-invoices/src/web/proformas/adapters/proforma-dto.adapter.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { - MoneyDTOHelper, - PercentageDTOHelper, - QuantityDTOHelper, - type TaxCatalogProvider, -} from "@erp/core"; - -import type { Proforma, ProformaFormData, UpdateProformaInput } from "../types"; - -export type ProformaDtoAdapterContext = { - taxCatalog: TaxCatalogProvider; - currency_code: string; - language_code: string; -}; - -/** - * Convierte el DTO completo de API a datos numéricos para el formulario. - */ -export const ProformaDtoAdapter = { - fromDto(dto: Proforma, context: ProformaDtoAdapterContext): ProformaFormData { - const { taxCatalog } = context; - return { - invoice_number: dto.invoice_number, - series: dto.series, - - invoice_date: dto.invoice_date, - operation_date: dto.operation_date, - - customer_id: dto.customer_id, - recipient: dto.recipient, - - reference: dto.reference ?? "", - description: dto.description ?? "", - notes: dto.notes ?? "", - - language_code: dto.language_code, - currency_code: dto.currency_code, - - subtotal_amount: MoneyDTOHelper.toNumber(dto.subtotal_amount), - items_discount_amount: 0, - discount_percentage: PercentageDTOHelper.toNumber(dto.discount_percentage), - discount_amount: MoneyDTOHelper.toNumber(dto.discount_amount), - taxable_amount: MoneyDTOHelper.toNumber(dto.taxable_amount), - taxes_amount: MoneyDTOHelper.toNumber(dto.taxes_amount), - total_amount: MoneyDTOHelper.toNumber(dto.total_amount), - - taxes: dto.taxes.map((taxItem) => ({ - tax_code: taxItem.tax_code, - tax_label: taxCatalog.findByCode(taxItem.tax_code).match( - (tax) => tax.name, - () => "" - ), - taxable_amount: MoneyDTOHelper.toNumber(taxItem.taxable_amount), - taxes_amount: MoneyDTOHelper.toNumber(taxItem.taxes_amount), - })), - - items: dto.items.map((item) => ({ - description: item.description ?? "", - quantity: QuantityDTOHelper.toNumericString(item.quantity), - unit_amount: MoneyDTOHelper.toNumericString(item.unit_amount), - subtotal_amount: MoneyDTOHelper.toNumber(item.subtotal_amount), - discount_percentage: PercentageDTOHelper.toNumericString(item.discount_percentage), - discount_amount: MoneyDTOHelper.toNumber(item.discount_amount), - taxable_amount: MoneyDTOHelper.toNumber(item.taxable_amount), - tax_codes: item.tax_codes ?? [], - taxes_amount: MoneyDTOHelper.toNumber(item.taxes_amount), - total_amount: MoneyDTOHelper.toNumber(item.total_amount), - })), - }; - }, - - toDto(form: ProformaFormData, context: ProformaDtoAdapterContext): UpdateProformaInput { - const { currency_code, language_code } = context; - return { - series: form.series, - - invoice_date: form.invoice_date, - operation_date: form.operation_date, - - customer_id: form.customer_id, - - reference: form.reference, - description: form.description, - notes: form.notes, - - language_code, - currency_code, - - items: form.items?.map((item) => ({ - description: item.description, - quantity: QuantityDTOHelper.fromNumericString(item.quantity, 4), - unit_amount: MoneyDTOHelper.fromNumericString(item.unit_amount, currency_code, 4), - discount_percentage: PercentageDTOHelper.fromNumericString(item.discount_percentage, 2), - tax_codes: item.tax_codes, - })), - }; - }, -}; diff --git a/modules/customer-invoices/src/web/proformas/adapters/proforma-summary-dto.adapter.ts b/modules/customer-invoices/src/web/proformas/adapters/proforma-summary-dto.adapter.ts deleted file mode 100644 index 8448d203..00000000 --- a/modules/customer-invoices/src/web/proformas/adapters/proforma-summary-dto.adapter.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { MoneyDTOHelper, PercentageDTOHelper, formatCurrency } from "@erp/core"; - -import type { ProformaSummaryPage } from "../types/proforma.api.schema"; -import type { - ProformaSummaryData, - ProformaSummaryPageData, -} from "../types/proforma-summary.web.schema"; - -/** - * Convierte el DTO completo de API a datos numéricos para el formulario. - */ -export const ProformaSummaryDtoAdapter = { - fromDto(pageDto: ProformaSummaryPage, context?: unknown): ProformaSummaryPageData { - return { - ...pageDto, - items: pageDto.items.map( - (summaryDto) => - ({ - ...summaryDto, - - subtotal_amount: MoneyDTOHelper.toNumber(summaryDto.subtotal_amount), - subtotal_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.subtotal_amount), - Number(summaryDto.total_amount.scale || 2), - summaryDto.currency_code, - summaryDto.language_code - ), - - discount_percentage: PercentageDTOHelper.toNumber(summaryDto.discount_percentage), - discount_percentage_fmt: PercentageDTOHelper.toNumericString( - summaryDto.discount_percentage - ), - - discount_amount: MoneyDTOHelper.toNumber(summaryDto.discount_amount), - discount_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.discount_amount), - Number(summaryDto.total_amount.scale || 2), - summaryDto.currency_code, - summaryDto.language_code - ), - - taxable_amount: MoneyDTOHelper.toNumber(summaryDto.taxable_amount), - taxable_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.taxable_amount), - Number(summaryDto.total_amount.scale || 2), - summaryDto.currency_code, - summaryDto.language_code - ), - - taxes_amount: MoneyDTOHelper.toNumber(summaryDto.taxes_amount), - taxes_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.taxes_amount), - Number(summaryDto.total_amount.scale || 2), - summaryDto.currency_code, - summaryDto.language_code - ), - - total_amount: MoneyDTOHelper.toNumber(summaryDto.total_amount), - total_amount_fmt: formatCurrency( - MoneyDTOHelper.toNumber(summaryDto.total_amount), - Number(summaryDto.total_amount.scale || 2), - summaryDto.currency_code, - summaryDto.language_code - ), - - //taxes: dto.taxes, - }) as unknown as ProformaSummaryData - ), - }; - }, -}; diff --git a/modules/customer-invoices/src/web/proformas/hooks/index.ts b/modules/customer-invoices/src/web/proformas/hooks/index.ts deleted file mode 100644 index 1f1631c0..00000000 --- a/modules/customer-invoices/src/web/proformas/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./use-issue-proforma-invoice"; -export * from "./use-proformas-query"; diff --git a/modules/customer-invoices/src/web/proformas/hooks/use-delete-proforma-mutation.ts.bak b/modules/customer-invoices/src/web/proformas/hooks/use-delete-proforma-mutation.ts.bak deleted file mode 100644 index 0b135939..00000000 --- a/modules/customer-invoices/src/web/proformas/hooks/use-delete-proforma-mutation.ts.bak +++ /dev/null @@ -1,70 +0,0 @@ -import { - useDataSource -} from ("@erp/core/hooks"); - -import { useMutation, useQueryClient } from "@tanstack/react-query"; - -import type { InvoiceFormData } from "../schemas"; - -export const CUSTOMER_INVOICES_LIST_KEY = ["customer-invoices"] as const; - -type UpdateCustomerInvoiceContext = {}; - -type UpdateCustomerInvoicePayload = { - id: string; - data: Partial; -}; - -export function useDeleteProforma() { - const queryClient = useQueryClient(); - const dataSource = useDataSource(); - - return useMutation<{ id: string }, Error>({ - mutationKey: ["customer-invoice:delete", id], - - mutationFn: async (payload) => { - const { id: proformaId } = payload; - - if (!proformaId) { - throw new Error("proformaId is required"); - } - - await dataSource.deleteOne("proformas", proformaId); - }, - - onMutate: async ({ id }) => { - await queryClient.cancelQueries({ queryKey: [CUSTOMERS_LIST_SCOPE] }); - - const snapshots = getAllCustomerListQueryKeys(queryClient).map((key) => ({ - key, - page: queryClient.getQueryData(key), - })); - - for (const { key, page } of snapshots) { - if (!page) continue; - queryClient.setQueryData(key, { - ...page, - items: page.items.filter((c) => c.id !== id), - totalItems: Math.max(0, page.totalItems - 1), - }); - } - return { snapshots }; - }, - - onError: (_e, _v, ctx) => { - if (!ctx) return; - for (const snap of ctx.snapshots as Array<{ key: QueryKey; page?: CustomersPage }>) { - if (snap.page) queryClient.setQueryData(snap.key, snap.page); - } - }, - - onSuccess: ({ id }) => { - // Limpia cache de detalle - queryClient.removeQueries({ queryKey: buildCustomerQueryKey(id) }); - }, - - onSettled: () => { - queryClient.invalidateQueries({ queryKey: [CUSTOMERS_LIST_SCOPE] }); - }, - }); -} diff --git a/modules/customer-invoices/src/web/proformas/hooks/use-issue-proforma-invoice.ts b/modules/customer-invoices/src/web/proformas/hooks/use-issue-proforma-invoice.ts deleted file mode 100644 index 39d7c10b..00000000 --- a/modules/customer-invoices/src/web/proformas/hooks/use-issue-proforma-invoice.ts +++ /dev/null @@ -1,26 +0,0 @@ -// hooks/use-issue-proforma-invoice.ts - -import { useDataSource } from "@erp/core/hooks"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; - -export const ISSUE_PROFORMA_INVOICE_KEY = ["proformas", "issue"] as const; - -interface IssueProformaInvoicePayload { - proformaId: string; -} - -export function useIssueProformaInvoice() { - const dataSource = useDataSource(); - const queryClient = useQueryClient(); - - return useMutation({ - mutationKey: ISSUE_PROFORMA_INVOICE_KEY, - mutationFn: ({ proformaId }: IssueProformaInvoicePayload) => - issueProformaInvoiceApi(dataSource, proformaId), - - onSuccess() { - queryClient.invalidateQueries({ queryKey: ["proformas"] }); - queryClient.invalidateQueries({ queryKey: ["invoices"] }); - }, - }); -} diff --git a/modules/customer-invoices/src/web/proformas/hooks/use-proforma-actions.ts b/modules/customer-invoices/src/web/proformas/hooks/use-proforma-actions.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/modules/customer-invoices/src/web/proformas/hooks/use-proforma-items-columns.tsx b/modules/customer-invoices/src/web/proformas/hooks/use-proforma-items-columns.tsx deleted file mode 100644 index 02cd27bb..00000000 --- a/modules/customer-invoices/src/web/proformas/hooks/use-proforma-items-columns.tsx +++ /dev/null @@ -1,323 +0,0 @@ -import { DataTableColumnHeader } from "@repo/rdx-ui/components"; -import { InputGroup, InputGroupTextarea } from "@repo/shadcn-ui/components"; -import { cn } from "@repo/shadcn-ui/lib/utils"; -import type { ColumnDef } from "@tanstack/react-table"; -import * as React from "react"; -import { Controller, useFormContext } from "react-hook-form"; - -import { useProformaContext } from "../pages/update/context"; -import { AmountInputField } from "../ui/components/amount-input-field"; -import { PercentageInputField } from "../ui/components/percentage-input-field"; -import { QuantityInputField } from "../ui/components/quantity-input-field"; - -export interface ProformaItemFormData { - id: string; // ← mapea RHF field.id aquí - description: string; - quantity: number | ""; - unit_amount: number | ""; - discount_percentage: number | ""; - discount_amount: number | ""; - taxable_amount: number | ""; - tax_codes: string[]; - taxes_amount: number | ""; - total_amount: number | ""; // readonly calculado -} -export interface ProformaFormData { - items: ProformaItemFormData[]; -} - -export function useProformaItemsColumns(): ColumnDef[] { - const { t, readOnly, currency_code, language_code } = useProformaContext(); - const { control } = useFormContext(); - - // Atención: Memoizar siempre para evitar reconstrucciones y resets de estado de tabla - return React.useMemo[]>( - () => [ - { - id: "position", - header: ({ column }) => ( - - ), - cell: ({ row }) => row.index + 1, - enableSorting: false, - size: 32, - }, - { - accessorKey: "description", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - ( - - { - const el = e.currentTarget; - el.style.height = "auto"; - el.style.height = `${el.scrollHeight}px`; - }} - // auto-grow simple - readOnly={readOnly} - rows={1} - spellCheck - /> - {/* - Line 1, Column 1 - - - Send - - */} - - )} - /> - ), - enableSorting: false, - size: 480, - minSize: 240, - maxSize: 768, - }, - { - accessorKey: "quantity", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableSorting: false, - size: 52, - minSize: 48, - maxSize: 64, - }, - { - accessorKey: "unit_amount", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableSorting: false, - size: 120, - minSize: 100, - maxSize: 160, - }, - { - accessorKey: "discount_percentage", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableSorting: false, - size: 40, - minSize: 40, - }, - { - accessorKey: "discount_amount", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableHiding: true, - enableSorting: false, - size: 120, - minSize: 100, - maxSize: 160, - }, - { - accessorKey: "taxable_amount", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableHiding: true, - enableSorting: false, - size: 120, - minSize: 100, - maxSize: 160, - }, - { - accessorKey: "tax_codes", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - ( - - )} - /> - ), - enableSorting: false, - size: 120, - minSize: 130, - maxSize: 180, - }, - { - accessorKey: "taxes_amount", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - ), - enableSorting: false, - size: 120, - minSize: 100, - maxSize: 160, - }, - { - accessorKey: "total_amount", - header: ({ column }) => ( - - ), - cell: ({ row }) => ( - - - - ), - enableSorting: false, - size: 120, - minSize: 100, - maxSize: 160, - }, - { - id: "actions", - header: ({ column }) => ( - - ), - cell: ({ row, table }) => , - enableSorting: false, - size: 100, - minSize: 100, - maxSize: 100, - }, - ], - [t, readOnly, control, currency_code, language_code] - ); -} diff --git a/modules/customer-invoices/src/web/proformas/hooks/use-proformas-query.ts b/modules/customer-invoices/src/web/proformas/hooks/use-proformas-query.ts deleted file mode 100644 index 9fcc3516..00000000 --- a/modules/customer-invoices/src/web/proformas/hooks/use-proformas-query.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { CriteriaDTO } from "@erp/core"; -import { useDataSource } from "@erp/core/hooks"; -import { INITIAL_PAGE_INDEX, INITIAL_PAGE_SIZE } from "@repo/rdx-criteria"; -import { type DefaultError, type QueryKey, useQuery } from "@tanstack/react-query"; - -import type { ProformaSummaryPage } from "../types/proforma.api.schema"; - -export const PROFORMAS_QUERY_KEY = (criteria?: CriteriaDTO): QueryKey => [ - "proforma", - { - pageNumber: criteria?.pageNumber ?? INITIAL_PAGE_INDEX, - pageSize: criteria?.pageSize ?? INITIAL_PAGE_SIZE, - q: criteria?.q ?? "", - filters: criteria?.filters ?? [], - orderBy: criteria?.orderBy ?? "", - order: criteria?.order ?? "", - }, -]; - -type ProformasQueryOptions = { - enabled?: boolean; - criteria?: CriteriaDTO; -}; - -// Obtener todas las facturas -export const useProformasQuery = (options?: ProformasQueryOptions) => { - const dataSource = useDataSource(); - const enabled = options?.enabled ?? true; - const criteria = options?.criteria ?? {}; - - return useQuery({ - queryKey: PROFORMAS_QUERY_KEY(criteria), - queryFn: async ({ signal }) => { - return await dataSource.getList("proformas", { - signal, - ...criteria, - }); - }, - enabled, - placeholderData: (previousData, _previousQuery) => previousData, // Mantener datos previos mientras se carga nueva datos (antiguo `keepPreviousData`) - }); -}; diff --git a/modules/customer-invoices/src/web/proformas/schemas/index.ts b/modules/customer-invoices/src/web/proformas/schemas/index.ts deleted file mode 100644 index e69de29b..00000000