import { AggregateRoot, type CurrencyCode, DomainValidationError, type LanguageCode, type Percentage, type TextValue, type UniqueID, type UtcDate, } from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; import type { InvoicePaymentMethod } from "../common/entities"; import type { InvoiceAmount, InvoiceNumber, InvoiceRecipient, InvoiceSerie, InvoiceStatus, } from "../common/value-objects"; import { IssuedInvoiceItems, type IssuedInvoiceTaxes, type VerifactuRecord } from "./entities"; export type IssuedInvoiceProps = { companyId: UniqueID; status: InvoiceStatus; proformaId: Maybe; // <- proforma padre en caso de issue series: Maybe; invoiceNumber: InvoiceNumber; invoiceDate: UtcDate; operationDate: Maybe; customerId: UniqueID; recipient: Maybe; reference: Maybe; description: Maybe; notes: Maybe; languageCode: LanguageCode; currencyCode: CurrencyCode; paymentMethod: Maybe; items: IssuedInvoiceItems; taxes: IssuedInvoiceTaxes; subtotalAmount: InvoiceAmount; itemDiscountAmount: InvoiceAmount; globalDiscountPercentage: Percentage; globalDiscountAmount: InvoiceAmount; totalDiscountAmount: InvoiceAmount; taxableAmount: InvoiceAmount; ivaAmount: InvoiceAmount; recAmount: InvoiceAmount; retentionAmount: InvoiceAmount; taxesAmount: InvoiceAmount; totalAmount: InvoiceAmount; verifactu: Maybe; }; export class IssuedInvoice extends AggregateRoot { private _items!: IssuedInvoiceItems; protected constructor(props: IssuedInvoiceProps, id?: UniqueID) { super(props, id); this._items = props.items || IssuedInvoiceItems.create({ languageCode: props.languageCode, currencyCode: props.currencyCode, globalDiscountPercentage: props.globalDiscountPercentage, }); } static create(props: IssuedInvoiceProps, id?: UniqueID): Result { if (!props.recipient) { return Result.fail( new DomainValidationError( "MISSING_RECIPIENT", "recipient", "Issued invoice requires recipient" ) ); } const issuedInvoice = new IssuedInvoice(props, id); // Reglas de negocio / validaciones // ... // 🔹 Disparar evento de dominio "IssuedInvoiceAuthenticatedEvent" //const { customerInvoice } = props; //user.addDomainEvent(new IssuedInvoiceAuthenticatedEvent(id, customerInvoice.toString())); return Result.ok(issuedInvoice); } // Getters public get companyId(): UniqueID { return this.props.companyId; } public get customerId(): UniqueID { return this.props.customerId; } public get proformaId(): Maybe { return this.props.proformaId; } public get status(): InvoiceStatus { return this.props.status; } public get series(): Maybe { return this.props.series; } public get invoiceNumber() { return this.props.invoiceNumber; } public get invoiceDate(): UtcDate { return this.props.invoiceDate; } public get operationDate(): Maybe { return this.props.operationDate; } public get reference(): Maybe { return this.props.reference; } public get description(): Maybe { return this.props.description; } public get notes(): Maybe { return this.props.notes; } public get recipient(): Maybe { return this.props.recipient; } public get paymentMethod(): Maybe { return this.props.paymentMethod; } public get languageCode(): LanguageCode { return this.props.languageCode; } public get currencyCode(): CurrencyCode { return this.props.currencyCode; } public get verifactu(): Maybe { return this.props.verifactu; } public get subtotalAmount(): InvoiceAmount { return this.props.subtotalAmount; } public get itemDiscountAmount(): InvoiceAmount { return this.props.itemDiscountAmount; } public get globalDiscountPercentage(): Percentage { return this.props.globalDiscountPercentage; } public get globalDiscountAmount(): InvoiceAmount { return this.props.globalDiscountAmount; } public get totalDiscountAmount(): InvoiceAmount { return this.props.totalDiscountAmount; } public get taxableAmount(): InvoiceAmount { return this.props.taxableAmount; } public get taxesAmount(): InvoiceAmount { return this.props.taxesAmount; } public get totalAmount(): InvoiceAmount { return this.props.totalAmount; } public get taxes(): IssuedInvoiceTaxes { return this.props.taxes; } // Method to get the complete list of line items public get items(): IssuedInvoiceItems { return this._items; } public get hasRecipient() { return this.recipient.isSome(); } public get hasPaymentMethod() { return this.paymentMethod.isSome(); } public getProps(): IssuedInvoiceProps { return this.props; } }