Uecko_ERP/modules/customer-invoices/src/api/domain/entities/customer-invoice-items/customer-invoice-item.ts

167 lines
4.3 KiB
TypeScript
Raw Normal View History

2025-09-10 11:57:15 +00:00
import { CurrencyCode, DomainEntity, LanguageCode, Percentage, UniqueID } from "@repo/rdx-ddd";
2025-09-03 10:41:12 +00:00
import { Maybe, Result } from "@repo/rdx-utils";
import {
CustomerInvoiceItemDescription,
2025-09-05 11:23:45 +00:00
ItemAmount,
ItemDiscount,
ItemQuantity,
2025-09-03 10:41:12 +00:00
} from "../../value-objects";
2025-09-10 11:57:15 +00:00
import { ItemTaxes } from "../item-taxes";
2025-09-03 10:41:12 +00:00
export interface CustomerInvoiceItemProps {
description: Maybe<CustomerInvoiceItemDescription>;
2025-09-05 11:23:45 +00:00
quantity: Maybe<ItemQuantity>; // Cantidad de unidades
unitAmount: Maybe<ItemAmount>; // Precio unitario en la moneda de la factura
2025-09-10 11:57:15 +00:00
2025-09-05 11:23:45 +00:00
discountPercentage: Maybe<ItemDiscount>; // % descuento
2025-09-03 10:41:12 +00:00
2025-09-10 11:57:15 +00:00
taxes: ItemTaxes;
2025-09-07 19:55:12 +00:00
2025-09-03 10:41:12 +00:00
languageCode: LanguageCode;
currencyCode: CurrencyCode;
}
2025-09-05 11:23:45 +00:00
export interface ICustomerInvoiceItem {
description: Maybe<CustomerInvoiceItemDescription>;
quantity: Maybe<ItemQuantity>; // Cantidad de unidades
unitAmount: Maybe<ItemAmount>; // Precio unitario en la moneda de la factura
discountPercentage: Maybe<ItemDiscount>; // % descuento
2025-09-10 11:57:15 +00:00
taxes: ItemTaxes;
2025-09-05 11:23:45 +00:00
languageCode: LanguageCode;
currencyCode: CurrencyCode;
2025-09-10 11:57:15 +00:00
getSubtotalAmount(): ItemAmount;
getDiscountAmount(): ItemAmount;
2025-09-05 11:23:45 +00:00
2025-09-10 11:57:15 +00:00
getTaxableAmount(): ItemAmount;
getTaxesAmount(): ItemAmount;
getTotalAmount(): ItemAmount;
2025-09-05 11:23:45 +00:00
}
export class CustomerInvoiceItem
extends DomainEntity<CustomerInvoiceItemProps>
implements ICustomerInvoiceItem
{
2025-09-03 10:41:12 +00:00
public static create(
props: CustomerInvoiceItemProps,
id?: UniqueID
): Result<CustomerInvoiceItem, Error> {
const item = new CustomerInvoiceItem(props, id);
// Reglas de negocio / validaciones
// ...
// ...
return Result.ok(item);
}
get description(): Maybe<CustomerInvoiceItemDescription> {
return this.props.description;
}
2025-09-05 11:23:45 +00:00
get quantity(): Maybe<ItemQuantity> {
2025-09-03 10:41:12 +00:00
return this.props.quantity;
}
2025-09-05 11:23:45 +00:00
get unitAmount(): Maybe<ItemAmount> {
2025-09-04 17:57:04 +00:00
return this.props.unitAmount;
2025-09-03 10:41:12 +00:00
}
2025-09-04 17:57:04 +00:00
get discountPercentage(): Maybe<Percentage> {
return this.props.discountPercentage;
}
2025-09-10 11:57:15 +00:00
get languageCode(): LanguageCode {
return this.props.languageCode;
2025-09-03 10:41:12 +00:00
}
2025-09-10 11:57:15 +00:00
get currencyCode(): CurrencyCode {
return this.props.currencyCode;
2025-09-05 11:23:45 +00:00
}
2025-09-10 11:57:15 +00:00
get taxes(): ItemTaxes {
return this.props.taxes;
2025-09-05 11:23:45 +00:00
}
2025-09-10 11:57:15 +00:00
getProps(): CustomerInvoiceItemProps {
return this.props;
2025-09-03 10:41:12 +00:00
}
2025-09-10 11:57:15 +00:00
toPrimitive() {
return this.getProps();
2025-09-03 10:41:12 +00:00
}
2025-09-17 17:37:41 +00:00
private _getDiscountAmount(subtotalAmount: ItemAmount): ItemAmount {
const discount = this.discountPercentage.match(
(percentage) => percentage,
() => ItemDiscount.zero()
);
return subtotalAmount.percentage(discount);
}
private _getTaxableAmount(subtotalAmount: ItemAmount, discountAmount: ItemAmount): ItemAmount {
return subtotalAmount.subtract(discountAmount);
}
private _getTaxesAmount(taxableAmount: ItemAmount): ItemAmount {
return this.props.taxes.getTaxesAmount(taxableAmount);
}
private _getTotalAmount(taxableAmount: ItemAmount, taxesAmount: ItemAmount): ItemAmount {
return taxableAmount.add(taxesAmount);
}
2025-09-10 11:57:15 +00:00
public getSubtotalAmount(): ItemAmount {
const curCode = this.currencyCode.code;
const quantity = this.quantity.match(
(quantity) => quantity,
() => ItemQuantity.zero()
);
const unitAmount = this.unitAmount.match(
(unitAmount) => unitAmount,
() => ItemAmount.zero(curCode)
);
return unitAmount.multiply(quantity);
2025-09-03 10:41:12 +00:00
}
2025-09-10 11:57:15 +00:00
public getDiscountAmount(): ItemAmount {
2025-09-17 17:37:41 +00:00
return this._getDiscountAmount(this.getSubtotalAmount());
2025-09-03 10:41:12 +00:00
}
2025-09-10 11:57:15 +00:00
public getTaxableAmount(): ItemAmount {
2025-09-17 17:37:41 +00:00
return this._getTaxableAmount(this.getSubtotalAmount(), this.getDiscountAmount());
2025-09-03 10:41:12 +00:00
}
2025-09-10 11:57:15 +00:00
public getTaxesAmount(): ItemAmount {
return this._getTaxesAmount(this.getTaxableAmount());
}
public getTotalAmount(): ItemAmount {
const taxableAmount = this.getTaxableAmount();
2025-09-17 17:37:41 +00:00
const taxesAmount = this._getTaxesAmount(taxableAmount);
return this._getTotalAmount(taxableAmount, taxesAmount);
2025-09-10 11:57:15 +00:00
}
2025-09-03 10:41:12 +00:00
2025-09-10 11:57:15 +00:00
public getAllAmounts() {
2025-09-17 17:37:41 +00:00
const subtotalAmount = this.getSubtotalAmount();
const discountAmount = this._getDiscountAmount(subtotalAmount);
const taxableAmount = this._getTaxableAmount(subtotalAmount, discountAmount);
const taxesAmount = this._getTaxesAmount(taxableAmount);
const totalAmount = this._getTotalAmount(taxableAmount, taxesAmount);
2025-09-10 11:57:15 +00:00
return {
2025-09-17 17:37:41 +00:00
subtotalAmount,
discountAmount,
taxableAmount,
taxesAmount,
totalAmount,
2025-09-10 11:57:15 +00:00
};
2025-09-03 10:41:12 +00:00
}
}