import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@erp/core"; import { UniqueID } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { InferCreationAttributes } from "sequelize"; import { Invoice, InvoiceItem, InvoiceItemDescription, InvoiceItemDiscount, InvoiceItemQuantity, InvoiceItemUnitPrice, } from "../../domain"; import { InvoiceItemCreationAttributes, InvoiceItemModel, InvoiceModel } from "../sequelize"; export interface IInvoiceItemMapper extends ISequelizeMapper {} export class InvoiceItemMapper extends SequelizeMapper implements IInvoiceItemMapper { public mapToDomain( source: InvoiceItemModel, params?: MapperParamsType ): Result { const { sourceParent } = params as { sourceParent: InvoiceModel }; // Validación y creación de ID único const idOrError = UniqueID.create(source.item_id); if (idOrError.isFailure) { return Result.fail(idOrError.error); } // Validación y creación de descripción const descriptionOrError = InvoiceItemDescription.create(source.description || ""); if (descriptionOrError.isFailure) { return Result.fail(descriptionOrError.error); } // Validación y creación de cantidad const quantityOrError = InvoiceItemQuantity.create({ amount: source.quantity_amount, scale: source.quantity_scale, }); if (quantityOrError.isFailure) { return Result.fail(quantityOrError.error); } // Validación y creación de precio unitario const unitPriceOrError = InvoiceItemUnitPrice.create({ amount: source.unit_price_amount, scale: source.unit_price_scale, currency_code: sourceParent.invoice_currency, }); if (unitPriceOrError.isFailure) { return Result.fail(unitPriceOrError.error); } // Validación y creación de descuento const discountOrError = InvoiceItemDiscount.create({ amount: source.discount_amount || 0, scale: source.discount_scale || 0, }); if (discountOrError.isFailure) { return Result.fail(discountOrError.error); } // Combinación de resultados const result = Result.combine([ idOrError, descriptionOrError, quantityOrError, unitPriceOrError, discountOrError, ]); if (result.isFailure) { return Result.fail(result.error); } // Creación del objeto de dominio return InvoiceItem.create( { description: descriptionOrError.data, quantity: quantityOrError.data, unitPrice: unitPriceOrError.data, discount: discountOrError.data, }, idOrError.data ); } public mapToPersistence( source: InvoiceItem, params?: MapperParamsType ): InferCreationAttributes { const { index, sourceParent } = params as { index: number; sourceParent: Invoice; }; const lineData = { parent_id: undefined, invoice_id: sourceParent.id.toPrimitive(), item_type: "simple", position: index, item_id: source.id.toPrimitive(), description: source.description.toPrimitive(), quantity_amount: source.quantity.toPrimitive().amount, quantity_scale: source.quantity.toPrimitive().scale, unit_price_amount: source.unitPrice.toPrimitive().amount, unit_price_scale: source.unitPrice.toPrimitive().scale, subtotal_amount: source.subtotalPrice.toPrimitive().amount, subtotal_scale: source.subtotalPrice.toPrimitive().scale, discount_amount: source.discount.toPrimitive().amount, discount_scale: source.discount.toPrimitive().scale, total_amount: source.totalPrice.toPrimitive().amount, total_scale: source.totalPrice.toPrimitive().scale, }; return lineData; } }