import { DomainValidationError } from "@erp/core/api"; import { AggregateRoot, CurrencyCode, LanguageCode, MoneyValue, Percentage, TextValue, UniqueID, UtcDate, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; import { CustomerInvoiceItems } from "../entities"; import { InvoiceTaxes } from "../entities/invoice-taxes"; import { CustomerInvoiceNumber, CustomerInvoiceSerie, CustomerInvoiceStatus, InvoiceRecipient, } from "../value-objects"; export interface CustomerInvoiceProps { companyId: UniqueID; isProforma: boolean; invoiceNumber: CustomerInvoiceNumber; status: CustomerInvoiceStatus; series: Maybe; invoiceDate: UtcDate; operationDate: Maybe; customerId: UniqueID; recipient: Maybe; notes: Maybe; languageCode: LanguageCode; currencyCode: CurrencyCode; //subtotalAmount: MoneyValue; discountPercentage: Percentage; //discountAmount: MoneyValue; taxes: InvoiceTaxes; //totalAmount: MoneyValue; items: CustomerInvoiceItems; } export type CustomerInvoicePatchProps = Partial>; export class CustomerInvoice extends AggregateRoot { private _items!: CustomerInvoiceItems; protected constructor(props: CustomerInvoiceProps, id?: UniqueID) { super(props, id); this._items = props.items || CustomerInvoiceItems.create({ languageCode: props.languageCode, currencyCode: props.currencyCode, }); } static create(props: CustomerInvoiceProps, id?: UniqueID): Result { const customerInvoice = new CustomerInvoice(props, id); // Reglas de negocio / validaciones if (!customerInvoice.isProforma && !customerInvoice.hasRecipient) { return Result.fail( new DomainValidationError( "MISSING_CUSTOMER_DATA", "recipient", "Customer data must be provided for non-proforma invoices" ) ); } // 🔹 Disparar evento de dominio "CustomerInvoiceAuthenticatedEvent" //const { customerInvoice } = props; //user.addDomainEvent(new CustomerInvoiceAuthenticatedEvent(id, customerInvoice.toString())); return Result.ok(customerInvoice); } public update(partialInvoice: CustomerInvoicePatchProps): Result { throw new Error("Not implemented"); } public get companyId(): UniqueID { return this.props.companyId; } public get customerId(): UniqueID { return this.props.customerId; } public get isProforma(): boolean { return this.props.isProforma; } public get status(): CustomerInvoiceStatus { 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 notes(): Maybe { return this.props.notes; } public get recipient(): Maybe { return this.props.recipient; } public get languageCode(): LanguageCode { return this.props.languageCode; } public get currencyCode(): CurrencyCode { return this.props.currencyCode; } public get subtotalAmount(): MoneyValue { throw new Error("discountAmount not implemented"); } public get discountPercentage(): Percentage { return this.props.discountPercentage; } public get discountAmount(): MoneyValue { throw new Error("discountAmount not implemented"); } public get taxableAmount(): MoneyValue { throw new Error("taxableAmount not implemented"); } public get taxAmount(): MoneyValue { throw new Error("discountAmount not implemented"); } public get totalAmount(): MoneyValue { throw new Error("totalAmount not implemented"); } // Method to get the complete list of line items get items(): CustomerInvoiceItems { return this._items; } get hasRecipient() { return this.recipient.isSome(); } /*get senderId(): UniqueID { return this.props.senderId; }*/ /* get customer(): CustomerInvoiceCustomer | undefined { return this.props.customer; }*/ /*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; }*/ /* addLineItem(lineItem: CustomerInvoiceLineItem, position?: number): void { if (position === undefined) { this._lineItems.push(lineItem); } else { this._lineItems.splice(position, 0, lineItem); } }*/ /*calculateSubtotal(): MoneyValue { const customerInvoiceSubtotal = MoneyValue.create({ amount: 0, currency_code: this.props.currency, scale: 2, }).data; return this._items.getAll().reduce((subtotal, item) => { return subtotal.add(item.calculateTotal()); }, customerInvoiceSubtotal); }*/ // Method to calculate the total tax in the customerInvoice /*calculateTaxTotal(): MoneyValue { const taxTotal = MoneyValue.create({ amount: 0, currency_code: this.props.currency, scale: 2, }).data; return taxTotal; }*/ // Method to calculate the total customerInvoice amount, including taxes /*calculateTotal(): MoneyValue { return this.calculateSubtotal().add(this.calculateTaxTotal()); }*/ }