Uecko_ERP/modules/customers/src/api/infrastructure/mappers/customer-item.mapper.ts

129 lines
3.9 KiB
TypeScript

import { ISequelizeMapper, MapperParamsType, SequelizeMapper } from "@erp/core/api";
import { UniqueID } from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";
import { InferCreationAttributes } from "sequelize";
import {
Customer,
CustomerItem,
CustomerItemDescription,
CustomerItemDiscount,
CustomerItemQuantity,
CustomerItemUnitPrice,
} from "../../domain";
import { CustomerItemCreationAttributes, CustomerItemModel, CustomerModel } from "../sequelize";
export interface ICustomerItemMapper
extends ISequelizeMapper<CustomerItemModel, CustomerItemCreationAttributes, CustomerItem> {}
export class CustomerItemMapper
extends SequelizeMapper<CustomerItemModel, CustomerItemCreationAttributes, CustomerItem>
implements ICustomerItemMapper
{
public mapToDomain(
source: CustomerItemModel,
params?: MapperParamsType
): Result<CustomerItem, Error> {
const { sourceParent } = params as { sourceParent: CustomerModel };
// 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 = CustomerItemDescription.create(source.description || "");
if (descriptionOrError.isFailure) {
return Result.fail(descriptionOrError.error);
}
// Validación y creación de cantidad
const quantityOrError = CustomerItemQuantity.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 = CustomerItemUnitPrice.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 = CustomerItemDiscount.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 CustomerItem.create(
{
description: descriptionOrError.data,
quantity: quantityOrError.data,
unitPrice: unitPriceOrError.data,
discount: discountOrError.data,
},
idOrError.data
);
}
public mapToPersistence(
source: CustomerItem,
params?: MapperParamsType
): InferCreationAttributes<CustomerItemModel, {}> {
const { index, sourceParent } = params as {
index: number;
sourceParent: Customer;
};
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;
}
}