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

105 lines
3.1 KiB
TypeScript
Raw Normal View History

2025-09-26 15:00:11 +00:00
import { Tax } from "@erp/core/api";
2025-09-03 10:41:12 +00:00
import { CurrencyCode, LanguageCode } from "@repo/rdx-ddd";
import { Collection } from "@repo/rdx-utils";
2025-09-10 18:14:19 +00:00
import { ItemAmount } from "../../value-objects";
2025-09-03 10:41:12 +00:00
import { CustomerInvoiceItem } from "./customer-invoice-item";
export interface CustomerInvoiceItemsProps {
items?: CustomerInvoiceItem[];
languageCode: LanguageCode;
currencyCode: CurrencyCode;
}
export class CustomerInvoiceItems extends Collection<CustomerInvoiceItem> {
private _languageCode!: LanguageCode;
private _currencyCode!: CurrencyCode;
constructor(props: CustomerInvoiceItemsProps) {
2025-09-07 19:55:12 +00:00
const { items = [], languageCode, currencyCode } = props;
2025-09-03 10:41:12 +00:00
super(items);
this._languageCode = languageCode;
this._currencyCode = currencyCode;
}
public static create(props: CustomerInvoiceItemsProps): CustomerInvoiceItems {
return new CustomerInvoiceItems(props);
}
2025-09-07 19:55:12 +00:00
add(item: CustomerInvoiceItem): boolean {
// Antes de añadir un nuevo item, debo comprobar que el item a añadir
// tiene el mismo "currencyCode" y "languageCode" que la colección de items.
2025-09-10 18:14:19 +00:00
if (
!this._languageCode.equals(item.languageCode) ||
!this._currencyCode.equals(item.currencyCode)
) {
2025-09-07 19:55:12 +00:00
return false;
}
2025-09-10 18:14:19 +00:00
return super.add(item);
2025-09-07 19:55:12 +00:00
}
2025-09-17 17:37:41 +00:00
public getSubtotalAmount(): ItemAmount {
return this.getAll().reduce(
(total, tax) => total.add(tax.getSubtotalAmount()),
ItemAmount.zero(this._currencyCode.code)
);
}
public getDiscountAmount(): ItemAmount {
return this.getAll().reduce(
(total, item) => total.add(item.getDiscountAmount()),
ItemAmount.zero(this._currencyCode.code)
);
}
public getTaxableAmount(): ItemAmount {
return this.getAll().reduce(
(total, item) => total.add(item.getTaxableAmount()),
ItemAmount.zero(this._currencyCode.code)
);
}
public getTaxesAmount(): ItemAmount {
return this.getAll().reduce(
(total, item) => total.add(item.getTaxesAmount()),
ItemAmount.zero(this._currencyCode.code)
);
}
2025-09-10 18:14:19 +00:00
public getTotalAmount(): ItemAmount {
return this.getAll().reduce(
2025-09-17 17:37:41 +00:00
(total, item) => total.add(item.getTotalAmount()),
2025-09-10 18:14:19 +00:00
ItemAmount.zero(this._currencyCode.code)
);
}
2025-09-26 15:00:11 +00:00
2025-09-26 18:09:14 +00:00
public getTaxesAmountByTaxes() {
const resultMap = new Map<Tax, { taxableAmount: ItemAmount; taxesAmount: ItemAmount }>();
2025-09-26 15:00:11 +00:00
const currencyCode = this._currencyCode.code;
for (const item of this.getAll()) {
2025-09-26 18:09:14 +00:00
for (const { taxableAmount, tax, taxesAmount } of item.getTaxesAmountByTaxes()) {
const { taxableAmount: taxableCurrent, taxesAmount: taxesCurrent } = resultMap.get(tax) ?? {
taxableAmount: ItemAmount.zero(currencyCode),
taxesAmount: ItemAmount.zero(currencyCode),
};
resultMap.set(tax, {
taxableAmount: taxableCurrent.add(taxableAmount),
taxesAmount: taxesCurrent.add(taxesAmount),
});
2025-09-26 15:00:11 +00:00
}
}
2025-09-26 18:09:14 +00:00
const items = [];
for (const [tax, { taxableAmount, taxesAmount }] of resultMap) {
items.push({
taxableAmount,
tax,
taxesAmount,
});
2025-09-26 15:00:11 +00:00
}
2025-09-26 18:09:14 +00:00
return items;
2025-09-26 15:00:11 +00:00
}
2025-09-03 10:41:12 +00:00
}