From 9961383a9f638898f8b4c31c917db316d09f9be7 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 12 May 2026 21:42:21 +0200 Subject: [PATCH] . Co-authored-by: Copilot --- ...forma-to-issued-invoice-props-converter.ts | 10 +- .../full/proforma-full-snapshot-builder.ts | 8 +- .../proforma-items-full-snapshot-builder.ts | 24 ++-- .../aggregates/proforma.aggregate.ts | 20 +-- .../proforma-items/proforma-item.entity.ts | 64 ++++----- .../proforma-items.collection.ts | 125 ++---------------- .../api/domain/proformas/services/index.ts | 3 + .../services/proforma-compute-tax-groups.ts | 11 +- .../proforma-items-totals-calculator.ts | 18 ++- .../services/proforma-taxes-calculator.ts | 10 +- .../sequelize-proforma-domain.mapper.ts | 3 - .../sequelize-proforma-item-domain.mapper.ts | 20 ++- ...roforma-to-proforma-update-form.adapter.ts | 2 + 13 files changed, 119 insertions(+), 199 deletions(-) diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts index f95777bd..4428548f 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts @@ -127,7 +127,13 @@ export class ProformaToIssuedInvoiceConverter implements IProformaToIssuedInvoic proforma: Proforma, item: ReturnType[number] ): Result { - const itemTotals = item.totals(); + const calculationContext = { + languageCode: proforma.languageCode, + currencyCode: proforma.currencyCode, + globalDiscountPercentage: proforma.globalDiscountPercentage, + }; + + const itemTotals = item.totals(calculationContext); return IssuedInvoiceItem.create({ description: item.description, @@ -139,7 +145,7 @@ export class ProformaToIssuedInvoiceConverter implements IProformaToIssuedInvoic itemDiscountPercentage: item.itemDiscountPercentage, itemDiscountAmount: itemTotals.itemDiscountAmount, - globalDiscountPercentage: item.globalDiscountPercentage, + globalDiscountPercentage: proforma.globalDiscountPercentage, globalDiscountAmount: itemTotals.globalDiscountAmount, totalDiscountAmount: itemTotals.totalDiscountAmount, diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts index 6a16137c..1c50e780 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts @@ -22,7 +22,13 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder ) {} toOutput(proforma: Proforma): ProformaFullSnapshot { - const items = this.itemsBuilder.toOutput(proforma.items); + const calculationContext = { + languageCode: proforma.languageCode, + currencyCode: proforma.currencyCode, + globalDiscountPercentage: proforma.globalDiscountPercentage, + }; + + const items = this.itemsBuilder.toOutput(proforma.items, calculationContext); const recipient = this.recipientBuilder.toOutput(proforma); const taxes = this.taxesBuilder.toOutput(proforma.taxes()); //const paymentMethod = this.paymentMethodBuilder.toOutput(proforma.paymentMethod); diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts index 362ab1e3..0b4af5db 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts @@ -1,17 +1,21 @@ -import type { ISnapshotBuilder } from "@erp/core/api"; import type { ProformaItemDetailDTO } from "@erp/customer-invoices/common"; import { maybeToNullable } from "@repo/rdx-ddd"; -import { ItemAmount, type ProformaItem, type ProformaItems } from "../../../../domain"; +import { ItemAmount, type ProformaCalculationContext, type ProformaItem, type ProformaItems } from "../../../../domain"; -export interface IProformaItemsFullSnapshotBuilder - extends ISnapshotBuilder {} +export interface IProformaItemsFullSnapshotBuilder { + toOutput(invoiceItems: ProformaItems, context: ProformaCalculationContext): ProformaItemDetailDTO[]; +} export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnapshotBuilder { - private mapItem(proformaItem: ProformaItem, index: number): ProformaItemDetailDTO { - const allAmounts = proformaItem.totals(); + private mapItem( + proformaItem: ProformaItem, + context: ProformaCalculationContext, + index: number + ): ProformaItemDetailDTO { + const allAmounts = proformaItem.totals(context); const isValued = proformaItem.isValued(); - const currencyCode = proformaItem.currencyCode.code; + const currencyCode = context.currencyCode.code; return { id: proformaItem.id.toPrimitive(), @@ -34,7 +38,7 @@ export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnaps ? allAmounts.itemDiscountAmount.toObjectString() : ItemAmount.zero(currencyCode).toObjectString(), - global_discount_percentage: proformaItem.globalDiscountPercentage.toObjectString(), + global_discount_percentage: context.globalDiscountPercentage.toObjectString(), global_discount_amount: isValued ? allAmounts.globalDiscountAmount.toObjectString() @@ -81,7 +85,7 @@ export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnaps }; } - toOutput(invoiceItems: ProformaItems): ProformaItemDetailDTO[] { - return invoiceItems.map((item, index) => this.mapItem(item, index)); + toOutput(invoiceItems: ProformaItems, context: ProformaCalculationContext): ProformaItemDetailDTO[] { + return invoiceItems.map((item, index) => this.mapItem(item, context, index)); } } diff --git a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts index c45d96d4..1dc5b980 100644 --- a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts +++ b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts @@ -27,7 +27,7 @@ import { ProformaItems, } from "../entities"; import { ProformaItemMismatch } from "../errors"; -import type { IProformaTaxTotals } from "../services"; +import type { IProformaTaxTotals, ProformaCalculationContext } from "../services"; import { ProformaItemTaxes } from "../value-objects"; export interface IProformaCreateProps { @@ -128,9 +128,6 @@ export class Proforma extends AggregateRoot implements IP const internalItems = ProformaItems.create({ items: [], - languageCode: props.languageCode, - currencyCode: props.currencyCode, - globalDiscountPercentage: props.globalDiscountPercentage, }); const { items, ...internalProps } = props; @@ -201,9 +198,6 @@ export class Proforma extends AggregateRoot implements IP for (const [index, itemProps] of itemsProps.entries()) { const itemResult = ProformaItem.create({ ...itemProps, - languageCode: this.languageCode, - currencyCode: this.currencyCode, - globalDiscountPercentage: this.globalDiscountPercentage, }); if (itemResult.isFailure) { @@ -413,7 +407,7 @@ export class Proforma extends AggregateRoot implements IP * La cabecera NO recalcula lógica de porcentaje — toda la lógica está en Item/Items. */ public totals(): IProformaTotals { - const itemsTotals = this.items.totals(); + const itemsTotals = this.items.totals(this.calculationContext()); return { subtotalAmount: this.toInvoiceAmount(itemsTotals.subtotalAmount), @@ -434,7 +428,7 @@ export class Proforma extends AggregateRoot implements IP } public taxes(): Collection { - return this.items.taxes(); + return this.items.taxes(this.calculationContext()); } public addItem(props: IProformaItemCreateProps): Result { @@ -457,6 +451,14 @@ export class Proforma extends AggregateRoot implements IP return Result.ok(); } + private calculationContext(): ProformaCalculationContext { + return { + languageCode: this.languageCode, + currencyCode: this.currencyCode, + globalDiscountPercentage: this.globalDiscountPercentage, + }; + } + // Helpers /** diff --git a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts index 671d5713..6b2c643a 100644 --- a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts +++ b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts @@ -1,8 +1,9 @@ import { DiscountPercentage, type Tax, type TaxPercentage } from "@erp/core/api"; -import { type CurrencyCode, DomainEntity, type LanguageCode, type UniqueID } from "@repo/rdx-ddd"; +import { DomainEntity, type UniqueID } from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; import { ItemAmount, type ItemDescription, type ItemQuantity } from "../../../common"; +import type { ProformaCalculationContext } from "../../services"; import { ProformaItemTaxes, type ProformaItemTaxesProps, @@ -34,18 +35,9 @@ export interface IProformaItemCreateProps { itemDiscountPercentage: Maybe; // % descuento de línea taxes: ProformaItemTaxesProps; - - // Estos campos vienen de la cabecera, - // pero se necesitan para cálculos y representaciones de la línea. - globalDiscountPercentage: DiscountPercentage; // % descuento de la cabecera - languageCode: LanguageCode; // Para formateos específicos de idioma - currencyCode: CurrencyCode; // Para cálculos y formateos de moneda } -export type ProformaItemPatchProps = Omit< - IProformaItemCreateProps, - "globalDiscountPercentage" | "languageCode" | "currencyCode" ->; +export type ProformaItemPatchProps = IProformaItemCreateProps; export interface IProformaItemTotals { subtotalAmount: ItemAmount; @@ -67,16 +59,12 @@ export interface IProformaItemTotals { export interface IProformaItem { description: Maybe; - languageCode: LanguageCode; - currencyCode: CurrencyCode; - quantity: Maybe; unitAmount: Maybe; taxes: ProformaItemTaxes; itemDiscountPercentage: Maybe; // Descuento en línea - globalDiscountPercentage: DiscountPercentage; // Descuento en cabecera ivaCode(): Maybe; ivaPercentage(): Maybe; @@ -87,7 +75,8 @@ export interface IProformaItem { retentionCode(): Maybe; retentionPercentage(): Maybe; - totals(): IProformaItemTotals; + totals(context: ProformaCalculationContext): IProformaItemTotals; + subtotalAmount(context: ProformaCalculationContext): ItemAmount; isValued(): boolean; // Indica si el item tiene cantidad o precio (o ambos) para ser considerado "valorizado" } @@ -135,14 +124,6 @@ export class ProformaItem extends DomainEntity implem return this.props.description; } - get languageCode() { - return this.props.languageCode; - } - - get currencyCode() { - return this.props.currencyCode; - } - get quantity() { return this.props.quantity; } @@ -155,10 +136,6 @@ export class ProformaItem extends DomainEntity implem return this.props.itemDiscountPercentage; } - get globalDiscountPercentage() { - return this.props.globalDiscountPercentage; - } - get taxes() { return this.props.taxes; } @@ -178,9 +155,9 @@ export class ProformaItem extends DomainEntity implem return this.props.quantity.isSome() && this.props.unitAmount.isSome(); } - public subtotalAmount(): ItemAmount { + public subtotalAmount(context: ProformaCalculationContext): ItemAmount { if (!this.isValued()) { - return ItemAmount.zero(this.currencyCode.code); + return ItemAmount.zero(context.currencyCode.code); } const quantity = this.quantity.unwrap(); @@ -240,13 +217,14 @@ export class ProformaItem extends DomainEntity implem * - totalAmount * */ - public totals(): IProformaItemTotals { - const subtotalAmount = this._calculateSubtotalAmount(); + public totals(context: ProformaCalculationContext): IProformaItemTotals { + const subtotalAmount = this._calculateSubtotalAmount(context); - const itemDiscountAmount = this._calculateItemDiscountAmount(subtotalAmount); + const itemDiscountAmount = this._calculateItemDiscountAmount(subtotalAmount, context); const globalDiscountAmount = this._calculateGlobalDiscountAmount( subtotalAmount, - itemDiscountAmount + itemDiscountAmount, + context ); const totalDiscountAmount = this._calculateTotalDiscountAmount( itemDiscountAmount, @@ -286,9 +264,9 @@ export class ProformaItem extends DomainEntity implem /** * @summary Helper puro para calcular el subtotal. */ - private _calculateSubtotalAmount(): ItemAmount { + private _calculateSubtotalAmount(context: ProformaCalculationContext): ItemAmount { if (!this.isValued()) { - return ItemAmount.zero(this.currencyCode.code); + return ItemAmount.zero(context.currencyCode.code); } const quantity = this.quantity.unwrap(); @@ -300,9 +278,12 @@ export class ProformaItem extends DomainEntity implem /** * @summary Helper puro para calcular el descuento de línea. */ - private _calculateItemDiscountAmount(subtotal: ItemAmount): ItemAmount { + private _calculateItemDiscountAmount( + subtotal: ItemAmount, + context: ProformaCalculationContext + ): ItemAmount { if (!this.isValued() || this.props.itemDiscountPercentage.isNone()) { - return ItemAmount.zero(this.currencyCode.code); + return ItemAmount.zero(context.currencyCode.code); } const discountPercentage = this.props.itemDiscountPercentage.match( @@ -318,15 +299,16 @@ export class ProformaItem extends DomainEntity implem */ private _calculateGlobalDiscountAmount( subtotalAmount: ItemAmount, - discountAmount: ItemAmount + discountAmount: ItemAmount, + context: ProformaCalculationContext ): ItemAmount { if (!this.isValued()) { - return ItemAmount.zero(this.currencyCode.code); + return ItemAmount.zero(context.currencyCode.code); } const amountAfterLineDiscount = subtotalAmount.subtract(discountAmount); - const globalDiscount = this.props.globalDiscountPercentage; + const globalDiscount = context.globalDiscountPercentage; return amountAfterLineDiscount.percentage(globalDiscount); } diff --git a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts index 45e0339b..d3daa5be 100644 --- a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts +++ b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts @@ -1,126 +1,40 @@ -import type { DiscountPercentage } from "@erp/core/api"; -import type { CurrencyCode, LanguageCode } from "@repo/rdx-ddd"; -import { Collection, Result } from "@repo/rdx-utils"; +import { Collection } from "@repo/rdx-utils"; -import { ProformaItemMismatch } from "../../errors"; -import { type IProformaTaxTotals, ProformaTaxesCalculator } from "../../services"; -import { ProformaItemsTotalsCalculator } from "../../services/proforma-items-totals-calculator"; +import { + type IProformaTaxTotals, + type ProformaCalculationContext, + ProformaItemsTotalsCalculator, + ProformaTaxesCalculator, +} from "../../services"; import type { IProformaItem, IProformaItemTotals, ProformaItem } from "./proforma-item.entity"; export interface IProformaItemsProps { items?: ProformaItem[]; - - // Estos campos vienen de la cabecera, - // pero se necesitan para cálculos y representaciones de la línea. - globalDiscountPercentage: DiscountPercentage; // % descuento de la cabecera - languageCode: LanguageCode; // Para formateos específicos de idioma - currencyCode: CurrencyCode; // Para cálculos y formateos de moneda } -/*type ProformaItemCreateProps = { - items: IProformaItemCreateProps[]; - - // Estos campos vienen de la cabecera, - // pero se necesitan para cálculos y representaciones de la línea. - globalDiscountPercentage: DiscountPercentage; // % descuento de la cabecera - languageCode: LanguageCode; // Para formateos específicos de idioma - currencyCode: CurrencyCode; // Para cálculos y formateos de moneda -}; - -type InternalProformaProps = Omit & { - items: ProformaItem[]; -};*/ - export interface IProformaItems { // OJO, no extendemos de Collection para no exponer // públicamente métodos para manipular la colección. valued(): IProformaItem[]; // Devuelve solo las líneas valoradas. - totals(): IProformaItemTotals; - taxes(): Collection; - - globalDiscountPercentage: DiscountPercentage; // % descuento de la cabecera - languageCode: LanguageCode; // Para formateos específicos de idioma - currencyCode: CurrencyCode; // Para cálculos y formateos de moneda + totals(context: ProformaCalculationContext): IProformaItemTotals; + taxes(context: ProformaCalculationContext): Collection; } export class ProformaItems extends Collection implements IProformaItems { - public languageCode!: LanguageCode; - public currencyCode!: CurrencyCode; - public globalDiscountPercentage!: DiscountPercentage; - private constructor(props: IProformaItemsProps) { super(props.items ?? []); - this.languageCode = props.languageCode; - this.currencyCode = props.currencyCode; - this.globalDiscountPercentage = props.globalDiscountPercentage; - - if (this.items.length > 0) { - this.ensureSameContext(this.items); - } - 4; } static create(props: IProformaItemsProps): ProformaItems { return new ProformaItems(props); } - public add(item: ProformaItem): boolean { - console.log("adding item", { - item: { - description: item.description.getOrUndefined()?.toString(), - quantity: item.quantity.getOrUndefined()?.toString(), - unitAmount: item.unitAmount.getOrUndefined()?.toObjectString(), - itemDiscountPercentage: item.itemDiscountPercentage.getOrUndefined()?.toObjectString(), - ivaPercentage: item.ivaPercentage.toString(), - recPercentage: item.recPercentage.toString(), - languageCode: item.languageCode.code, - currencyCode: item.currencyCode.code, - globalDiscountPercentage: item.globalDiscountPercentage.toObjectString(), - }, - languageCode: this.languageCode, - currencyCode: this.currencyCode, - globalDiscountPercentage: this.globalDiscountPercentage, - }); - const same = - this.languageCode.equals(item.languageCode) && - this.currencyCode.equals(item.currencyCode) && - this.globalDiscountPercentage.equals(item.globalDiscountPercentage); - - if (!same) return false; - - return super.add(item); - } - public valued(): IProformaItem[] { return this.filter((item) => item.isValued()); } - /** - * @summary Añade un nuevo ítem a la colección. - * @param item - El ítem de factura a añadir. - * @returns `true` si el ítem fue añadido correctamente; `false` si fue rechazado. - * @remarks - * Sólo se aceptan ítems cuyo `LanguageCode` y `CurrencyCode` coincidan con - * los de la colección. Si no coinciden, el método devuelve un resultado fallido sin modificar - * la colección. - */ - public addItem(item: ProformaItem): Result { - // 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. - const same = - this.languageCode.equals(item.languageCode) && - this.currencyCode.equals(item.currencyCode) && - this.globalDiscountPercentage.equals(item.globalDiscountPercentage); - - if (!same) { - return Result.fail(new ProformaItemMismatch(this.size())); - } - super.add(item); - return Result.ok(); - } - // Cálculos /** @@ -128,24 +42,11 @@ export class ProformaItems extends Collection implements IProforma * @remarks * Delega en los ítems individuales (DDD correcto) pero evita múltiples recorridos. */ - public totals(): IProformaItemTotals { - return new ProformaItemsTotalsCalculator(this).calculate(); + public totals(context: ProformaCalculationContext): IProformaItemTotals { + return new ProformaItemsTotalsCalculator(this, context).calculate(); } - public taxes(): Collection { - return new ProformaTaxesCalculator(this).calculate(); - } - - private ensureSameContext(items: IProformaItem[]): void { - for (const item of items) { - const same = - item.languageCode.equals(this.languageCode) && - item.currencyCode.equals(this.currencyCode) && - item.globalDiscountPercentage.equals(this.globalDiscountPercentage); - - if (!same) { - throw new Error("[ProformaItems] All items must share the same context."); - } - } + public taxes(context: ProformaCalculationContext): Collection { + return new ProformaTaxesCalculator(this, context).calculate(); } } diff --git a/modules/customer-invoices/src/api/domain/proformas/services/index.ts b/modules/customer-invoices/src/api/domain/proformas/services/index.ts index f76afc95..bf7459f9 100644 --- a/modules/customer-invoices/src/api/domain/proformas/services/index.ts +++ b/modules/customer-invoices/src/api/domain/proformas/services/index.ts @@ -1 +1,4 @@ +export * from "./proforma-compare-tax-totals"; +export * from "./proforma-compute-tax-groups"; +export * from "./proforma-items-totals-calculator"; export * from "./proforma-taxes-calculator"; diff --git a/modules/customer-invoices/src/api/domain/proformas/services/proforma-compute-tax-groups.ts b/modules/customer-invoices/src/api/domain/proformas/services/proforma-compute-tax-groups.ts index ab4ce609..5e9f383b 100644 --- a/modules/customer-invoices/src/api/domain/proformas/services/proforma-compute-tax-groups.ts +++ b/modules/customer-invoices/src/api/domain/proformas/services/proforma-compute-tax-groups.ts @@ -4,6 +4,8 @@ import { Maybe } from "@repo/rdx-utils"; import { ItemAmount } from "../../common"; import type { IProformaItems } from "../entities"; +import type { ProformaCalculationContext } from "./proforma-items-totals-calculator"; + type TaxGroupState = { taxableAmount: ItemAmount; @@ -30,9 +32,12 @@ type TaxGroupState = { * - REC y RETENTION pueden ser None. * - No se recalculan porcentajes (se suma lo ya calculado por línea). */ -export function proformaComputeTaxGroups(items: IProformaItems): Map { +export function proformaComputeTaxGroups( + items: IProformaItems, + context: ProformaCalculationContext +): Map { const map = new Map(); - const currency = items.currencyCode; + const currency = context.currencyCode; for (const item of items.valued()) { const iva = item.taxes.iva; @@ -65,7 +70,7 @@ export function proformaComputeTaxGroups(items: IProformaItems): Map { - const groups = proformaComputeTaxGroups(this.items); // <- devuelve en escala 4 + const groups = proformaComputeTaxGroups(this.items, this.context); // <- devuelve en escala 4 // Vamos acumulando los importes, redondeando previamente a 2 decimales const rows = Array.from(groups.values()).map((g) => { @@ -65,7 +69,7 @@ export class ProformaTaxesCalculator { private toInvoiceAmount(amount: ItemAmount): InvoiceAmount { return InvoiceAmount.create({ value: amount.convertScale(InvoiceAmount.DEFAULT_SCALE).value, - currency_code: this.items.currencyCode.code, + currency_code: this.context.currencyCode.code, }).data; } } diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts index b48d9c63..1cfbf7f9 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts @@ -241,9 +241,6 @@ export class SequelizeProformaDomainMapper extends SequelizeDomainMapper< // 6) Construcción del agregado (Dominio) const items = ProformaItems.create({ - languageCode: attributes.languageCode!, - currencyCode: attributes.currencyCode!, - globalDiscountPercentage: attributes.globalDiscountPercentage!, items: itemCollectionResults.data.getAll(), }); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts index 474c6776..f39feac3 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts @@ -128,15 +128,10 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< return { itemId, - - languageCode: parent.languageCode, - currencyCode: parent.currencyCode, description, quantity, unitAmount, itemDiscountPercentage, - globalDiscountPercentage: parent.globalDiscountPercentage, - iva, rec, retention, @@ -179,11 +174,7 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< unitAmount: attributes.unitAmount!, itemDiscountPercentage: attributes.itemDiscountPercentage!, - globalDiscountPercentage: attributes.globalDiscountPercentage!, taxes: taxesResult.data, - - languageCode: attributes.languageCode!, - currencyCode: attributes.currencyCode!, }, itemId ); @@ -201,7 +192,11 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< errors: ValidationErrorDetail[]; }; - const allAmounts = source.totals(); + const allAmounts = source.totals({ + currencyCode: parent.currencyCode, + globalDiscountPercentage: parent.globalDiscountPercentage, + languageCode: parent.languageCode, + }); return Result.ok({ item_id: source.id.toPrimitive(), @@ -236,8 +231,9 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< item_discount_amount_scale: allAmounts.itemDiscountAmount.scale, // - global_discount_percentage_value: source.globalDiscountPercentage.value, - global_discount_percentage_scale: source.globalDiscountPercentage.scale, + global_discount_percentage_value: parent.globalDiscountPercentage.toPrimitive().value, + global_discount_percentage_scale: + parent.globalDiscountPercentage.toPrimitive().scale ?? DiscountPercentage.DEFAULT_SCALE, global_discount_amount_value: allAmounts.globalDiscountAmount.value, global_discount_amount_scale: allAmounts.globalDiscountAmount.scale, diff --git a/modules/customer-invoices/src/web/proformas/update/adapters/map-proforma-to-proforma-update-form.adapter.ts b/modules/customer-invoices/src/web/proformas/update/adapters/map-proforma-to-proforma-update-form.adapter.ts index 928b6a40..a99502da 100644 --- a/modules/customer-invoices/src/web/proformas/update/adapters/map-proforma-to-proforma-update-form.adapter.ts +++ b/modules/customer-invoices/src/web/proformas/update/adapters/map-proforma-to-proforma-update-form.adapter.ts @@ -28,6 +28,8 @@ export const mapProformaToProformaUpdateForm = (proforma: Proforma): ProformaUpd const defaultRetentionPercentage = defaultTaxSummary?.retentionPercentage ?? firstTaxableItem?.retentionPercentage ?? null; + console.log({ defaultTaxPercentage, defaultRecPercentage, defaultRetentionPercentage, taxMode }); + return { series: proforma.series ?? proformaDefaults.series,