.
This commit is contained in:
parent
cc38faed94
commit
167eaff171
@ -21,7 +21,7 @@ import {
|
|||||||
type ItemAmount,
|
type ItemAmount,
|
||||||
} from "../../common/value-objects";
|
} from "../../common/value-objects";
|
||||||
import { ProformaItems } from "../entities/proforma-items";
|
import { ProformaItems } from "../entities/proforma-items";
|
||||||
import { type IProformaTaxTotals, ProformaTaxCalculator } from "../services";
|
import { type IProformaTaxTotals, ProformaTaxesCalculator } from "../services";
|
||||||
|
|
||||||
export type ProformaProps = {
|
export type ProformaProps = {
|
||||||
companyId: UniqueID;
|
companyId: UniqueID;
|
||||||
@ -255,7 +255,7 @@ export class Proforma extends AggregateRoot<ProformaProps> implements IProforma
|
|||||||
}
|
}
|
||||||
|
|
||||||
public taxes(): Collection<IProformaTaxTotals> {
|
public taxes(): Collection<IProformaTaxTotals> {
|
||||||
return new ProformaTaxCalculator(this.items).calculate();
|
return new ProformaTaxesCalculator(this.items).calculate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getProps(): ProformaProps {
|
public getProps(): ProformaProps {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import type { DiscountPercentage } from "@erp/core/api";
|
|||||||
import type { CurrencyCode, LanguageCode } from "@repo/rdx-ddd";
|
import type { CurrencyCode, LanguageCode } from "@repo/rdx-ddd";
|
||||||
import { Collection } from "@repo/rdx-utils";
|
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";
|
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.
|
* Delega en los ítems individuales (DDD correcto) pero evita múltiples recorridos.
|
||||||
*/
|
*/
|
||||||
public totals(): IProformaItemTotals {
|
public totals(): IProformaItemTotals {
|
||||||
let subtotalAmount = ItemAmount.zero(this.currencyCode.code);
|
return new ProformaItemsTotalsCalculator(this).calculate();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ensureSameCurrencyAndLanguage(items: IProformaItem[]): void {
|
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 { TaxPercentage } from "@erp/core/api";
|
||||||
import type { Maybe } from "@repo/rdx-utils";
|
import type { Maybe } from "@repo/rdx-utils";
|
||||||
|
|
||||||
import type { IProformaTaxTotals } from "./proforma-tax-calculator";
|
import type { IProformaTaxTotals } from "./proforma-taxes-calculator";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orden determinista:
|
* 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;
|
taxesAmount: InvoiceAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProformaTaxCalculator {
|
export class ProformaTaxesCalculator {
|
||||||
constructor(private readonly items: IProformaItems) {}
|
constructor(private readonly items: IProformaItems) {}
|
||||||
|
|
||||||
public calculate(): Collection<IProformaTaxTotals> {
|
public calculate(): Collection<IProformaTaxTotals> {
|
||||||
@ -8,8 +8,6 @@ import { ValueObject } from "./value-object";
|
|||||||
const DEFAULT_SCALE = 2;
|
const DEFAULT_SCALE = 2;
|
||||||
const DEFAULT_CURRENCY_CODE = "EUR";
|
const DEFAULT_CURRENCY_CODE = "EUR";
|
||||||
|
|
||||||
type CurrencyData = Currency;
|
|
||||||
|
|
||||||
export type RoundingMode =
|
export type RoundingMode =
|
||||||
| "HALF_ODD"
|
| "HALF_ODD"
|
||||||
| "HALF_EVEN"
|
| "HALF_EVEN"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user