diff --git a/apps/web/index.html b/apps/web/index.html index ec999fa2..5ec17b9b 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -10,9 +10,6 @@ - FactuGES 2025 diff --git a/modules/customer-invoices/src/api/application/helpers/format-percentage-dto.ts b/modules/customer-invoices/src/api/application/helpers/format-percentage-dto.ts new file mode 100644 index 00000000..4d72baad --- /dev/null +++ b/modules/customer-invoices/src/api/application/helpers/format-percentage-dto.ts @@ -0,0 +1,11 @@ +import { PercentageDTO } from "@erp/core"; +import { Percentage } from "@repo/rdx-ddd"; + +export function formatPercentageDTO(Percentage_value: PercentageDTO) { + const value = Percentage.create({ + value: Number(Percentage_value.value), + scale: Number(Percentage_value.scale), + }).data; + + return value.toNumber; +} diff --git a/modules/customer-invoices/src/api/application/helpers/index.ts b/modules/customer-invoices/src/api/application/helpers/index.ts index 907223bb..20a90177 100644 --- a/modules/customer-invoices/src/api/application/helpers/index.ts +++ b/modules/customer-invoices/src/api/application/helpers/index.ts @@ -1,2 +1,3 @@ export * from "./format-money-dto"; +export * from "./format-percentage-dto"; export * from "./map-dto-to-customer-invoice-props"; diff --git a/modules/customer-invoices/src/api/application/helpers/quantity-dto.ts b/modules/customer-invoices/src/api/application/helpers/quantity-dto.ts new file mode 100644 index 00000000..ce5d39a8 --- /dev/null +++ b/modules/customer-invoices/src/api/application/helpers/quantity-dto.ts @@ -0,0 +1,12 @@ +import { MoneyDTO } from "@erp/core"; +import { MoneyValue } from "@repo/rdx-ddd"; + +export function formatMoneyDTO(amount: MoneyDTO, locale: string) { + const money = MoneyValue.create({ + value: Number(amount.value), + currency_code: amount.currency_code, + scale: Number(amount.scale), + }).data; + + return money.format(locale); +} diff --git a/modules/customer-invoices/src/api/application/presenters/queries/customer-invoice.report.presenter.ts b/modules/customer-invoices/src/api/application/presenters/queries/customer-invoice.report.presenter.ts index 1000c31a..8ee49ed8 100644 --- a/modules/customer-invoices/src/api/application/presenters/queries/customer-invoice.report.presenter.ts +++ b/modules/customer-invoices/src/api/application/presenters/queries/customer-invoice.report.presenter.ts @@ -1,6 +1,6 @@ import { Presenter } from "@erp/core/api"; import { GetCustomerInvoiceByIdResponseDTO } from "../../../../common/dto"; -import { formatMoneyDTO } from "../../helpers"; +import { formatMoneyDTO, formatPercentageDTO } from "../../helpers"; export class CustomerInvoiceReportPresenter extends Presenter< GetCustomerInvoiceByIdResponseDTO, @@ -11,6 +11,10 @@ export class CustomerInvoiceReportPresenter extends Presenter< return { ...invoiceDTO, + subtotal_amount: formatMoneyDTO(invoiceDTO.subtotal_amount, locale), + percentage: formatPercentageDTO(invoiceDTO.discount_percentage), + discount_amount: formatMoneyDTO(invoiceDTO.discount_amount, locale), + taxes_amount: formatMoneyDTO(invoiceDTO.taxes_amount, locale), total_amount: formatMoneyDTO(invoiceDTO.total_amount, locale), }; } diff --git a/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs b/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs index 624ca84e..0331e031 100644 --- a/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs +++ b/modules/customer-invoices/src/api/application/use-cases/report/reporter/templates/customer-invoice/template.hbs @@ -182,25 +182,29 @@
+ {{#if percentage}} - + + {{else}} + + {{/if}} - + - + - +
Importe neto 761,14 €
Descuento 0%0{{discount_amount.value}}
Base imponible765,14€{{subtotal_amount}}
IVA 21%159,84 €{{taxes_amount}}
Total factura960,56 €{{total_amount}}
diff --git a/modules/customers/src/web/components/form-debug.tsx b/modules/customers/src/web/components/form-debug.tsx new file mode 100644 index 00000000..c5be808d --- /dev/null +++ b/modules/customers/src/web/components/form-debug.tsx @@ -0,0 +1,34 @@ +import { UseFormReturn } from "react-hook-form"; + +export const FormDebug = ({ form }: { form: UseFormReturn }) => { + const { + watch, + formState: { isDirty, dirtyFields, defaultValues }, + } = form; + + const currentValues = watch(); + + return ( +
+

+ ¿Formulario modificado? {isDirty ? "Sí" : "No"} +

+
+ Campos modificados: + {Object.keys(dirtyFields).length > 0 ? ( +
    + {Object.keys(dirtyFields).map((campo) => ( +
  • + {campo}:{" "} + {String(defaultValues![campo])}{" "} + ➝ {String(currentValues[campo])} +
  • + ))} +
+ ) : ( +

Ninguno

+ )} +
+
+ ); +}; diff --git a/modules/customers/src/web/components/index.ts b/modules/customers/src/web/components/index.ts index b3a10d5b..72f39232 100644 --- a/modules/customers/src/web/components/index.ts +++ b/modules/customers/src/web/components/index.ts @@ -3,4 +3,5 @@ export * from "./customer-editor-skeleton"; export * from "./customers-layout"; export * from "./customers-list-grid"; export * from "./error-alert"; +export * from "./form-debug"; export * from "./not-found-card"; diff --git a/modules/customers/src/web/pages/update/customer-additional-config-fields.tsx b/modules/customers/src/web/pages/update/customer-additional-config-fields.tsx new file mode 100644 index 00000000..f5bbee99 --- /dev/null +++ b/modules/customers/src/web/pages/update/customer-additional-config-fields.tsx @@ -0,0 +1,60 @@ +import { TaxesMultiSelectField } from "@erp/core/components"; +import { SelectField, TextAreaField } from "@repo/rdx-ui/components"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@repo/shadcn-ui/components"; +import { CURRENCY_OPTIONS, LANGUAGE_OPTIONS } from "../../constants"; +import { useTranslation } from "../../i18n"; + +export function CustomerAdditionalConfigFields({ control }: { control: any }) { + const { t } = useTranslation(); + + return ( + + + {t("form_groups.additional_config.title")} + {t("form_groups.additional_config.description")} + + + + + + + + + ); +} diff --git a/modules/customers/src/web/pages/update/customer-address-fields.tsx b/modules/customers/src/web/pages/update/customer-address-fields.tsx new file mode 100644 index 00000000..f8e2a4c9 --- /dev/null +++ b/modules/customers/src/web/pages/update/customer-address-fields.tsx @@ -0,0 +1,67 @@ +import { SelectField, TextField } from "@repo/rdx-ui/components"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@repo/shadcn-ui/components"; +import { COUNTRY_OPTIONS } from "../../constants"; +import { useTranslation } from "../../i18n"; + +export function CustomerAddressFields({ control }: { control: any }) { + const { t } = useTranslation(); + + return ( + + + {t("form_groups.address.title")} + {t("form_groups.address.description")} + + + + + + + + + + ); +} diff --git a/modules/customers/src/web/pages/update/customer-basic-info-fields.tsx b/modules/customers/src/web/pages/update/customer-basic-info-fields.tsx new file mode 100644 index 00000000..e36b854b --- /dev/null +++ b/modules/customers/src/web/pages/update/customer-basic-info-fields.tsx @@ -0,0 +1,88 @@ +import { TextField } from "@repo/rdx-ui/components"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, + RadioGroup, + RadioGroupItem, +} from "@repo/shadcn-ui/components"; +import { useTranslation } from "../../i18n"; + +export function CustomerBasicInfoFields({ control }: { control: any }) { + const { t } = useTranslation(); + + return ( + + + {t("form_groups.basic_info.title")} + {t("form_groups.basic_info.description")} + + + ( + + {t("form_fields.customer_type.label")} + + field.onChange(val === "1")} + className='flex gap-6' + > + + + + + + {t("form_fields.customer_type.company")} + + + + + + + + {t("form_fields.customer_type.individual")} + + + + + + + )} + /> + + + + + + + ); +} diff --git a/modules/customers/src/web/pages/update/customer-contact-fields.tsx b/modules/customers/src/web/pages/update/customer-contact-fields.tsx new file mode 100644 index 00000000..2834def1 --- /dev/null +++ b/modules/customers/src/web/pages/update/customer-contact-fields.tsx @@ -0,0 +1,81 @@ +import { TextField } from "@repo/rdx-ui/components"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@repo/shadcn-ui/components"; +import { useTranslation } from "../../i18n"; + +export function CustomerContactFields({ control }: { control: any }) { + const { t } = useTranslation(); + + return ( + + + {t("form_groups.contact_info.title")} + {t("form_groups.contact_info.description")} + + + + + + + + + + + + + ); +} diff --git a/modules/customers/src/web/pages/update/customer-edit-form.tsx b/modules/customers/src/web/pages/update/customer-edit-form.tsx index d9d23d84..89f5d8ec 100644 --- a/modules/customers/src/web/pages/update/customer-edit-form.tsx +++ b/modules/customers/src/web/pages/update/customer-edit-form.tsx @@ -1,29 +1,16 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { FieldErrors, useForm } from "react-hook-form"; -import { TaxesMultiSelectField } from "@erp/core/components"; -import { SelectField, TextAreaField, TextField } from "@repo/rdx-ui/components"; -import { - Button, - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, - RadioGroup, - RadioGroupItem, -} from "@repo/shadcn-ui/components"; +import { Form } from "@repo/shadcn-ui/components"; import { useUnsavedChangesNotifier } from "@erp/core/hooks"; -import { COUNTRY_OPTIONS, LANGUAGE_OPTIONS } from "../../constants/customer.constants"; +import { FormDebug } from "../../components/form-debug"; import { useTranslation } from "../../i18n"; import { CustomerData, CustomerUpdateData, CustomerUpdateSchema } from "../../schemas"; +import { CustomerAdditionalConfigFields } from "./customer-additional-config-fields"; +import { CustomerAddressFields } from "./customer-address-fields"; +import { CustomerBasicInfoFields } from "./customer-basic-info-fields"; +import { CustomerContactFields } from "./customer-contact-fields"; interface CustomerFormProps { formId: string; @@ -63,262 +50,16 @@ export const CustomerEditForm = ({ formId, data, onSubmit, isPending }: Customer form.reset(data); }; - const { - formState: { isDirty, dirtyFields }, - } = form; - return (
-
-

- ¿Formulario modificado? {isDirty ? "Sí" : "No"} -

-

- Campos modificados:{" "} - {Object.keys(dirtyFields).length > 0 ? Object.keys(dirtyFields).join(", ") : "Ninguno"} -

-
{" "} +
- {/* Información básica */} - - - {t("form_groups.basic_info.title")} - {t("form_groups.basic_info.description")} - - - ( - - {t("form_fields.customer_type.label")} - - field.onChange(value === "1")} - defaultValue={field.value ? "1" : "0"} - className='flex gap-6' - > - - - - - - {t("form_fields.customer_type.company")} - - - - - - - - - {t("form_fields.customer_type.individual")} - - - - - - - )} - /> - - - - - - - - - - {/* Dirección */} - - - {t("form_groups.address.title")} - {t("form_groups.address.description")} - - - - - - - - - - - - - - - {/* Contacto */} - - - {t("form_groups.contact_info.title")} - {t("form_groups.contact_info.description")} - - - - - - - - - - - - - - - - - - - - - {/* Configuraciones Adicionales */} - - - {t("form_groups.additional_config.title")} - {t("form_groups.additional_config.description")} - - - - - - - - - + + + +
- ); diff --git a/packages/rdx-ui/src/components/form/TextField.tsx b/packages/rdx-ui/src/components/form/TextField.tsx index f4cd2cc2..f0ddef74 100644 --- a/packages/rdx-ui/src/components/form/TextField.tsx +++ b/packages/rdx-ui/src/components/form/TextField.tsx @@ -37,6 +37,9 @@ export function TextField({ const { t } = useTranslation(); const isDisabled = disabled || readOnly; + const { getFieldState } = control; + const state = getFieldState(name); + return ( ({
)} - +

diff --git a/packages/shadcn-ui/src/styles/globals.css b/packages/shadcn-ui/src/styles/globals.css index 82e3649e..37c13160 100644 --- a/packages/shadcn-ui/src/styles/globals.css +++ b/packages/shadcn-ui/src/styles/globals.css @@ -50,9 +50,9 @@ } @theme inline { - --font-sans: Geist, sans-serif; + /*--font-sans: Geist, sans-serif; --font-serif: Merriweather, serif; - --font-mono: "Geist Mono", monospace; + --font-mono: "Geist Mono", monospace;*/ --color-background: var(--background); --color-foreground: var(--foreground); @@ -168,6 +168,14 @@ body { @apply bg-background text-foreground; } + + input { + @apply font-semibold; + } + + label { + @apply font-light; + } } @source "../components";