// filepath: src/contexts/billing/domain/aggregates/factura.ts import { AggregateRoot, UniqueID, UTCDate } from "@common/domain"; import { Result } from "@common/helpers"; import { FacturaDraft } from "../events/factura-draft"; import { FacturaEmitted } from "../events/factura-emitted"; import { FacturaSent } from "../events/factura-sent"; import { FacturaRejected } from "../events/factura-rejected"; import { FacturaReference } from "../value-objects/factura-reference"; import { FacturaStatus } from "../value-objects/factura-status"; export interface IFacturaProps { id: UniqueID; referencia: FacturaReference; lineasDetalle: any[]; // Se puede definir una entidad específica para las líneas de detalle clienteOProveedor: any; // Se puede definir una entidad específica para el cliente o proveedor estado: FacturaStatus; fecha: UTCDate; } export class Factura extends AggregateRoot { static create(props: IFacturaProps): Result { const factura = new Factura(props); factura.addDomainEvent(new FacturaDraft(factura.id, props.referencia)); return Result.ok(factura); } emit(): Result { if (this.props.estado !== FacturaStatus.draft) { return Result.fail(new Error("La factura solo puede ser emitida en estado 'draft'.")); } this.props.estado = FacturaStatus.emitted(); this.addDomainEvent(new FacturaEmitted(this.id)); return Result.ok(); } send(): Result { if (this.props.estado !== FacturaStatus.emitted) { return Result.fail(new Error("La factura solo puede ser enviada en estado 'emitted'.")); } this.props.estado = FacturaStatus.sent(); this.addDomainEvent(new FacturaSent(this.id)); return Result.ok(); } reject(): Result { if (this.props.estado !== FacturaStatus.draft) { return Result.fail(new Error("La factura solo puede ser rechazada en estado 'draft'.")); } this.props.estado = FacturaStatus.rejected(); this.addDomainEvent(new FacturaRejected(this.id)); return Result.ok(); } get referencia(): FacturaReference { return this.props.referencia; } get estado(): FacturaStatus { return this.props.estado; } get fecha(): UTCDate { return this.props.fecha; } }