FactuGES_ERP/modules/customers/src/api/domain/aggregates/customer.ts

208 lines
5.0 KiB
TypeScript
Raw Normal View History

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;
}
}