2025-08-11 17:49:52 +00:00
|
|
|
import {
|
|
|
|
|
AggregateRoot,
|
2025-09-01 14:07:59 +00:00
|
|
|
CurrencyCode,
|
2025-08-11 17:49:52 +00:00
|
|
|
EmailAddress,
|
2025-09-01 14:07:59 +00:00
|
|
|
LanguageCode,
|
|
|
|
|
Name,
|
2025-08-11 17:49:52 +00:00
|
|
|
PhoneNumber,
|
|
|
|
|
PostalAddress,
|
2025-09-01 14:07:59 +00:00
|
|
|
PostalAddressPatchProps,
|
|
|
|
|
PostalAddressSnapshot,
|
2025-08-11 17:49:52 +00:00
|
|
|
TINNumber,
|
2025-09-01 14:07:59 +00:00
|
|
|
TaxCode,
|
|
|
|
|
TextValue,
|
|
|
|
|
URLAddress,
|
2025-08-11 17:49:52 +00:00
|
|
|
UniqueID,
|
|
|
|
|
} from "@repo/rdx-ddd";
|
2025-09-01 14:07:59 +00:00
|
|
|
import { Collection, Maybe, Result } from "@repo/rdx-utils";
|
2025-08-26 18:55:59 +00:00
|
|
|
import { CustomerStatus } from "../value-objects";
|
2025-08-11 17:49:52 +00:00
|
|
|
|
|
|
|
|
export interface CustomerProps {
|
2025-08-25 17:42:56 +00:00
|
|
|
companyId: UniqueID;
|
2025-08-26 18:55:59 +00:00
|
|
|
status: CustomerStatus;
|
2025-09-01 14:07:59 +00:00
|
|
|
reference: Maybe<Name>;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-08-25 17:42:56 +00:00
|
|
|
isCompany: boolean;
|
2025-09-01 14:07:59 +00:00
|
|
|
name: Name;
|
|
|
|
|
tradeName: Maybe<Name>;
|
|
|
|
|
tin: Maybe<TINNumber>;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-08-11 17:49:52 +00:00
|
|
|
address: PostalAddress;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
email: Maybe<EmailAddress>;
|
|
|
|
|
phone: Maybe<PhoneNumber>;
|
|
|
|
|
fax: Maybe<PhoneNumber>;
|
|
|
|
|
website: Maybe<URLAddress>;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
legalRecord: Maybe<TextValue>;
|
|
|
|
|
defaultTaxes: Collection<TaxCode>;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
languageCode: LanguageCode;
|
|
|
|
|
currencyCode: CurrencyCode;
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
export interface CustomerSnapshot {
|
|
|
|
|
id: string;
|
|
|
|
|
companyId: string;
|
|
|
|
|
status: string;
|
|
|
|
|
reference: string | null;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
isCompany: boolean;
|
2025-08-26 18:55:59 +00:00
|
|
|
name: string;
|
2025-09-01 14:07:59 +00:00
|
|
|
tradeName: string | null;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
tin: string | null;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
address: PostalAddressSnapshot; // snapshot serializable del VO PostalAddress
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
email: string | null;
|
|
|
|
|
phone: string | null;
|
|
|
|
|
fax: string | null;
|
|
|
|
|
website: string | null;
|
2025-08-26 18:55:59 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
legalRecord: string | null;
|
|
|
|
|
defaultTaxes: string[];
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
languageCode: string;
|
|
|
|
|
currencyCode: string;
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
export type CustomerPatchProps = Partial<Omit<CustomerProps, "companyId" | "address">> & {
|
|
|
|
|
address?: PostalAddressPatchProps;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export class Customer extends AggregateRoot<CustomerProps> {
|
2025-08-11 17:49:52 +00:00
|
|
|
static create(props: CustomerProps, id?: UniqueID): Result<Customer, Error> {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public update(partial: CustomerPatchProps): Result<Customer, Error> {
|
|
|
|
|
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);
|
2025-08-25 17:42:56 +00:00
|
|
|
return Result.ok(updatedCustomer);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
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 {
|
2025-08-25 17:42:56 +00:00
|
|
|
return this.props.companyId;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get reference(): Maybe<Name> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.reference;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get name(): Name {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.name;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get tradeName(): Maybe<Name> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.tradeName;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get tin(): Maybe<TINNumber> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.tin;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get address(): PostalAddress {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.address;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get email(): Maybe<EmailAddress> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.email;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get phone(): Maybe<PhoneNumber> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.phone;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get fax(): Maybe<PhoneNumber> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.fax;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get website(): Maybe<URLAddress> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.website;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get legalRecord(): Maybe<TextValue> {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.legalRecord;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get defaultTaxes(): Collection<TaxCode> {
|
|
|
|
|
return this.props.defaultTaxes;
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get languageCode(): LanguageCode {
|
|
|
|
|
return this.props.languageCode;
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-01 14:07:59 +00:00
|
|
|
public get currencyCode(): CurrencyCode {
|
2025-08-11 17:49:52 +00:00
|
|
|
return this.props.currencyCode;
|
|
|
|
|
}
|
|
|
|
|
}
|