import { AggregateRoot, CurrencyCode, EmailAddress, LanguageCode, Name, PhoneNumber, PostalAddress, PostalAddressPatchProps, PostalAddressSnapshot, TINNumber, TaxCode, TextValue, URLAddress, UniqueID, } from "@repo/rdx-ddd"; import { Collection, Maybe, Result } from "@repo/rdx-utils"; import { CustomerStatus } from "../value-objects"; export interface CustomerProps { companyId: UniqueID; status: CustomerStatus; reference: Maybe; isCompany: boolean; name: Name; tradeName: Maybe; tin: Maybe; address: PostalAddress; email: Maybe; phone: Maybe; fax: Maybe; website: Maybe; legalRecord: Maybe; defaultTaxes: Collection; languageCode: LanguageCode; currencyCode: CurrencyCode; } export interface CustomerSnapshot { id: string; companyId: string; status: string; reference: string | null; isCompany: boolean; name: string; tradeName: string | null; tin: string | null; address: PostalAddressSnapshot; // snapshot serializable del VO PostalAddress email: string | null; phone: string | null; fax: string | null; website: string | null; legalRecord: string | null; defaultTaxes: string[]; languageCode: string; currencyCode: string; } export type CustomerPatchProps = Partial> & { address?: PostalAddressPatchProps; }; export class Customer extends AggregateRoot { static create(props: CustomerProps, id?: UniqueID): Result { const contact = new Customer(props, id); // Reglas de negocio / validaciones // ... // ... // 🔹 Disparar evento de dominio "CustomerAuthenticatedEvent" //const { contact } = props; //user.addDomainEvent(new CustomerAuthenticatedEvent(id, contact.toString())); return Result.ok(contact); } public update(partial: CustomerPatchProps): Result { const updatedProps = { ...this.props, ...partial, } as CustomerProps; if (partial.address) { const updatedAddressOrError = PostalAddress.update(this.props.address, partial.address); 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(), }; } 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 email(): Maybe { return this.props.email; } public get phone(): Maybe { return this.props.phone; } 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(): Collection { return this.props.defaultTaxes; } public get languageCode(): LanguageCode { return this.props.languageCode; } public get currencyCode(): CurrencyCode { return this.props.currencyCode; } }