Uecko_ERP/modules/customer-invoices/src/api/domain/entities/invoice-items/invoice-item.ts
2025-06-12 08:55:17 +02:00

108 lines
3.1 KiB
TypeScript

import { DomainEntity, UniqueID } from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";
import {
CustomerInvoiceItemDescription,
CustomerInvoiceItemDiscount,
CustomerInvoiceItemQuantity,
CustomerInvoiceItemSubtotalPrice,
CustomerInvoiceItemTotalPrice,
CustomerInvoiceItemUnitPrice,
} from "../../value-objects";
export interface ICustomerInvoiceItemProps {
description: CustomerInvoiceItemDescription;
quantity: CustomerInvoiceItemQuantity; // Cantidad de unidades
unitPrice: CustomerInvoiceItemUnitPrice; // Precio unitario en la moneda de la factura
//subtotalPrice?: MoneyValue; // Precio unitario * Cantidad
discount: CustomerInvoiceItemDiscount; // % descuento
//totalPrice?: MoneyValue;
}
export interface ICustomerInvoiceItem {
id: UniqueID;
description: CustomerInvoiceItemDescription;
quantity: CustomerInvoiceItemQuantity;
unitPrice: CustomerInvoiceItemUnitPrice;
subtotalPrice: CustomerInvoiceItemSubtotalPrice;
discount: CustomerInvoiceItemDiscount;
totalPrice: CustomerInvoiceItemTotalPrice;
}
export class CustomerInvoiceItem
extends DomainEntity<ICustomerInvoiceItemProps>
implements ICustomerInvoiceItem
{
private _subtotalPrice!: CustomerInvoiceItemSubtotalPrice;
private _totalPrice!: CustomerInvoiceItemTotalPrice;
public static create(
props: ICustomerInvoiceItemProps,
id?: UniqueID
): Result<CustomerInvoiceItem, Error> {
const item = new CustomerInvoiceItem(props, id);
// Reglas de negocio / validaciones
// ...
// ...
// 🔹 Disparar evento de dominio "CustomerInvoiceItemCreatedEvent"
//const { customerInvoice } = props;
//user.addDomainEvent(new CustomerInvoiceAuthenticatedEvent(id, customerInvoice.toString()));
return Result.ok(item);
}
get description(): CustomerInvoiceItemDescription {
return this.props.description;
}
get quantity(): CustomerInvoiceItemQuantity {
return this.props.quantity;
}
get unitPrice(): CustomerInvoiceItemUnitPrice {
return this.props.unitPrice;
}
get subtotalPrice(): CustomerInvoiceItemSubtotalPrice {
if (!this._subtotalPrice) {
this._subtotalPrice = this.calculateSubtotal();
}
return this._subtotalPrice;
}
get discount(): CustomerInvoiceItemDiscount {
return this.props.discount;
}
get totalPrice(): CustomerInvoiceItemTotalPrice {
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(): CustomerInvoiceItemSubtotalPrice {
return this.unitPrice.multiply(this.quantity.toNumber()); // Precio unitario * Cantidad
}
calculateTotal(): CustomerInvoiceItemTotalPrice {
return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
}
}