import { DomainEntity, MoneyValue, Percentage, Quantity, UniqueID } from "core/common/domain"; import { Result } from "core/common/helpers"; import { InvoiceItemDescription } from "../../value-objects"; export interface IInvoiceItemProps { description: InvoiceItemDescription; quantity: Quantity; // Cantidad de unidades unitPrice: MoneyValue; // Precio unitario en la moneda de la factura //subtotalPrice?: MoneyValue; // Precio unitario * Cantidad discount: Percentage; // % descuento //totalPrice?: MoneyValue; } export interface IInvoiceItem { id: UniqueID; description: InvoiceItemDescription; quantity: Quantity; unitPrice: MoneyValue; subtotalPrice: MoneyValue; discount: Percentage; totalPrice: MoneyValue; } export class InvoiceItem extends DomainEntity implements IInvoiceItem { private _subtotalPrice!: MoneyValue; private _totalPrice!: MoneyValue; public static create(props: IInvoiceItemProps, id?: UniqueID): Result { const item = new InvoiceItem(props, id); // Reglas de negocio / validaciones // ... // ... // 🔹 Disparar evento de dominio "InvoiceItemCreatedEvent" //const { invoice } = props; //user.addDomainEvent(new InvoiceAuthenticatedEvent(id, invoice.toString())); return Result.ok(item); } get description(): InvoiceItemDescription { return this.props.description; } get quantity(): Quantity { return this.props.quantity; } get unitPrice(): MoneyValue { return this.props.unitPrice; } get subtotalPrice(): MoneyValue { if (!this._subtotalPrice) { this._subtotalPrice = this.calculateSubtotal(); } return this._subtotalPrice; } get discount(): Percentage { return this.props.discount; } get totalPrice(): MoneyValue { if (!this._totalPrice) { this._totalPrice = this.calculateTotal(); } return this._totalPrice; } getValue() { return this.props; } toPrimitive() { return { description: this.description.toPrimitive(), quantity: this.quantity.toPrimitive(), unit_price: this.unitPrice.toPrimitive(), subtotal_price: this.subtotalPrice.toPrimitive(), discount: this.discount.toPrimitive(), total_price: this.totalPrice.toPrimitive(), }; } calculateSubtotal(): MoneyValue { return this.unitPrice.multiply(this.quantity.toNumber()); // Precio unitario * Cantidad } calculateTotal(): MoneyValue { return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber())); } }