import { Invoice, InvoiceItem, InvoiceItemDescription } from "@/contexts/invoices/domain"; import { type ISequelizeMapper, type MapperParamsType, MoneyValue, Percentage, Quantity, Result, SequelizeMapper, UniqueID, } from "@/core"; import { InvoiceModel } from "../sequelize"; import { InferCreationAttributes } from "sequelize"; import { InvoiceItemCreationAttributes, InvoiceItemModel } 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 }; const idOrError = UniqueID.create(source.item_id); const descriptionOrError = InvoiceItemDescription.create(source.description); const quantityOrError = Quantity.create({ amount: source.quantity_amount, scale: source.quantity_scale, }); const unitPriceOrError = MoneyValue.create({ amount: source.unit_price_amount, scale: source.unit_price_scale, currency_code: sourceParent.invoice_currency, }); const discountOrError = Percentage.create({ amount: source.discount_amount, scale: source.discount_scale, }); const result = Result.combine([ idOrError, descriptionOrError, quantityOrError, unitPriceOrError, discountOrError, ]); if (result.isFailure) { return Result.fail(result.error); } return InvoiceItem.create( { description: descriptionOrError.data, quantity: quantityOrError.data, unitPrice: unitPriceOrError.data, discount: discountOrError.data, }, idOrError.data //sourceParent ); } 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; } }