import { AggregateRoot, MoneyValue, UniqueID, UtcDate } from "@repo/rdx-ddd"; import { Collection, Result } from "@repo/rdx-utils"; import { CustomerInvoiceCustomer, CustomerInvoiceItem, CustomerInvoiceItems } from "../entities"; import { CustomerInvoiceNumber, CustomerInvoiceSerie, CustomerInvoiceStatus } from "../value-objects"; export interface ICustomerInvoiceProps { customerCustomerInvoiceNumber: CustomerInvoiceNumber; customerCustomerInvoiceSeries: CustomerInvoiceSerie; status: CustomerInvoiceStatus; issueDate: UtcDate; operationDate: UtcDate; //dueDate: UtcDate; // ? --> depende de la forma de pago //tax: Tax; // ? --> detalles? customerCustomerInvoiceCurrency: string; //language: Language; //purchareOrderNumber: string; //notes: Note; //senderId: UniqueID; //paymentInstructions: Note; //paymentTerms: string; customer?: CustomerInvoiceCustomer; items?: CustomerInvoiceItems; } export interface ICustomerInvoice { id: UniqueID; customerCustomerInvoiceNumber: CustomerInvoiceNumber; customerCustomerInvoiceSeries: CustomerInvoiceSerie; status: CustomerInvoiceStatus; issueDate: UtcDate; operationDate: UtcDate; //senderId: UniqueID; customer?: CustomerInvoiceCustomer; //dueDate //tax: Tax; //language: Language; customerCustomerInvoiceCurrency: string; //purchareOrderNumber: string; //notes: Note; //paymentInstructions: Note; //paymentTerms: string; items: CustomerInvoiceItems; calculateSubtotal: () => MoneyValue; calculateTaxTotal: () => MoneyValue; calculateTotal: () => MoneyValue; } export class CustomerInvoice extends AggregateRoot implements ICustomerInvoice { private _items!: Collection; //protected _status: CustomerInvoiceStatus; protected constructor(props: ICustomerInvoiceProps, id?: UniqueID) { super(props, id); this._items = props.items || CustomerInvoiceItems.create(); } static create(props: ICustomerInvoiceProps, id?: UniqueID): Result { const customerCustomerInvoice = new CustomerInvoice(props, id); // Reglas de negocio / validaciones // ... // ... // 🔹 Disparar evento de dominio "CustomerInvoiceAuthenticatedEvent" //const { customerCustomerInvoice } = props; //user.addDomainEvent(new CustomerInvoiceAuthenticatedEvent(id, customerCustomerInvoice.toString())); return Result.ok(customerCustomerInvoice); } get customerCustomerInvoiceNumber() { return this.props.customerCustomerInvoiceNumber; } get customerCustomerInvoiceSeries() { return this.props.customerCustomerInvoiceSeries; } get issueDate() { return this.props.issueDate; } /*get senderId(): UniqueID { return this.props.senderId; }*/ get customer(): CustomerInvoiceCustomer | undefined { return this.props.customer; } get operationDate() { return this.props.operationDate; } /*get language() { return this.props.language; }*/ get dueDate() { return undefined; } get tax() { return undefined; } get status() { return this.props.status; } get items() { return this._items; } /*get purchareOrderNumber() { return this.props.purchareOrderNumber; } get paymentInstructions() { return this.props.paymentInstructions; } get paymentTerms() { return this.props.paymentTerms; } get billTo() { return this.props.billTo; } get shipTo() { return this.props.shipTo; }*/ get customerCustomerInvoiceCurrency() { return this.props.customerCustomerInvoiceCurrency; } /*get notes() { return this.props.notes; }*/ // Method to get the complete list of line items /*get lineItems(): CustomerInvoiceLineItem[] { return this._lineItems; } addLineItem(lineItem: CustomerInvoiceLineItem, position?: number): void { if (position === undefined) { this._lineItems.push(lineItem); } else { this._lineItems.splice(position, 0, lineItem); } }*/ calculateSubtotal(): MoneyValue { const customerCustomerInvoiceSubtotal = MoneyValue.create({ amount: 0, currency_code: this.props.customerCustomerInvoiceCurrency, scale: 2, }).data; return this._items.getAll().reduce((subtotal, item) => { return subtotal.add(item.calculateTotal()); }, customerCustomerInvoiceSubtotal); } // Method to calculate the total tax in the customerCustomerInvoice calculateTaxTotal(): MoneyValue { const taxTotal = MoneyValue.create({ amount: 0, currency_code: this.props.customerCustomerInvoiceCurrency, scale: 2, }).data; return taxTotal; } // Method to calculate the total customerCustomerInvoice amount, including taxes calculateTotal(): MoneyValue { return this.calculateSubtotal().add(this.calculateTaxTotal()); } }