import { AggregateRoot, type EmailAddress, type PhoneNumber, PostalAddress, type TINNumber, UniqueID, } from "@/core"; import { Maybe, Result } from "@repo/rdx-utils"; import { AccountStatus } from "../value-objects"; export interface IAccountProps { status: AccountStatus; isFreelancer: boolean; name: string; tin: TINNumber; address: PostalAddress; email: EmailAddress; phone: PhoneNumber; legalRecord: string; defaultTax: number; langCode: string; currencyCode: string; tradeName: Maybe; website: Maybe; fax: Maybe; logo: Maybe; } export interface IAccount { id: UniqueID; status: AccountStatus; name: string; tin: TINNumber; address: PostalAddress; email: EmailAddress; phone: PhoneNumber; legalRecord: string; defaultTax: number; langCode: string; currencyCode: string; tradeName: Maybe; fax: Maybe; website: Maybe; logo: Maybe; isAccount: boolean; isFreelancer: boolean; isActive: boolean; activate(): boolean; deactivate(): boolean; } export class Account extends AggregateRoot implements IAccount { id: UniqueID; static create(props: IAccountProps, id?: UniqueID): Result { const account = new Account(props, id); // Reglas de negocio / validaciones // ... // ... // 🔹 Disparar evento de dominio "AccountAuthenticatedEvent" //const { account } = props; //user.addDomainEvent(new AccountAuthenticatedEvent(id, account.toString())); return Result.ok(account); } static update(oldAccount: Account, data: Partial): Result { const updatedPostalAddress = PostalAddress.update(oldAccount.address, data.address ?? {}).data; return Account.create( { isFreelancer: data.isFreelancer ?? oldAccount.isFreelancer, name: data.name ?? oldAccount.name, tin: data.tin ?? oldAccount.tin, address: updatedPostalAddress, email: data.email ?? oldAccount.email, phone: data.phone ?? oldAccount.phone, legalRecord: data.legalRecord ?? oldAccount.legalRecord, defaultTax: data.defaultTax ?? oldAccount.defaultTax, status: oldAccount.props.status, langCode: data.langCode ?? oldAccount.langCode, currencyCode: data.currencyCode ?? oldAccount.currencyCode, tradeName: data.tradeName ?? oldAccount.tradeName, website: data.website ?? oldAccount.website, fax: data.fax ?? oldAccount.fax, logo: data.logo ?? oldAccount.logo, }, oldAccount.id ).getOrElse(this); } activate() { if (!this.props.status.canTransitionTo("active")) { return false; } this.props.status = AccountStatus.createActive(); return true; } deactivate() { if (!this.props.status.canTransitionTo("inactive")) { return false; } this.props.status = AccountStatus.createInactive(); return true; } get status() { return this.props.status; } get name() { return this.props.name; } get tradeName() { return this.props.tradeName; } get tin(): TINNumber { return this.props.tin; } get address(): PostalAddress { return this.props.address; } get email(): EmailAddress { return this.props.email; } get phone(): PhoneNumber { return this.props.phone; } get fax(): Maybe { return this.props.fax; } get website() { return this.props.website; } get legalRecord() { return this.props.legalRecord; } get defaultTax() { return this.props.defaultTax; } get langCode() { return this.props.langCode; } get currencyCode() { return this.props.currencyCode; } get logo() { return this.props.logo; } get isAccount(): boolean { return !this.props.isFreelancer; } get isFreelancer(): boolean { return this.props.isFreelancer; } get isActive(): boolean { return this.props.status.equals(AccountStatus.createActive()); } }