From b35b89ee2bffb306b4f01dcf75c90473de7cae4d Mon Sep 17 00:00:00 2001 From: david Date: Sat, 4 Apr 2026 01:39:03 +0200 Subject: [PATCH] Customers --- .../domain/aggregates/customer.aggregate.ts | 10 ++- .../domain/value-objects/customer-taxes.vo.ts | 7 ++ .../ui/editor/customer-basic-info-fields.tsx | 87 +++++++++++-------- .../update/ui/editor/customer-edit-form.tsx | 5 +- .../ui/editor/customer-taxes-multi-select.tsx | 27 +++--- 5 files changed, 82 insertions(+), 54 deletions(-) diff --git a/modules/customers/src/api/domain/aggregates/customer.aggregate.ts b/modules/customers/src/api/domain/aggregates/customer.aggregate.ts index bbb89c1c..ec0268fb 100644 --- a/modules/customers/src/api/domain/aggregates/customer.aggregate.ts +++ b/modules/customers/src/api/domain/aggregates/customer.aggregate.ts @@ -149,7 +149,7 @@ export class Customer extends AggregateRoot implements IC } public update(partialCustomer: CustomerPatchProps): Result { - const { address: partialAddress, ...rest } = partialCustomer; + const { address: partialAddress, defaultTaxes: partialTaxes, ...rest } = partialCustomer; Object.assign(this.props, rest); @@ -161,6 +161,14 @@ export class Customer extends AggregateRoot implements IC } } + if (partialTaxes) { + const taxesResult = this.defaultTaxes.update(partialTaxes); + + if (taxesResult.isFailure) { + return Result.fail(taxesResult.error); + } + } + return Result.ok(); } diff --git a/modules/customers/src/api/domain/value-objects/customer-taxes.vo.ts b/modules/customers/src/api/domain/value-objects/customer-taxes.vo.ts index e73797ae..ea5fd6aa 100644 --- a/modules/customers/src/api/domain/value-objects/customer-taxes.vo.ts +++ b/modules/customers/src/api/domain/value-objects/customer-taxes.vo.ts @@ -17,11 +17,18 @@ export interface ICustomerItemTaxes { toKey(): string; // Clave para representar un trío. } +export type CustomerTaxesPatchProps = Partial; + export class CustomerTaxes extends ValueObject implements ICustomerItemTaxes { static create(props: CustomerTaxesProps) { return Result.ok(new CustomerTaxes(props)); } + public update(partial: CustomerTaxesPatchProps): Result { + Object.assign(this.props, partial); + return Result.ok(); + } + /** * Reconstruye una instancia de CustomerTaxes a partir de una clave serializada. * Este método es la operación inversa de toKey(). diff --git a/modules/customers/src/web/update/ui/editor/customer-basic-info-fields.tsx b/modules/customers/src/web/update/ui/editor/customer-basic-info-fields.tsx index 4bd6e641..99d25165 100644 --- a/modules/customers/src/web/update/ui/editor/customer-basic-info-fields.tsx +++ b/modules/customers/src/web/update/ui/editor/customer-basic-info-fields.tsx @@ -1,13 +1,13 @@ import { FormFieldLabel, TextAreaField, TextField } from "@repo/rdx-ui/components"; import { Field, + FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSet, - FormControl, RadioGroup, RadioGroupItem, } from "@repo/shadcn-ui/components"; @@ -19,15 +19,9 @@ import type { CustomerUpdateForm } from "../../entities"; import { CustomerTaxesMultiSelect } from "./customer-taxes-multi-select"; -interface CustomerBasicInfoFieldsProps extends React.ComponentProps { - focusRef?: React.RefObject; -} +interface CustomerBasicInfoFieldsProps extends React.ComponentProps {} -export const CustomerBasicInfoFields = ({ - focusRef, - className, - ...props -}: CustomerBasicInfoFieldsProps) => { +export const CustomerBasicInfoFields = ({ className, ...props }: CustomerBasicInfoFieldsProps) => { const { t } = useTranslation(); const { control, setFocus } = useFormContext(); @@ -50,49 +44,68 @@ export const CustomerBasicInfoFields = ({ required /> - - ( - + { + console.log(field.value); + return ( + {t("form_fields.customer_type.label")} - - field.onChange(value === "true")} - value={String(field.value)} - > -
- - -
+ + +
-
- - -
- - + + +
+ {t("form_fields.customer_type.description")}
- )} - /> - + ); + }} + /> ) => void; className?: string; - focusRef?: React.RefObject; }; -export const CustomerEditForm = ({ formId, onSubmit, className, focusRef }: CustomerFormProps) => { +export const CustomerEditForm = ({ formId, onSubmit, className }: CustomerFormProps) => { return (
- + diff --git a/modules/customers/src/web/update/ui/editor/customer-taxes-multi-select.tsx b/modules/customers/src/web/update/ui/editor/customer-taxes-multi-select.tsx index 35146c25..7c476b2f 100644 --- a/modules/customers/src/web/update/ui/editor/customer-taxes-multi-select.tsx +++ b/modules/customers/src/web/update/ui/editor/customer-taxes-multi-select.tsx @@ -5,33 +5,34 @@ import { useCallback, useMemo } from "react"; import { useTranslation } from "../../../i18n"; -interface CustomerTaxesMultiSelect { +interface CustomerTaxesMultiSelectProps { value?: string[]; onChange: (selectedValues: string[]) => void; className?: string; inputId?: string; - [key: string]: any; // Allow other props to be passed + [key: string]: unknown; } -export const CustomerTaxesMultiSelect = (props: CustomerTaxesMultiSelect) => { - const { value, onChange, className, inputId, ...otherProps } = props; +export const CustomerTaxesMultiSelect = ({ + value, + onChange, + className, + inputId, + ...otherProps +}: CustomerTaxesMultiSelectProps) => { const { t } = useTranslation(); const taxCatalog = useMemo(() => SpainTaxCatalogProvider(), []); - const catalogLookup = useMemo(() => SpainTaxCatalogProvider().toOptionLookup(), []); + const catalogLookup = useMemo(() => taxCatalog.toOptionLookup(), [taxCatalog]); - /** - * Filtra para mantener solo un elemento por grupo. - * Si hay duplicados dentro del mismo grupo, se queda con el último. - */ const filterSelectedByGroup = useCallback( (selectedValues: string[]) => { - const groupMap = new Map(); + const groupMap = new Map(); for (const code of selectedValues) { const item = taxCatalog.findByCode(code).getOrUndefined(); const group = item?.group ?? "ungrouped"; - groupMap.set(group, code); // Sobrescribe el anterior del mismo grupo + groupMap.set(group, code); } return Array.from(groupMap.values()); @@ -43,19 +44,19 @@ export const CustomerTaxesMultiSelect = (props: CustomerTaxesMultiSelect) => {