import { ISequelizeMapper, MapperParamsType, SequelizeMapper, ValidationErrorCollection, ValidationErrorDetail, extractOrPushError, } from "@erp/core/api"; import { UniqueID, maybeFromNullableVO, toNullable } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { InferCreationAttributes } from "sequelize"; import { CustomerInvoice, CustomerInvoiceItem, CustomerInvoiceItemDescription, CustomerInvoiceProps, ItemAmount, ItemDiscount, ItemQuantity, } from "../../domain"; import { CustomerInvoiceItemCreationAttributes, CustomerInvoiceItemModel } from "../sequelize"; export interface ICustomerInvoiceItemMapper extends ISequelizeMapper< CustomerInvoiceItemModel, CustomerInvoiceItemCreationAttributes, CustomerInvoiceItem > {} export class CustomerInvoiceItemMapper extends SequelizeMapper< CustomerInvoiceItemModel, CustomerInvoiceItemCreationAttributes, CustomerInvoiceItem > implements ICustomerInvoiceItemMapper { private mapAttributesToDomain(source: CustomerInvoiceItemModel, params?: MapperParamsType) { const { errors, index, attributes } = params as { index: number; errors: ValidationErrorDetail[]; attributes: Partial; }; const itemId = extractOrPushError( UniqueID.create(source.item_id), `items[${index}].item_id`, errors ); const description = extractOrPushError( maybeFromNullableVO(source.description, (value) => CustomerInvoiceItemDescription.create(value) ), `items[${index}].description`, errors ); const quantity = extractOrPushError( maybeFromNullableVO(source.quantity_value, (value) => ItemQuantity.create({ value })), `items[${index}].discount_percentage`, errors ); const unitAmount = extractOrPushError( maybeFromNullableVO(source.unit_amount_value, (value) => ItemAmount.create({ value, currency_code: attributes.currencyCode!.code }) ), `items[${index}].unit_amount`, errors ); return { itemId, languageCode: attributes.languageCode, currencyCode: attributes.currencyCode, description, quantity, unitAmount, }; } public mapToDomain( source: CustomerInvoiceItemModel, params?: MapperParamsType ): Result { const { errors, index, requireIncludes } = params as { index: number; requireIncludes: boolean; errors: ValidationErrorDetail[]; attributes: Partial; }; if (requireIncludes) { if (!source.taxes) { errors.push({ path: `items[${index}].taxes`, message: "Taxes not included in query (requireIncludes=true)", }); } } const attributes = this.mapAttributesToDomain(source, params); const discountPercentage = extractOrPushError( maybeFromNullableVO(source.discount_percentage_value, (value) => ItemDiscount.create({ value }) ), `items[${index}].discount_percentage`, errors ); // Creación del objeto de dominio const createResult = CustomerInvoiceItem.create( { languageCode: attributes.languageCode!, currencyCode: attributes.currencyCode!, description: attributes.description!, quantity: attributes.quantity!, unitAmount: attributes.unitAmount!, discountPercentage: discountPercentage!, }, attributes.itemId ); if (createResult.isFailure) { return Result.fail( new ValidationErrorCollection("Invoice item entity creation failed", [ { path: `items[${index}]`, message: createResult.error.message }, ]) ); } return createResult; } public mapToPersistence( source: CustomerInvoiceItem, params?: MapperParamsType ): InferCreationAttributes { 1; const { index, sourceParent } = params as { index: number; sourceParent: CustomerInvoice; }; return { item_id: source.id.toPrimitive(), invoice_id: sourceParent.id.toPrimitive(), position: index, description: toNullable(source.description, (description) => description.toPrimitive()), quantity_value: toNullable(source.quantity, (value) => value.toPrimitive().value), quantity_scale: source.quantity.match( (value) => value.toPrimitive().scale, () => ItemQuantity.DEFAULT_SCALE ), unit_amount_value: toNullable(source.unitAmount, (value) => value.toPrimitive().value), unit_amount_scale: source.unitAmount.match( (value) => value.toPrimitive().scale, () => ItemAmount.DEFAULT_SCALE ), subtotal_amount_value: source.subtotalAmount.toPrimitive().value, subtotal_amount_scale: source.subtotalAmount.toPrimitive().scale, discount_percentage_value: toNullable( source.discountPercentage, (value) => value.toPrimitive().value ), discount_percentage_scale: source.discountPercentage.match( (value) => value.toPrimitive().scale, () => ItemAmount.DEFAULT_SCALE ), discount_amount_value: toNullable( source.discountAmount, (value) => value.toPrimitive().value ), discount_amount_scale: source.discountAmount.match( (value) => value.toPrimitive().scale, () => ItemDiscount.DEFAULT_SCALE ), taxable_amount_value: source.taxableAmount.toPrimitive().value, taxable_amount_scale: source.taxableAmount.toPrimitive().value, taxes_amount_value: source.taxesAmount.toPrimitive().value, taxes_amount_scale: source.taxesAmount.toPrimitive().value, total_amount_value: source.totalAmount.toPrimitive().value, total_amount_scale: source.totalAmount.toPrimitive().scale, }; } }