import { ISequelizeMapper, MapperParamsType, SequelizeMapper, ValidationErrorCollection, ValidationErrorDetail, extractOrPushError, } from "@erp/core/api"; import { CurrencyCode, LanguageCode, Percentage, TextValue, UniqueID, UtcDate, maybeFromNullableVO, toNullable, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { CustomerInvoice, CustomerInvoiceItems, CustomerInvoiceNumber, CustomerInvoiceProps, CustomerInvoiceSerie, CustomerInvoiceStatus, } from "../../domain"; import { CustomerInvoiceCreationAttributes, CustomerInvoiceModel } from "../sequelize"; import { CustomerInvoiceItemMapper } from "./customer-invoice-item.mapper"; export interface ICustomerInvoiceMapper extends ISequelizeMapper< CustomerInvoiceModel, CustomerInvoiceCreationAttributes, CustomerInvoice > {} export class CustomerInvoiceMapper extends SequelizeMapper implements ICustomerInvoiceMapper { private _itemsMapper: CustomerInvoiceItemMapper; constructor() { super(); this._itemsMapper = new CustomerInvoiceItemMapper(); // Instanciar el mapper de items } public mapToDomain( source: CustomerInvoiceModel, params?: MapperParamsType ): Result { try { const errors: ValidationErrorDetail[] = []; const invoiceId = extractOrPushError(UniqueID.create(source.id), "id", errors); const companyId = extractOrPushError( UniqueID.create(source.company_id), "company_id", errors ); const status = extractOrPushError( CustomerInvoiceStatus.create(source.status), "status", errors ); const series = extractOrPushError( maybeFromNullableVO(source.series, (value) => CustomerInvoiceSerie.create(value)), "serie", errors ); const invoiceNumber = extractOrPushError( CustomerInvoiceNumber.create(source.invoice_number), "invoice_number", errors ); const invoiceDate = extractOrPushError( UtcDate.createFromISO(source.invoice_date), "invoice_date", errors ); const operationDate = extractOrPushError( maybeFromNullableVO(source.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); const notes = extractOrPushError( maybeFromNullableVO(source.notes, (value) => TextValue.create(value)), "notes", errors ); const languageCode = extractOrPushError( LanguageCode.create(source.language_code), "language_code", errors ); const currencyCode = extractOrPushError( CurrencyCode.create(source.currency_code), "currency_code", errors ); const discountPercentage = extractOrPushError( Percentage.create({ value: source.discount_percentage_value, scale: source.discount_percentage_scale, }), "discount_percentage", errors ); if (errors.length > 0) { return Result.fail( new ValidationErrorCollection("Customer invoice props mapping failed", errors) ); } // Mapear los items de la factura const items = this._itemsMapper.mapArrayToDomain(source.items, { sourceParent: source, errors, ...params, }); if (errors.length > 0) { return Result.fail( new ValidationErrorCollection("Customer invoice item props mapping failed", errors) ); } const invoiceProps: CustomerInvoiceProps = { companyId: companyId!, status: status!, series: series!, invoiceNumber: invoiceNumber!, invoiceDate: invoiceDate!, operationDate: operationDate!, notes: notes!, languageCode: languageCode!, currencyCode: currencyCode!, discountPercentage: discountPercentage!, items: CustomerInvoiceItems.create({ languageCode: languageCode!, currencyCode: currencyCode!, }), }; return CustomerInvoice.create(invoiceProps, invoiceId); } catch (err: unknown) { return Result.fail(err as Error); } } public mapToPersistence( source: CustomerInvoice, params?: MapperParamsType ): CustomerInvoiceCreationAttributes { //const subtotal = source.calculateSubtotal(); //const total = source.calculateTotal(); const items = this._itemsMapper.mapCollectionToPersistence(source.items, params); return { id: source.id.toPrimitive(), company_id: source.companyId.toPrimitive(), status: source.status.toPrimitive(), series: toNullable(source.series, (series) => series.toPrimitive()), invoice_number: source.invoiceNumber.toPrimitive(), invoice_date: source.invoiceDate.toPrimitive(), operation_date: toNullable(source.operationDate, (operationDate) => operationDate.toPrimitive() ), notes: toNullable(source.notes, (notes) => notes.toPrimitive()), language_code: source.languageCode.code, currency_code: source.currencyCode.code, subtotal_amount_value: 0, //subtotal.amount, subtotal_amount_scale: 2, //subtotal.scale, /*discount_percentage_value: source.discountPercentage.value, discount_percentage_scale: source.discountPercentage.scale, discount_amount_value: source.discountAmount.value, discount_amount_scale: source.discountAmount.scale,*/ total_amount_value: 0, //total.amount, total_amount_scale: 2, //total.scale, items, }; } }