import { AggregateRoot, type CurrencyCode, type EmailAddress, type LanguageCode, type Name, type PhoneNumber, PostalAddress, type PostalAddressPatchProps, type PostalAddressProps, type TINNumber, type TextValue, type URLAddress, type UniqueID, } from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; import { type CustomerStatus, CustomerTaxes } from "../value-objects"; export interface ICustomerCreateProps { companyId: UniqueID; status: CustomerStatus; reference: Maybe; isCompany: boolean; name: Name; tradeName: Maybe; tin: Maybe; address: PostalAddressProps; emailPrimary: Maybe; emailSecondary: Maybe; phonePrimary: Maybe; phoneSecondary: Maybe; mobilePrimary: Maybe; mobileSecondary: Maybe; fax: Maybe; website: Maybe; legalRecord: Maybe; defaultTaxes: CustomerTaxes; languageCode: LanguageCode; currencyCode: CurrencyCode; } export type CustomerPatchProps = Partial< Omit > & { address?: PostalAddressPatchProps; }; // Customer export interface ICustomer { // comportamiento update(partialCustomer: CustomerPatchProps): Result; // propiedades (getters) readonly isIndividual: boolean; readonly isCompany: boolean; readonly isActive: boolean; readonly companyId: UniqueID; readonly reference: Maybe; readonly name: Name; readonly tradeName: Maybe; readonly tin: Maybe; readonly address: PostalAddress; readonly emailPrimary: Maybe; readonly emailSecondary: Maybe; readonly phonePrimary: Maybe; readonly phoneSecondary: Maybe; readonly mobilePrimary: Maybe; readonly mobileSecondary: Maybe; readonly fax: Maybe; readonly website: Maybe; readonly legalRecord: Maybe; readonly defaultTaxes: CustomerTaxes; readonly languageCode: LanguageCode; readonly currencyCode: CurrencyCode; } type CustomerInternalProps = Omit & { readonly address: PostalAddress; readonly defaultTaxes: CustomerTaxes; }; export class Customer extends AggregateRoot implements ICustomer { static create(props: ICustomerCreateProps, id?: UniqueID): Result { const validationResult = Customer.validateCreateProps(props); if (validationResult.isFailure) { return Result.fail(validationResult.error); } const { address, defaultTaxes, ...internalProps } = props; const postalAddressResult = PostalAddress.create(address); if (postalAddressResult.isFailure) { return Result.fail(postalAddressResult.error); } const taxes = CustomerTaxes.create(defaultTaxes); if (taxes.isFailure) { return Result.fail(taxes.error); } const contact = new Customer( { ...internalProps, defaultTaxes: taxes.data, address: postalAddressResult.data, }, id ); // Reglas de negocio / validaciones // ... // ... // Disparar eventos de dominio // ... // ... return Result.ok(contact); } private static validateCreateProps(props: ICustomerCreateProps): Result { return Result.ok(); } // Rehidratación desde persistencia static rehydrate(props: CustomerInternalProps, id: UniqueID): Customer { return new Customer(props, id); } public update(partialCustomer: CustomerPatchProps): Result { const { address: partialAddress, ...rest } = partialCustomer; Object.assign(this.props, rest); if (partialAddress) { const addressResult = this.address.update(partialAddress); if (addressResult.isFailure) { return Result.fail(addressResult.error); } } return Result.ok(); } // Getters public get isIndividual(): boolean { return !this.props.isCompany; } public get isCompany(): boolean { return this.props.isCompany; } public get isActive(): boolean { return this.props.status.isActive(); } public get companyId(): UniqueID { return this.props.companyId; } public get reference(): Maybe { return this.props.reference; } public get name(): Name { return this.props.name; } public get tradeName(): Maybe { return this.props.tradeName; } public get tin(): Maybe { return this.props.tin; } public get address(): PostalAddress { return this.props.address; } public get emailPrimary(): Maybe { return this.props.emailPrimary; } public get emailSecondary(): Maybe { return this.props.emailSecondary; } public get phonePrimary(): Maybe { return this.props.phonePrimary; } public get phoneSecondary(): Maybe { return this.props.phoneSecondary; } public get mobilePrimary(): Maybe { return this.props.mobilePrimary; } public get mobileSecondary(): Maybe { return this.props.mobileSecondary; } public get fax(): Maybe { return this.props.fax; } public get website(): Maybe { return this.props.website; } public get legalRecord(): Maybe { return this.props.legalRecord; } public get defaultTaxes(): CustomerTaxes { return this.props.defaultTaxes; } public get languageCode(): LanguageCode { return this.props.languageCode; } public get currencyCode(): CurrencyCode { return this.props.currencyCode; } }