.
This commit is contained in:
parent
cc38faed94
commit
167eaff171
@ -21,7 +21,7 @@ import {
|
||||
type ItemAmount,
|
||||
} from "../../common/value-objects";
|
||||
import { ProformaItems } from "../entities/proforma-items";
|
||||
import { type IProformaTaxTotals, ProformaTaxCalculator } from "../services";
|
||||
import { type IProformaTaxTotals, ProformaTaxesCalculator } from "../services";
|
||||
|
||||
export type ProformaProps = {
|
||||
companyId: UniqueID;
|
||||
@ -255,7 +255,7 @@ export class Proforma extends AggregateRoot<ProformaProps> implements IProforma
|
||||
}
|
||||
|
||||
public taxes(): Collection<IProformaTaxTotals> {
|
||||
return new ProformaTaxCalculator(this.items).calculate();
|
||||
return new ProformaTaxesCalculator(this.items).calculate();
|
||||
}
|
||||
|
||||
public getProps(): ProformaProps {
|
||||
|
||||
@ -2,7 +2,7 @@ import type { DiscountPercentage } from "@erp/core/api";
|
||||
import type { CurrencyCode, LanguageCode } from "@repo/rdx-ddd";
|
||||
import { Collection } from "@repo/rdx-utils";
|
||||
|
||||
import { ItemAmount } from "../../../common";
|
||||
import { ProformaItemsTotalsCalculator } from "../../services/proforma-items-totals-calculator";
|
||||
|
||||
import type { IProformaItem, IProformaItemTotals, ProformaItem } from "./proforma-item.entity";
|
||||
|
||||
@ -77,63 +77,7 @@ export class ProformaItems extends Collection<ProformaItem> implements IProforma
|
||||
* Delega en los ítems individuales (DDD correcto) pero evita múltiples recorridos.
|
||||
*/
|
||||
public totals(): IProformaItemTotals {
|
||||
let subtotalAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
|
||||
let itemDiscountAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
let globalDiscountAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
let totalDiscountAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
|
||||
let taxableAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
|
||||
let ivaAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
let recAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
let retentionAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
|
||||
let taxesAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
let totalAmount = ItemAmount.zero(this.currencyCode.code);
|
||||
|
||||
for (const item of this.getAll()) {
|
||||
const amounts = item.totals();
|
||||
|
||||
// Subtotales
|
||||
subtotalAmount = subtotalAmount.add(amounts.subtotalAmount);
|
||||
|
||||
// Descuentos
|
||||
itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount);
|
||||
globalDiscountAmount = globalDiscountAmount.add(amounts.globalDiscountAmount);
|
||||
totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount);
|
||||
|
||||
// Base imponible
|
||||
taxableAmount = taxableAmount.add(amounts.taxableAmount);
|
||||
|
||||
// Impuestos individuales
|
||||
ivaAmount = ivaAmount.add(amounts.ivaAmount);
|
||||
recAmount = recAmount.add(amounts.recAmount);
|
||||
retentionAmount = retentionAmount.add(amounts.retentionAmount);
|
||||
|
||||
// Total impuestos del ítem
|
||||
taxesAmount = taxesAmount.add(amounts.taxesAmount);
|
||||
|
||||
// Total final del ítem
|
||||
totalAmount = totalAmount.add(amounts.totalAmount);
|
||||
}
|
||||
|
||||
return {
|
||||
subtotalAmount,
|
||||
|
||||
itemDiscountAmount,
|
||||
globalDiscountAmount,
|
||||
totalDiscountAmount,
|
||||
|
||||
taxableAmount,
|
||||
|
||||
ivaAmount,
|
||||
recAmount,
|
||||
retentionAmount,
|
||||
|
||||
taxesAmount,
|
||||
totalAmount,
|
||||
} as const;
|
||||
return new ProformaItemsTotalsCalculator(this).calculate();
|
||||
}
|
||||
|
||||
private ensureSameCurrencyAndLanguage(items: IProformaItem[]): void {
|
||||
|
||||
@ -1 +1 @@
|
||||
export * from "./proforma-tax-calculator";
|
||||
export * from "./proforma-taxes-calculator";
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { TaxPercentage } from "@erp/core/api";
|
||||
import type { Maybe } from "@repo/rdx-utils";
|
||||
|
||||
import type { IProformaTaxTotals } from "./proforma-tax-calculator";
|
||||
import type { IProformaTaxTotals } from "./proforma-taxes-calculator";
|
||||
|
||||
/**
|
||||
* Orden determinista:
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
import { ItemAmount } from "../../common";
|
||||
import type { IProformaItems } from "../entities";
|
||||
|
||||
export interface IProformaItemsTotals {
|
||||
subtotalAmount: ItemAmount;
|
||||
|
||||
itemDiscountAmount: ItemAmount;
|
||||
globalDiscountAmount: ItemAmount;
|
||||
totalDiscountAmount: ItemAmount;
|
||||
|
||||
taxableAmount: ItemAmount;
|
||||
|
||||
ivaAmount: ItemAmount;
|
||||
recAmount: ItemAmount;
|
||||
retentionAmount: ItemAmount;
|
||||
|
||||
taxesAmount: ItemAmount;
|
||||
totalAmount: ItemAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcula los totales (scale 4) a partir de las líneas valoradas.
|
||||
* La lógica fiscal está en ProformaItem; aquí solo se agregan resultados.
|
||||
*/
|
||||
export class ProformaItemsTotalsCalculator {
|
||||
constructor(private readonly items: IProformaItems) {}
|
||||
|
||||
public calculate(): IProformaItemsTotals {
|
||||
const zero = ItemAmount.zero(this.items.currencyCode.code);
|
||||
|
||||
let subtotalAmount = zero;
|
||||
|
||||
let itemDiscountAmount = zero;
|
||||
let globalDiscountAmount = zero;
|
||||
let totalDiscountAmount = zero;
|
||||
|
||||
let taxableAmount = zero;
|
||||
|
||||
let ivaAmount = zero;
|
||||
let recAmount = zero;
|
||||
let retentionAmount = zero;
|
||||
|
||||
let taxesAmount = zero;
|
||||
let totalAmount = zero;
|
||||
|
||||
for (const item of this.items.getAll()) {
|
||||
const amounts = item.totals();
|
||||
|
||||
// Subtotales
|
||||
subtotalAmount = subtotalAmount.add(amounts.subtotalAmount);
|
||||
|
||||
// Descuentos
|
||||
itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount);
|
||||
globalDiscountAmount = globalDiscountAmount.add(amounts.globalDiscountAmount);
|
||||
totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount);
|
||||
|
||||
// Base imponible
|
||||
taxableAmount = taxableAmount.add(amounts.taxableAmount);
|
||||
|
||||
// Impuestos individuales
|
||||
ivaAmount = ivaAmount.add(amounts.ivaAmount);
|
||||
recAmount = recAmount.add(amounts.recAmount);
|
||||
retentionAmount = retentionAmount.add(amounts.retentionAmount);
|
||||
|
||||
// Total impuestos del ítem
|
||||
taxesAmount = taxesAmount.add(amounts.taxesAmount);
|
||||
|
||||
// Total final del ítem
|
||||
totalAmount = totalAmount.add(amounts.totalAmount);
|
||||
}
|
||||
|
||||
return {
|
||||
subtotalAmount,
|
||||
|
||||
itemDiscountAmount,
|
||||
globalDiscountAmount,
|
||||
totalDiscountAmount,
|
||||
|
||||
taxableAmount,
|
||||
|
||||
ivaAmount,
|
||||
recAmount,
|
||||
retentionAmount,
|
||||
|
||||
taxesAmount,
|
||||
totalAmount,
|
||||
} as const;
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ export interface IProformaTaxTotals {
|
||||
taxesAmount: InvoiceAmount;
|
||||
}
|
||||
|
||||
export class ProformaTaxCalculator {
|
||||
export class ProformaTaxesCalculator {
|
||||
constructor(private readonly items: IProformaItems) {}
|
||||
|
||||
public calculate(): Collection<IProformaTaxTotals> {
|
||||
@ -8,8 +8,6 @@ import { ValueObject } from "./value-object";
|
||||
const DEFAULT_SCALE = 2;
|
||||
const DEFAULT_CURRENCY_CODE = "EUR";
|
||||
|
||||
type CurrencyData = Currency;
|
||||
|
||||
export type RoundingMode =
|
||||
| "HALF_ODD"
|
||||
| "HALF_EVEN"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user