import { ISequelizeMapper, SequelizeMapper } from "@/contexts/common/infrastructure"; import { Description, Quantity, UniqueID, UnitPrice } from "@shared/contexts"; import { Invoice } from "../../domain"; import { IInvoiceSimpleItemProps, InvoiceItem, InvoiceSimpleItem } from "../../domain/entities"; import { IInvoicingContext } from "../InvoicingContext"; import { InvoiceItem_Model, InvoiceModel, TCreationInvoiceItem_Model } from "../sequelize"; export interface IInvoiceItemMapper extends ISequelizeMapper {} export const createInvoiceItemMapper = (context: IInvoicingContext): IInvoiceItemMapper => new InvoiceItemMapper({ context }); class InvoiceItemMapper extends SequelizeMapper implements IInvoiceItemMapper { protected toDomainMappingImpl( source: InvoiceItem_Model, params: { sourceParent: InvoiceModel } ): InvoiceItem { const { sourceParent } = params; const id = this.mapsValue(source, "item_id", UniqueID.create); const props: IInvoiceSimpleItemProps = { description: this.mapsValue(source, "description", Description.create), quantity: this.mapsValue(source, "quantity", Quantity.create), unitPrice: this.mapsValue(source, "unit_price", (unit_price) => UnitPrice.create({ amount: unit_price, currencyCode: sourceParent.invoice_currency, precision: 4, }) ), }; const invoiceItemOrError = InvoiceSimpleItem.create(props, id); if (invoiceItemOrError.isFailure) { throw invoiceItemOrError.error; } return invoiceItemOrError.object; } protected toPersistenceMappingImpl( source: InvoiceItem, params: { index: number; sourceParent: Invoice } ): TCreationInvoiceItem_Model { const { index, sourceParent } = params; 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: source.quantity.toPrimitive(), unit_price: source.unitPrice.toPrimitive(), subtotal: source.calculateSubtotal().toPrimitive(), total: source.calculateTotal().toPrimitive(), }; return lineData; } }