From 0420b8e090db4c2c3981c9fe1385a56025760d66 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 2 Sep 2025 12:55:45 +0200 Subject: [PATCH] Clientes --- .../assembler/create-customers.assembler.ts | 4 +- .../create-customer.use-case.ts | 5 -- .../map-dto-to-create-customer-props.ts | 26 ------ .../assembler/get-customer.assembler.ts | 2 +- .../get-customer/get-customer.use-case.ts | 4 - .../assembler/list-customers.assembler.ts | 70 ++++------------ .../assembler/update-customer.assembler.ts | 79 ++++++------------- .../map-dto-to-update-customer-props.ts | 15 ++-- .../src/api/domain/aggregates/customer.ts | 46 ++--------- .../express/customers.routes.ts | 8 +- .../infrastructure/mappers/customer.mapper.ts | 3 - .../sequelize/customer.repository.ts | 12 --- .../customers/src/common/dto/request/index.ts | 2 +- ...s => update-customer-by-id.request.dto.ts} | 6 +- .../response/create-customer.result.dto.ts | 2 +- .../response/customer-list.response.dto.ts | 2 +- .../get-customer-by-id.response.dto.ts | 2 +- .../src/common/dto/response/index.ts | 1 + .../update-customer-by-id.response.dto.ts | 36 +++++++++ modules/customers/src/common/locales/en.json | 8 +- modules/customers/src/common/locales/es.json | 8 +- .../web/pages/create/customer-edit-form.tsx | 10 +-- .../src/web/pages/create/customer.schema.ts | 4 +- packages/rdx-ddd/src/helpers/normalizers.ts | 4 +- .../src/value-objects/postal-address.ts | 33 ++------ 25 files changed, 130 insertions(+), 262 deletions(-) rename modules/customers/src/common/dto/request/{update-customer.request.dto.ts => update-customer-by-id.request.dto.ts} (85%) create mode 100644 modules/customers/src/common/dto/response/update-customer-by-id.response.dto.ts diff --git a/modules/customers/src/api/application/create-customer/assembler/create-customers.assembler.ts b/modules/customers/src/api/application/create-customer/assembler/create-customers.assembler.ts index 64d39e77..a883eac4 100644 --- a/modules/customers/src/api/application/create-customer/assembler/create-customers.assembler.ts +++ b/modules/customers/src/api/application/create-customer/assembler/create-customers.assembler.ts @@ -22,7 +22,7 @@ export class CreateCustomersAssembler { street: toEmptyString(address.street, (value) => value.toPrimitive()), street2: toEmptyString(address.street2, (value) => value.toPrimitive()), city: toEmptyString(address.city, (value) => value.toPrimitive()), - state: toEmptyString(address.province, (value) => value.toPrimitive()), + province: toEmptyString(address.province, (value) => value.toPrimitive()), postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), country: toEmptyString(address.country, (value) => value.toPrimitive()), @@ -33,7 +33,7 @@ export class CreateCustomersAssembler { legal_record: toEmptyString(customer.legalRecord, (value) => value.toPrimitive()), - default_taxes: customer.defaultTaxes.getAll().join(","), + default_taxes: customer.defaultTaxes.getAll().join(", "), status: customer.isActive ? "active" : "inactive", language_code: customer.languageCode.toPrimitive(), diff --git a/modules/customers/src/api/application/create-customer/create-customer.use-case.ts b/modules/customers/src/api/application/create-customer/create-customer.use-case.ts index ea1b9177..3bf77135 100644 --- a/modules/customers/src/api/application/create-customer/create-customer.use-case.ts +++ b/modules/customers/src/api/application/create-customer/create-customer.use-case.ts @@ -38,8 +38,6 @@ export class CreateCustomerUseCase { const newCustomer = buildResult.data; - console.debug("Built new customer entity:", id, newCustomer); - // 4) Ejecutar bajo transacción: verificar duplicado → persistir → ensamblar vista return this.transactionManager.complete(async (transaction: Transaction) => { const existsGuard = await this.ensureNotExists(companyId, id, transaction); @@ -47,15 +45,12 @@ export class CreateCustomerUseCase { return Result.fail(existsGuard.error); } - console.debug("No existing customer with same ID found, proceeding to save."); - const saveResult = await this.service.saveCustomer(newCustomer, transaction); if (saveResult.isFailure) { return Result.fail(saveResult.error); } const viewDTO = this.assembler.toDTO(saveResult.data); - console.debug("Assembled view DTO:", viewDTO); return Result.ok(viewDTO); }); diff --git a/modules/customers/src/api/application/create-customer/map-dto-to-create-customer-props.ts b/modules/customers/src/api/application/create-customer/map-dto-to-create-customer-props.ts index 06d2f38c..f9d2252c 100644 --- a/modules/customers/src/api/application/create-customer/map-dto-to-create-customer-props.ts +++ b/modules/customers/src/api/application/create-customer/map-dto-to-create-customer-props.ts @@ -156,7 +156,6 @@ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { } if (errors.length > 0) { - console.error(errors); return Result.fail(new ValidationErrorCollection("Customer props mapping failed", errors)); } @@ -175,30 +174,6 @@ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { errors ); - console.debug("Mapped customer props:", { - companyId, - status, - reference, - isCompany, - name, - tradeName, - tinNumber, - street, - street2, - city, - province, - postalCode, - country, - emailAddress, - phoneNumber, - faxNumber, - website, - legalRecord, - languageCode, - currencyCode, - defaultTaxes, - }); - const customerProps: CustomerProps = { companyId: companyId!, status: status!, @@ -224,7 +199,6 @@ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { return Result.ok({ id: customerId!, props: customerProps }); } catch (err: unknown) { - console.error(err); return Result.fail(new DomainError("Customer props mapping failed", { cause: err })); } } diff --git a/modules/customers/src/api/application/get-customer/assembler/get-customer.assembler.ts b/modules/customers/src/api/application/get-customer/assembler/get-customer.assembler.ts index 0eded6b3..89f10ce1 100644 --- a/modules/customers/src/api/application/get-customer/assembler/get-customer.assembler.ts +++ b/modules/customers/src/api/application/get-customer/assembler/get-customer.assembler.ts @@ -22,7 +22,7 @@ export class GetCustomerAssembler { street: toEmptyString(address.street, (value) => value.toPrimitive()), street2: toEmptyString(address.street2, (value) => value.toPrimitive()), city: toEmptyString(address.city, (value) => value.toPrimitive()), - state: toEmptyString(address.province, (value) => value.toPrimitive()), + province: toEmptyString(address.province, (value) => value.toPrimitive()), postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), country: toEmptyString(address.country, (value) => value.toPrimitive()), diff --git a/modules/customers/src/api/application/get-customer/get-customer.use-case.ts b/modules/customers/src/api/application/get-customer/get-customer.use-case.ts index f364d2bb..99e94924 100644 --- a/modules/customers/src/api/application/get-customer/get-customer.use-case.ts +++ b/modules/customers/src/api/application/get-customer/get-customer.use-case.ts @@ -17,7 +17,6 @@ export class GetCustomerUseCase { ) {} public execute(params: GetCustomerUseCaseInput) { - console.log(params); const { customer_id, companyId } = params; const idOrError = UniqueID.create(customer_id); @@ -36,14 +35,11 @@ export class GetCustomerUseCase { transaction ); - console.log(customerOrError); - if (customerOrError.isFailure) { return Result.fail(customerOrError.error); } const getDTO = this.assembler.toDTO(customerOrError.data); - console.log(getDTO); return Result.ok(getDTO); } catch (error: unknown) { return Result.fail(error as Error); diff --git a/modules/customers/src/api/application/list-customers/assembler/list-customers.assembler.ts b/modules/customers/src/api/application/list-customers/assembler/list-customers.assembler.ts index 1edddd96..fe9bf5b1 100644 --- a/modules/customers/src/api/application/list-customers/assembler/list-customers.assembler.ts +++ b/modules/customers/src/api/application/list-customers/assembler/list-customers.assembler.ts @@ -1,4 +1,5 @@ import { Criteria } from "@repo/rdx-criteria/server"; +import { toEmptyString } from "@repo/rdx-ddd"; import { Collection } from "@repo/rdx-utils"; import { CustomerListResponsetDTO } from "../../../../common/dto"; import { Customer } from "../../../domain"; @@ -12,64 +13,28 @@ export class ListCustomersAssembler { id: customer.id.toPrimitive(), company_id: customer.companyId.toPrimitive(), - reference: customer.reference.match( - (value) => value.toPrimitive(), - () => "" - ), + reference: toEmptyString(customer.reference, (value) => value.toPrimitive()), is_company: String(customer.isCompany), name: customer.name.toPrimitive(), - trade_name: customer.tradeName.match( - (value) => value.toPrimitive(), - () => "" - ), - tin: customer.tin.match( - (value) => value.toPrimitive(), - () => "" - ), - street: address.street.match( - (value) => value.toPrimitive(), - () => "" - ), - city: address.city.match( - (value) => value.toPrimitive(), - () => "" - ), - state: address.province.match( - (value) => value.toPrimitive(), - () => "" - ), - postal_code: address.postalCode.match( - (value) => value.toPrimitive(), - () => "" - ), - country: address.country.match( - (value) => value.toPrimitive(), - () => "" - ), + trade_name: toEmptyString(customer.tradeName, (value) => value.toPrimitive()), - email: customer.email.match( - (value) => value.toPrimitive(), - () => "" - ), - phone: customer.phone.match( - (value) => value.toPrimitive(), - () => "" - ), - fax: customer.fax.match( - (value) => value.toPrimitive(), - () => "" - ), - website: customer.website.match( - (value) => value.toPrimitive(), - () => "" - ), + tin: toEmptyString(customer.tin, (value) => value.toPrimitive()), - legal_record: customer.legalRecord.match( - (value) => value.toPrimitive(), - () => "" - ), + street: toEmptyString(address.street, (value) => value.toPrimitive()), + street2: toEmptyString(address.street2, (value) => value.toPrimitive()), + city: toEmptyString(address.city, (value) => value.toPrimitive()), + province: toEmptyString(address.province, (value) => value.toPrimitive()), + postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), + country: toEmptyString(address.country, (value) => value.toPrimitive()), + + email: toEmptyString(customer.email, (value) => value.toPrimitive()), + phone: toEmptyString(customer.phone, (value) => value.toPrimitive()), + fax: toEmptyString(customer.fax, (value) => value.toPrimitive()), + website: toEmptyString(customer.website, (value) => value.toPrimitive()), + + legal_record: toEmptyString(customer.legalRecord, (value) => value.toPrimitive()), default_taxes: customer.defaultTaxes.getAll().join(", "), @@ -79,7 +44,6 @@ export class ListCustomersAssembler { metadata: { entity: "customer", - id: customer.id.toPrimitive(), //created_at: customer.createdAt.toPrimitive(), //updated_at: customer.updatedAt.toPrimitive() }, diff --git a/modules/customers/src/api/application/update-customer/assembler/update-customer.assembler.ts b/modules/customers/src/api/application/update-customer/assembler/update-customer.assembler.ts index e3004657..21156994 100644 --- a/modules/customers/src/api/application/update-customer/assembler/update-customer.assembler.ts +++ b/modules/customers/src/api/application/update-customer/assembler/update-customer.assembler.ts @@ -1,4 +1,5 @@ -import { GetCustomerByIdResponseDTO as UpdateCustomerByIdResponseDTO } from "../../../../common/dto"; +import { toEmptyString } from "@repo/rdx-ddd"; +import { UpdateCustomerByIdResponseDTO } from "../../../../common/dto"; import { Customer } from "../../../domain"; export class UpdateCustomerAssembler { @@ -7,66 +8,32 @@ export class UpdateCustomerAssembler { return { id: customer.id.toPrimitive(), - reference: customer.reference.match( - (value) => value.toPrimitive(), - () => "" - ), + company_id: customer.companyId.toPrimitive(), - is_company: customer.isCompany, + reference: toEmptyString(customer.reference, (value) => value.toPrimitive()), + + is_company: String(customer.isCompany), name: customer.name.toPrimitive(), - trade_name: customer.tradeName.match( - (value) => value.toPrimitive(), - () => "" - ), - tin: customer.tin.match( - (value) => value.toPrimitive(), - () => "" - ), - street: address.street.match( - (value) => value.toPrimitive(), - () => "" - ), - city: address.city.match( - (value) => value.toPrimitive(), - () => "" - ), - state: address.province.match( - (value) => value.toPrimitive(), - () => "" - ), - postal_code: address.postalCode.match( - (value) => value.toPrimitive(), - () => "" - ), - country: address.country.match( - (value) => value.toPrimitive(), - () => "" - ), + trade_name: toEmptyString(customer.tradeName, (value) => value.toPrimitive()), - email: customer.email.match( - (value) => value.toPrimitive(), - () => "" - ), - phone: customer.phone.match( - (value) => value.toPrimitive(), - () => "" - ), - fax: customer.fax.match( - (value) => value.toPrimitive(), - () => "" - ), - website: customer.website.match( - (value) => value.toPrimitive(), - () => "" - ), + tin: toEmptyString(customer.tin, (value) => value.toPrimitive()), - legal_record: customer.legalRecord.match( - (value) => value.toPrimitive(), - () => "" - ), + street: toEmptyString(address.street, (value) => value.toPrimitive()), + street2: toEmptyString(address.street2, (value) => value.toPrimitive()), + city: toEmptyString(address.city, (value) => value.toPrimitive()), + province: toEmptyString(address.province, (value) => value.toPrimitive()), + postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), + country: toEmptyString(address.country, (value) => value.toPrimitive()), - default_taxes: customer.defaultTaxes.map((item) => item.toPrimitive()), + email: toEmptyString(customer.email, (value) => value.toPrimitive()), + phone: toEmptyString(customer.phone, (value) => value.toPrimitive()), + fax: toEmptyString(customer.fax, (value) => value.toPrimitive()), + website: toEmptyString(customer.website, (value) => value.toPrimitive()), + + legal_record: toEmptyString(customer.legalRecord, (value) => value.toPrimitive()), + + default_taxes: customer.defaultTaxes.getAll().join(", "), status: customer.isActive ? "active" : "inactive", language_code: customer.languageCode.toPrimitive(), @@ -74,7 +41,7 @@ export class UpdateCustomerAssembler { metadata: { entity: "customer", - id: customer.id.toPrimitive(), + //id: customer.id.toPrimitive(), //created_at: customer.createdAt.toPrimitive(), //updated_at: customer.updatedAt.toPrimitive() }, diff --git a/modules/customers/src/api/application/update-customer/map-dto-to-update-customer-props.ts b/modules/customers/src/api/application/update-customer/map-dto-to-update-customer-props.ts index 2e46b542..79fd2adb 100644 --- a/modules/customers/src/api/application/update-customer/map-dto-to-update-customer-props.ts +++ b/modules/customers/src/api/application/update-customer/map-dto-to-update-customer-props.ts @@ -32,8 +32,8 @@ import { CustomerPatchProps } from "../../domain"; * No construye directamente el agregado. * Tri-estado: * - campo omitido → no se cambia - * - campo con valor null/"" → set(None()), - * - campo con valor no-vacío → set(Some(VO)). + * - campo con valor null/"" → se quita el valor -> set(None()), + * - campo con valor no-vacío → se pone el nuevo valor -> set(Some(VO)). * * @param dto - DTO con los datos a cambiar en el cliente * @returns Cambios en las propiedades del cliente @@ -173,16 +173,17 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerRequestDTO) }); // PostalAddress - customerPatchProps.address = mapDTOToUpdatePostalAddressPatchProps(dto, errors); + const addressPatchProps = mapDTOToUpdatePostalAddressPatchProps(dto, errors); + if (addressPatchProps) { + customerPatchProps.address = addressPatchProps; + } if (errors.length > 0) { - console.error(errors); return Result.fail(new ValidationErrorCollection("Customer props mapping failed", errors)); } return Result.ok(customerPatchProps); } catch (err: unknown) { - console.error(err); return Result.fail(new DomainError("Customer props mapping failed", { cause: err })); } } @@ -190,7 +191,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerRequestDTO) function mapDTOToUpdatePostalAddressPatchProps( dto: UpdateCustomerRequestDTO, errors: ValidationErrorDetail[] -): PostalAddressPatchProps { +): PostalAddressPatchProps | undefined { const postalAddressPatchProps: PostalAddressPatchProps = {}; toPatchField(dto.street).ifSet((street) => { @@ -241,5 +242,5 @@ function mapDTOToUpdatePostalAddressPatchProps( ); }); - return postalAddressPatchProps; + return Object.keys(postalAddressPatchProps).length > 0 ? postalAddressPatchProps : undefined; } diff --git a/modules/customers/src/api/domain/aggregates/customer.ts b/modules/customers/src/api/domain/aggregates/customer.ts index cc0e796c..2edefd16 100644 --- a/modules/customers/src/api/domain/aggregates/customer.ts +++ b/modules/customers/src/api/domain/aggregates/customer.ts @@ -86,55 +86,23 @@ export class Customer extends AggregateRoot { return Result.ok(contact); } - public update(partial: CustomerPatchProps): Result { + public update(partialCustomer: CustomerPatchProps): Result { + const { address: partialAddress, ...rest } = partialCustomer; const updatedProps = { ...this.props, - ...partial, + ...rest, } as CustomerProps; - if (partial.address) { - const updatedAddressOrError = PostalAddress.update(this.props.address, partial.address); + if (partialAddress) { + const updatedAddressOrError = this.address.update(partialAddress); if (updatedAddressOrError.isFailure) { return Result.fail(updatedAddressOrError.error); } + updatedProps.address = updatedAddressOrError.data; } - const updatedCustomer = new Customer(updatedProps, this.id); - return Result.ok(updatedCustomer); - } - - public toSnapshot(): CustomerSnapshot { - return { - id: this.id.toPrimitive(), - companyId: this.props.companyId.toPrimitive(), - status: this.props.status.toPrimitive(), - reference: this.props.reference.isSome() - ? this.props.reference.unwrap()!.toPrimitive() - : null, - - isCompany: this.props.isCompany, - name: this.props.name.toPrimitive(), - tradeName: this.props.tradeName.isSome() - ? this.props.tradeName.unwrap()!.toPrimitive() - : null, - tin: this.props.tin.isSome() ? this.props.tin.unwrap()!.toPrimitive() : null, - - address: this.props.address.toSnapshot(), - - email: this.props.email.isSome() ? this.props.email.unwrap()!.toPrimitive() : null, - phone: this.props.phone.isSome() ? this.props.phone.unwrap()!.toPrimitive() : null, - fax: this.props.fax.isSome() ? this.props.fax.unwrap()!.toPrimitive() : null, - website: this.props.website.isSome() ? this.props.website.unwrap()!.toPrimitive() : null, - - legalRecord: this.props.legalRecord.isSome() - ? this.props.legalRecord.unwrap()!.toPrimitive() - : null, - defaultTaxes: this.props.defaultTaxes.map((tax) => tax.toPrimitive()), - - languageCode: this.props.languageCode.toPrimitive(), - currencyCode: this.props.currencyCode.toPrimitive(), - }; + return Customer.create(updatedProps, this.id); } public get isIndividual(): boolean { diff --git a/modules/customers/src/api/infrastructure/express/customers.routes.ts b/modules/customers/src/api/infrastructure/express/customers.routes.ts index 18bce96b..3fe0f7b8 100644 --- a/modules/customers/src/api/infrastructure/express/customers.routes.ts +++ b/modules/customers/src/api/infrastructure/express/customers.routes.ts @@ -7,8 +7,8 @@ import { CustomerListRequestSchema, DeleteCustomerByIdRequestSchema, GetCustomerByIdRequestSchema, - UpdateCustomerParamsRequestSchema, - UpdateCustomerRequestSchema, + UpdateCustomerByIdParamsRequestSchema, + UpdateCustomerByIdRequestSchema, } from "../../../common/dto"; import { getCustomerDependencies } from "../dependencies"; import { @@ -78,8 +78,8 @@ export const customersRouter = (params: ModuleParams) => { router.put( "/:customer_id", //checkTabContext, - validateRequest(UpdateCustomerParamsRequestSchema, "params"), - validateRequest(UpdateCustomerRequestSchema, "body"), + validateRequest(UpdateCustomerByIdParamsRequestSchema, "params"), + validateRequest(UpdateCustomerByIdRequestSchema, "body"), (req: Request, res: Response, next: NextFunction) => { const useCase = deps.build.update(); const controller = new UpdateCustomerController(useCase); diff --git a/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts b/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts index c845dd95..cebd1882 100644 --- a/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts +++ b/modules/customers/src/api/infrastructure/mappers/customer.mapper.ts @@ -160,7 +160,6 @@ export class CustomerMapper } if (errors.length > 0) { - console.error(errors); return Result.fail(new ValidationErrorCollection("Customer props mapping failed", errors)); } @@ -173,8 +172,6 @@ export class CustomerMapper country: country!, }; - console.log(postalAddressProps); - const postalAddress = extractOrPushError( PostalAddress.create(postalAddressProps), "address", diff --git a/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts b/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts index b7658eba..e2892ea3 100644 --- a/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts +++ b/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts @@ -30,17 +30,10 @@ export class CustomerRepository async save(customer: Customer, transaction: Transaction): Promise> { try { const data = this.mapper.mapToPersistence(customer); - console.debug("Saving customer to database:", data); - const [instance] = await CustomerModel.upsert(data, { transaction, returning: true }); - - console.debug("Customer saved successfully:", instance.toJSON()); - const savedCustomer = this.mapper.mapToDomain(instance); - console.debug("Mapped customer to domain:", savedCustomer); return savedCustomer; } catch (err: unknown) { - console.error("Error saving customer:", err); return Result.fail(translateSequelizeError(err)); } } @@ -93,7 +86,6 @@ export class CustomerRepository } const customer = this.mapper.mapToDomain(row); - console.log(customer); return customer; } catch (error: any) { return Result.fail(translateSequelizeError(error)); @@ -131,7 +123,6 @@ export class CustomerRepository return this.mapper.mapArrayToDomain(instances); } catch (err: unknown) { - console.error(err); return Result.fail(translateSequelizeError(err)); } } @@ -151,14 +142,11 @@ export class CustomerRepository transaction: Transaction ): Promise> { try { - console.log(id, companyId); const deleted = await CustomerModel.destroy({ where: { id: id.toString(), company_id: companyId.toString() }, transaction, }); - console.log(deleted); - return Result.ok(); } catch (err: unknown) { // , `Error deleting customer ${id} in company ${companyId}` diff --git a/modules/customers/src/common/dto/request/index.ts b/modules/customers/src/common/dto/request/index.ts index 0fc768db..b969b64c 100644 --- a/modules/customers/src/common/dto/request/index.ts +++ b/modules/customers/src/common/dto/request/index.ts @@ -2,4 +2,4 @@ export * from "./create-customer.request.dto"; export * from "./customer-list.request.dto"; export * from "./delete-customer-by-id.request.dto"; export * from "./get-customer-by-id.request.dto"; -export * from "./update-customer.request.dto"; +export * from "./update-customer-by-id.request.dto"; diff --git a/modules/customers/src/common/dto/request/update-customer.request.dto.ts b/modules/customers/src/common/dto/request/update-customer-by-id.request.dto.ts similarity index 85% rename from modules/customers/src/common/dto/request/update-customer.request.dto.ts rename to modules/customers/src/common/dto/request/update-customer-by-id.request.dto.ts index 239e6b4b..e97dcb4e 100644 --- a/modules/customers/src/common/dto/request/update-customer.request.dto.ts +++ b/modules/customers/src/common/dto/request/update-customer-by-id.request.dto.ts @@ -1,10 +1,10 @@ import * as z from "zod/v4"; -export const UpdateCustomerParamsRequestSchema = z.object({ +export const UpdateCustomerByIdParamsRequestSchema = z.object({ customer_id: z.string(), }); -export const UpdateCustomerRequestSchema = z.object({ +export const UpdateCustomerByIdRequestSchema = z.object({ reference: z.string().optional(), is_company: z.string().optional(), @@ -31,4 +31,4 @@ export const UpdateCustomerRequestSchema = z.object({ currency_code: z.string().optional(), }); -export type UpdateCustomerRequestDTO = z.infer; +export type UpdateCustomerRequestDTO = z.infer; diff --git a/modules/customers/src/common/dto/response/create-customer.result.dto.ts b/modules/customers/src/common/dto/response/create-customer.result.dto.ts index 9a32d008..768a1f3e 100644 --- a/modules/customers/src/common/dto/response/create-customer.result.dto.ts +++ b/modules/customers/src/common/dto/response/create-customer.result.dto.ts @@ -14,7 +14,7 @@ export const CreateCustomerResponseSchema = z.object({ street: z.string(), street2: z.string(), city: z.string(), - state: z.string(), + province: z.string(), postal_code: z.string(), country: z.string(), diff --git a/modules/customers/src/common/dto/response/customer-list.response.dto.ts b/modules/customers/src/common/dto/response/customer-list.response.dto.ts index 0a8eea6c..2f1b963d 100644 --- a/modules/customers/src/common/dto/response/customer-list.response.dto.ts +++ b/modules/customers/src/common/dto/response/customer-list.response.dto.ts @@ -14,7 +14,7 @@ export const CustomerListResponseSchema = createListViewResponseSchema( street: z.string(), city: z.string(), - state: z.string(), + province: z.string(), postal_code: z.string(), country: z.string(), diff --git a/modules/customers/src/common/dto/response/get-customer-by-id.response.dto.ts b/modules/customers/src/common/dto/response/get-customer-by-id.response.dto.ts index f3874833..24c33d13 100644 --- a/modules/customers/src/common/dto/response/get-customer-by-id.response.dto.ts +++ b/modules/customers/src/common/dto/response/get-customer-by-id.response.dto.ts @@ -14,7 +14,7 @@ export const GetCustomerByIdResponseSchema = z.object({ street: z.string(), street2: z.string(), city: z.string(), - state: z.string(), + province: z.string(), postal_code: z.string(), country: z.string(), diff --git a/modules/customers/src/common/dto/response/index.ts b/modules/customers/src/common/dto/response/index.ts index f6fe23f1..4f76f304 100644 --- a/modules/customers/src/common/dto/response/index.ts +++ b/modules/customers/src/common/dto/response/index.ts @@ -1,3 +1,4 @@ export * from "./create-customer.result.dto"; export * from "./customer-list.response.dto"; export * from "./get-customer-by-id.response.dto"; +export * from "./update-customer-by-id.response.dto"; diff --git a/modules/customers/src/common/dto/response/update-customer-by-id.response.dto.ts b/modules/customers/src/common/dto/response/update-customer-by-id.response.dto.ts new file mode 100644 index 00000000..9d1718bc --- /dev/null +++ b/modules/customers/src/common/dto/response/update-customer-by-id.response.dto.ts @@ -0,0 +1,36 @@ +import { MetadataSchema } from "@erp/core"; +import * as z from "zod/v4"; + +export const UpdateCustomerByIdResponseSchema = z.object({ + id: z.uuid(), + company_id: z.uuid(), + reference: z.string(), + + is_company: z.string(), + name: z.string(), + trade_name: z.string(), + tin: z.string(), + + street: z.string(), + street2: z.string(), + city: z.string(), + province: z.string(), + postal_code: z.string(), + country: z.string(), + + email: z.string(), + phone: z.string(), + fax: z.string(), + website: z.string(), + + legal_record: z.string(), + + default_taxes: z.string(), + status: z.string(), + language_code: z.string(), + currency_code: z.string(), + + metadata: MetadataSchema.optional(), +}); + +export type UpdateCustomerByIdResponseDTO = z.infer; diff --git a/modules/customers/src/common/locales/en.json b/modules/customers/src/common/locales/en.json index d060c7cc..868303b3 100644 --- a/modules/customers/src/common/locales/en.json +++ b/modules/customers/src/common/locales/en.json @@ -61,10 +61,10 @@ "placeholder": "Enter postal code", "description": "The postal code of the customer" }, - "state": { - "label": "State", - "placeholder": "Enter state", - "description": "The state of the customer" + "province": { + "label": "Province", + "placeholder": "Enter province", + "description": "The province of the customer" }, "country": { "label": "Country", diff --git a/modules/customers/src/common/locales/es.json b/modules/customers/src/common/locales/es.json index 0bc29da1..9001fa7a 100644 --- a/modules/customers/src/common/locales/es.json +++ b/modules/customers/src/common/locales/es.json @@ -61,10 +61,10 @@ "placeholder": "Ingrese el código postal", "description": "El código postal del cliente" }, - "state": { - "label": "Estado", - "placeholder": "Ingrese el estado", - "description": "El estado del cliente" + "province": { + "label": "Provincia", + "placeholder": "Ingrese la provincia", + "description": "La provincia del cliente" }, "country": { "label": "País", diff --git a/modules/customers/src/web/pages/create/customer-edit-form.tsx b/modules/customers/src/web/pages/create/customer-edit-form.tsx index 11af34b9..528d39ae 100644 --- a/modules/customers/src/web/pages/create/customer-edit-form.tsx +++ b/modules/customers/src/web/pages/create/customer-edit-form.tsx @@ -39,7 +39,7 @@ const defaultCustomerData = { city: "Madrid", country: "ES", postal_code: "28080", - state: "Madrid", + province: "Madrid", lang_code: "es", currency_code: "EUR", legal_record: "Registro Mercantil de Madrid, Tomo 12345, Folio 67, Hoja M-123456", @@ -208,11 +208,11 @@ export const CustomerEditForm = ({ ; diff --git a/packages/rdx-ddd/src/helpers/normalizers.ts b/packages/rdx-ddd/src/helpers/normalizers.ts index 7ab63022..c0482ecd 100644 --- a/packages/rdx-ddd/src/helpers/normalizers.ts +++ b/packages/rdx-ddd/src/helpers/normalizers.ts @@ -22,14 +22,14 @@ export function maybeFromNullableString(input?: string | null): Maybe { /** Maybe -> null para transporte */ export function toNullable(m: Maybe, map?: (t: T) => any): any | null { - if (m.isNone()) return null; + if (!m || m.isNone()) return null; const v = m.unwrap() as T; return map ? String(map(v)) : String(v); } /** Maybe -> "" para transporte */ export function toEmptyString(m: Maybe, map?: (t: T) => string): string { - if (m.isNone()) return ""; + if (!m || m.isNone()) return ""; const v = m.unwrap() as T; return map ? map(v) : String(v); } diff --git a/packages/rdx-ddd/src/value-objects/postal-address.ts b/packages/rdx-ddd/src/value-objects/postal-address.ts index cfd6f5a9..5ae793ab 100644 --- a/packages/rdx-ddd/src/value-objects/postal-address.ts +++ b/packages/rdx-ddd/src/value-objects/postal-address.ts @@ -40,19 +40,13 @@ export class PostalAddress extends ValueObject { return Result.ok(new PostalAddress(values)); } - static update( - oldAddress: PostalAddress, - data: Partial - ): Result { - return PostalAddress.create({ - street: data.street ?? oldAddress.street, - street2: data.street2 ?? oldAddress.street2, - city: data.city ?? oldAddress.city, - postalCode: data.postalCode ?? oldAddress.postalCode, - province: data.province ?? oldAddress.province, - country: data.country ?? oldAddress.country, - // biome-ignore lint/complexity/noThisInStatic: - }).getOrElse(this); + public update(partial: Partial): Result { + const updatedProps = { + ...this.props, + ...partial, + } as PostalAddressProps; + + return PostalAddress.create(updatedProps); } get street(): Maybe { @@ -90,17 +84,4 @@ export class PostalAddress extends ValueObject { toFormat(): string { return `${this.props.street}, ${this.props.street2}, ${this.props.city}, ${this.props.postalCode}, ${this.props.province}, ${this.props.country}`; } - - public toSnapshot(): PostalAddressSnapshot { - return { - street: this.props.street.isSome() ? this.props.street.unwrap()!.toString() : null, - street2: this.props.street2.isSome() ? this.props.street2.unwrap()!.toString() : null, - city: this.props.city.isSome() ? this.props.city.unwrap()!.toString() : null, - postalCode: this.props.postalCode.isSome() - ? this.props.postalCode.unwrap()!.toString() - : null, - province: this.props.province.isSome() ? this.props.province.unwrap()!.toString() : null, - country: this.props.country.isSome() ? this.props.country.unwrap()!.toString() : null, - }; - } }