Facturas de cliente
This commit is contained in:
parent
8c867eb7f3
commit
df1aa258d9
@ -7,39 +7,41 @@ type GetCustomerInvoiceItemsByInvoiceIdResponseDTO = GetCustomerInvoiceByIdRespo
|
|||||||
export class GetCustomerInvoiceItemsAssembler {
|
export class GetCustomerInvoiceItemsAssembler {
|
||||||
toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO {
|
toDTO(invoice: CustomerInvoice): GetCustomerInvoiceItemsByInvoiceIdResponseDTO {
|
||||||
const { items } = invoice;
|
const { items } = invoice;
|
||||||
return items.map((item, index) => ({
|
|
||||||
id: item.id.toString(),
|
|
||||||
position: String(index),
|
|
||||||
description: toEmptyString(item.description, (value) => value.toPrimitive()),
|
|
||||||
|
|
||||||
quantity: item.quantity.match(
|
return items.map((item, index) => {
|
||||||
(quantity) => {
|
const amounts = item.getAllAmounts();
|
||||||
const { value, scale } = quantity.toPrimitive();
|
|
||||||
return { value: value.toString(), scale: scale.toString() };
|
|
||||||
},
|
|
||||||
() => ({ value: "", scale: "" })
|
|
||||||
),
|
|
||||||
|
|
||||||
unit_amount: item.unitAmount.match(
|
return {
|
||||||
(unitAmount) => {
|
id: item.id.toString(),
|
||||||
const { value, scale } = unitAmount.toPrimitive();
|
position: String(index),
|
||||||
return { value: value.toString(), scale: scale.toString() };
|
description: toEmptyString(item.description, (value) => value.toPrimitive()),
|
||||||
},
|
|
||||||
() => ({ value: "", scale: "" })
|
|
||||||
),
|
|
||||||
|
|
||||||
discount_percentage: item.discountPercentage.match(
|
quantity: item.quantity.match(
|
||||||
(discountPercentage) => {
|
(quantity) => {
|
||||||
const { value, scale } = discountPercentage.toPrimitive();
|
const { value, scale } = quantity.toPrimitive();
|
||||||
return { value: value.toString(), scale: scale.toString() };
|
return { value: value.toString(), scale: scale.toString() };
|
||||||
},
|
},
|
||||||
() => ({ value: "", scale: "" })
|
() => ({ value: "", scale: "" })
|
||||||
),
|
),
|
||||||
|
|
||||||
total_amount: {
|
unit_amount: item.unitAmount.match(
|
||||||
value: item.totalAmount.toPrimitive().value.toString(),
|
(unitAmount) => {
|
||||||
scale: item.totalAmount.toPrimitive().scale.toString(),
|
const { value, scale } = unitAmount.toPrimitive();
|
||||||
},
|
return { value: value.toString(), scale: scale.toString() };
|
||||||
}));
|
},
|
||||||
|
() => ({ value: "", scale: "" })
|
||||||
|
),
|
||||||
|
|
||||||
|
discount_percentage: item.discountPercentage.match(
|
||||||
|
(discountPercentage) => {
|
||||||
|
const { value, scale } = discountPercentage.toPrimitive();
|
||||||
|
return { value: value.toString(), scale: scale.toString() };
|
||||||
|
},
|
||||||
|
() => ({ value: "", scale: "" })
|
||||||
|
),
|
||||||
|
|
||||||
|
total_amount: amounts.totalAmount.toPrimitive(),
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,22 +14,22 @@ export class GetCustomerInvoiceAssembler {
|
|||||||
const items = this._itemsAssembler.toDTO(invoice);
|
const items = this._itemsAssembler.toDTO(invoice);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: invoice.id.toPrimitive(),
|
id: invoice.id.toString(),
|
||||||
company_id: invoice.companyId.toPrimitive(),
|
company_id: invoice.companyId.toString(),
|
||||||
|
|
||||||
invoice_number: invoice.invoiceNumber.toString(),
|
invoice_number: invoice.invoiceNumber.toString(),
|
||||||
status: invoice.status.toPrimitive(),
|
status: invoice.status.toPrimitive(),
|
||||||
series: invoice.series.toString(),
|
series: toEmptyString(invoice.series, (value) => value.toString()),
|
||||||
|
|
||||||
invoice_date: invoice.invoiceDate.toDateString(),
|
invoice_date: invoice.invoiceDate.toDateString(),
|
||||||
operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()),
|
operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()),
|
||||||
|
|
||||||
notes: toEmptyString(invoice.notes, (value) => value.toPrimitive()),
|
notes: toEmptyString(invoice.notes, (value) => value.toString()),
|
||||||
|
|
||||||
language_code: invoice.languageCode.toPrimitive(),
|
language_code: invoice.languageCode.toString(),
|
||||||
currency_code: invoice.currencyCode.toPrimitive(),
|
currency_code: invoice.currencyCode.toString(),
|
||||||
|
|
||||||
subtotal_amount: {
|
/*subtotal_amount: {
|
||||||
value: invoice.subtotalAmount.value.toString(),
|
value: invoice.subtotalAmount.value.toString(),
|
||||||
scale: invoice.subtotalAmount.scale.toString(),
|
scale: invoice.subtotalAmount.scale.toString(),
|
||||||
},
|
},
|
||||||
@ -57,14 +57,13 @@ export class GetCustomerInvoiceAssembler {
|
|||||||
total_amount: {
|
total_amount: {
|
||||||
value: invoice.totalAmount.value.toString(),
|
value: invoice.totalAmount.value.toString(),
|
||||||
scale: invoice.totalAmount.scale.toString(),
|
scale: invoice.totalAmount.scale.toString(),
|
||||||
},
|
},*/
|
||||||
|
|
||||||
items,
|
items,
|
||||||
|
|
||||||
metadata: {
|
metadata: {
|
||||||
entity: "customer-invoices",
|
entity: "customer-invoices",
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,13 @@ import {
|
|||||||
UtcDate,
|
UtcDate,
|
||||||
} from "@repo/rdx-ddd";
|
} from "@repo/rdx-ddd";
|
||||||
import { Maybe, Result } from "@repo/rdx-utils";
|
import { Maybe, Result } from "@repo/rdx-utils";
|
||||||
import { CustomerInvoiceItems, InvoiceRecipient } from "../entities";
|
import { CustomerInvoiceItems } from "../entities";
|
||||||
import { InvoiceTaxes } from "../entities/invoice-taxes";
|
import { InvoiceTaxes } from "../entities/invoice-taxes";
|
||||||
import {
|
import {
|
||||||
CustomerInvoiceNumber,
|
CustomerInvoiceNumber,
|
||||||
CustomerInvoiceSerie,
|
CustomerInvoiceSerie,
|
||||||
CustomerInvoiceStatus,
|
CustomerInvoiceStatus,
|
||||||
|
InvoiceRecipient,
|
||||||
} from "../value-objects";
|
} from "../value-objects";
|
||||||
|
|
||||||
export interface CustomerInvoiceProps {
|
export interface CustomerInvoiceProps {
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import { InvoiceAmount } from "../../value-objects/invoice-amount";
|
|||||||
|
|
||||||
export interface InvoiceTaxProps {
|
export interface InvoiceTaxProps {
|
||||||
tax: Tax;
|
tax: Tax;
|
||||||
taxableAmount: InvoiceAmount;
|
|
||||||
taxesAmount: InvoiceAmount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvoiceTax extends DomainEntity<InvoiceTaxProps> {
|
export class InvoiceTax extends DomainEntity<InvoiceTaxProps> {
|
||||||
@ -24,14 +22,6 @@ export class InvoiceTax extends DomainEntity<InvoiceTaxProps> {
|
|||||||
return this.props.tax;
|
return this.props.tax;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get taxableAmount(): InvoiceAmount {
|
|
||||||
return this.props.taxableAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get taxesAmount(): InvoiceAmount {
|
|
||||||
return this.props.taxesAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
getProps(): InvoiceTaxProps {
|
getProps(): InvoiceTaxProps {
|
||||||
return this.props;
|
return this.props;
|
||||||
}
|
}
|
||||||
@ -39,4 +29,8 @@ export class InvoiceTax extends DomainEntity<InvoiceTaxProps> {
|
|||||||
toPrimitive() {
|
toPrimitive() {
|
||||||
return this.getProps();
|
return this.getProps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getTaxAmount(taxableAmount: InvoiceAmount): InvoiceAmount {
|
||||||
|
return taxableAmount.percentage(this.tax.percentage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,13 +9,13 @@ export interface ItemTaxProps {
|
|||||||
|
|
||||||
export class ItemTax extends DomainEntity<ItemTaxProps> {
|
export class ItemTax extends DomainEntity<ItemTaxProps> {
|
||||||
static create(props: ItemTaxProps, id?: UniqueID): Result<ItemTax, Error> {
|
static create(props: ItemTaxProps, id?: UniqueID): Result<ItemTax, Error> {
|
||||||
const invoiceTax = new ItemTax(props, id);
|
const itemTax = new ItemTax(props, id);
|
||||||
|
|
||||||
// Reglas de negocio / validaciones
|
// Reglas de negocio / validaciones
|
||||||
// ...
|
// ...
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
return Result.ok(invoiceTax);
|
return Result.ok(itemTax);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get tax(): Tax {
|
public get tax(): Tax {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ export * from "./customer-invoice-number";
|
|||||||
export * from "./customer-invoice-serie";
|
export * from "./customer-invoice-serie";
|
||||||
export * from "./customer-invoice-status";
|
export * from "./customer-invoice-status";
|
||||||
export * from "./invoice-amount";
|
export * from "./invoice-amount";
|
||||||
|
export * from "./invoice-recipient";
|
||||||
export * from "./item-amount";
|
export * from "./item-amount";
|
||||||
export * from "./item-discount";
|
export * from "./item-discount";
|
||||||
export * from "./item-quantity";
|
export * from "./item-quantity";
|
||||||
|
|||||||
@ -6,19 +6,20 @@ import {
|
|||||||
ValidationErrorDetail,
|
ValidationErrorDetail,
|
||||||
extractOrPushError,
|
extractOrPushError,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { UniqueID, maybeFromNullableVO, toNullable } from "@repo/rdx-ddd";
|
import { UniqueID, maybeFromNullableVO } from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import { InferCreationAttributes } from "sequelize";
|
||||||
import {
|
import {
|
||||||
CustomerInvoice,
|
|
||||||
CustomerInvoiceItem,
|
CustomerInvoiceItem,
|
||||||
CustomerInvoiceItemDescription,
|
CustomerInvoiceItemDescription,
|
||||||
CustomerInvoiceProps,
|
CustomerInvoiceProps,
|
||||||
ItemAmount,
|
ItemAmount,
|
||||||
ItemDiscount,
|
ItemDiscount,
|
||||||
ItemQuantity,
|
ItemQuantity,
|
||||||
|
ItemTaxes,
|
||||||
} from "../../domain";
|
} from "../../domain";
|
||||||
import { CustomerInvoiceItemCreationAttributes, CustomerInvoiceItemModel } from "../sequelize";
|
import { CustomerInvoiceItemCreationAttributes, CustomerInvoiceItemModel } from "../sequelize";
|
||||||
|
import { ItemTaxesMapper } from "./item-taxes.mapper";
|
||||||
|
|
||||||
export interface ICustomerInvoiceItemMapper
|
export interface ICustomerInvoiceItemMapper
|
||||||
extends ISequelizeMapper<
|
extends ISequelizeMapper<
|
||||||
@ -35,6 +36,13 @@ export class CustomerInvoiceItemMapper
|
|||||||
>
|
>
|
||||||
implements ICustomerInvoiceItemMapper
|
implements ICustomerInvoiceItemMapper
|
||||||
{
|
{
|
||||||
|
private _taxesMapper: ItemTaxesMapper;
|
||||||
|
|
||||||
|
constructor(params: MapperParamsType) {
|
||||||
|
super();
|
||||||
|
this._taxesMapper = new ItemTaxesMapper(params);
|
||||||
|
}
|
||||||
|
|
||||||
private mapAttributesToDomain(source: CustomerInvoiceItemModel, params?: MapperParamsType) {
|
private mapAttributesToDomain(source: CustomerInvoiceItemModel, params?: MapperParamsType) {
|
||||||
const { errors, index, attributes } = params as {
|
const { errors, index, attributes } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
@ -92,6 +100,10 @@ export class CustomerInvoiceItemMapper
|
|||||||
attributes: Partial<CustomerInvoiceProps>;
|
attributes: Partial<CustomerInvoiceProps>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 1) Valores escalares (atributos generales)
|
||||||
|
const attributes = this.mapAttributesToDomain(source, params);
|
||||||
|
|
||||||
|
// 2) Comprobar relaciones
|
||||||
if (requireIncludes) {
|
if (requireIncludes) {
|
||||||
if (!source.taxes) {
|
if (!source.taxes) {
|
||||||
errors.push({
|
errors.push({
|
||||||
@ -101,8 +113,7 @@ export class CustomerInvoiceItemMapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const attributes = this.mapAttributesToDomain(source, params);
|
// 3) Importes
|
||||||
|
|
||||||
const discountPercentage = extractOrPushError(
|
const discountPercentage = extractOrPushError(
|
||||||
maybeFromNullableVO(source.discount_percentage_value, (value) =>
|
maybeFromNullableVO(source.discount_percentage_value, (value) =>
|
||||||
ItemDiscount.create({ value })
|
ItemDiscount.create({ value })
|
||||||
@ -111,7 +122,25 @@ export class CustomerInvoiceItemMapper
|
|||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
// Creación del objeto de dominio
|
// 4) Taxes (colección a nivel de item/línea)
|
||||||
|
const taxesResults = this._taxesMapper.mapArrayToDomain(source.taxes, {
|
||||||
|
attributes,
|
||||||
|
...params,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (taxesResults.isFailure) {
|
||||||
|
errors.push({
|
||||||
|
path: `taxes[${index}].discount_percentage`,
|
||||||
|
message: taxesResults.error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5) Construcción del elemento de dominio
|
||||||
|
|
||||||
|
const taxes = ItemTaxes.create({
|
||||||
|
items: taxesResults.data.getAll(),
|
||||||
|
});
|
||||||
|
|
||||||
const createResult = CustomerInvoiceItem.create(
|
const createResult = CustomerInvoiceItem.create(
|
||||||
{
|
{
|
||||||
languageCode: attributes.languageCode!,
|
languageCode: attributes.languageCode!,
|
||||||
@ -120,6 +149,7 @@ export class CustomerInvoiceItemMapper
|
|||||||
quantity: attributes.quantity!,
|
quantity: attributes.quantity!,
|
||||||
unitAmount: attributes.unitAmount!,
|
unitAmount: attributes.unitAmount!,
|
||||||
discountPercentage: discountPercentage!,
|
discountPercentage: discountPercentage!,
|
||||||
|
taxes,
|
||||||
},
|
},
|
||||||
attributes.itemId
|
attributes.itemId
|
||||||
);
|
);
|
||||||
@ -139,12 +169,15 @@ export class CustomerInvoiceItemMapper
|
|||||||
source: CustomerInvoiceItem,
|
source: CustomerInvoiceItem,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): InferCreationAttributes<CustomerInvoiceItemModel, {}> {
|
): InferCreationAttributes<CustomerInvoiceItemModel, {}> {
|
||||||
1;
|
throw new Error("not implemented");
|
||||||
const { index, sourceParent } = params as {
|
/*
|
||||||
|
|
||||||
|
const { index, sourceParent } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
sourceParent: CustomerInvoice;
|
sourceParent: CustomerInvoice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
item_id: source.id.toPrimitive(),
|
item_id: source.id.toPrimitive(),
|
||||||
invoice_id: sourceParent.id.toPrimitive(),
|
invoice_id: sourceParent.id.toPrimitive(),
|
||||||
@ -193,6 +226,6 @@ export class CustomerInvoiceItemMapper
|
|||||||
|
|
||||||
total_amount_value: source.totalAmount.toPrimitive().value,
|
total_amount_value: source.totalAmount.toPrimitive().value,
|
||||||
total_amount_scale: source.totalAmount.toPrimitive().scale,
|
total_amount_scale: source.totalAmount.toPrimitive().scale,
|
||||||
};
|
};*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { JsonTaxCatalogProvider } from "@erp/core";
|
|
||||||
import {
|
import {
|
||||||
ISequelizeMapper,
|
ISequelizeMapper,
|
||||||
MapperParamsType,
|
MapperParamsType,
|
||||||
@ -15,7 +14,6 @@ import {
|
|||||||
UniqueID,
|
UniqueID,
|
||||||
UtcDate,
|
UtcDate,
|
||||||
maybeFromNullableVO,
|
maybeFromNullableVO,
|
||||||
toNullable,
|
|
||||||
} from "@repo/rdx-ddd";
|
} from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import {
|
import {
|
||||||
@ -47,11 +45,10 @@ export class CustomerInvoiceMapper
|
|||||||
private _recipientMapper: InvoiceRecipientMapper;
|
private _recipientMapper: InvoiceRecipientMapper;
|
||||||
private _taxesMapper: TaxesMapper;
|
private _taxesMapper: TaxesMapper;
|
||||||
|
|
||||||
constructor(params: {
|
constructor(params: MapperParamsType) {
|
||||||
taxCatalog: JsonTaxCatalogProvider;
|
|
||||||
}) {
|
|
||||||
super();
|
super();
|
||||||
this._itemsMapper = new CustomerInvoiceItemMapper(); // Instanciar el mapper de items
|
|
||||||
|
this._itemsMapper = new CustomerInvoiceItemMapper(params); // Instanciar el mapper de items
|
||||||
this._recipientMapper = new InvoiceRecipientMapper();
|
this._recipientMapper = new InvoiceRecipientMapper();
|
||||||
this._taxesMapper = new TaxesMapper(params);
|
this._taxesMapper = new TaxesMapper(params);
|
||||||
}
|
}
|
||||||
@ -155,8 +152,10 @@ export class CustomerInvoiceMapper
|
|||||||
try {
|
try {
|
||||||
const errors: ValidationErrorDetail[] = [];
|
const errors: ValidationErrorDetail[] = [];
|
||||||
|
|
||||||
|
// 1) Valores escalares (atributos generales)
|
||||||
const attributes = this.mapAttributesToDomain(source, { errors, ...params });
|
const attributes = this.mapAttributesToDomain(source, { errors, ...params });
|
||||||
|
|
||||||
|
// 2) Comprobar relaciones
|
||||||
const requireIncludes = Boolean(params?.requireIncludes);
|
const requireIncludes = Boolean(params?.requireIncludes);
|
||||||
if (requireIncludes) {
|
if (requireIncludes) {
|
||||||
if (!source.items) {
|
if (!source.items) {
|
||||||
@ -190,13 +189,13 @@ export class CustomerInvoiceMapper
|
|||||||
if (recipientResult.isFailure) {
|
if (recipientResult.isFailure) {
|
||||||
errors.push({
|
errors.push({
|
||||||
path: "recipient",
|
path: "recipient",
|
||||||
|
|
||||||
message: recipientResult.error.message,
|
message: recipientResult.error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) Items (colección)
|
// 4) Items (colección)
|
||||||
const itemsResults = this._itemsMapper.mapArrayToDomain(source.items, {
|
const itemsResults = this._itemsMapper.mapArrayToDomain(source.items, {
|
||||||
requireIncludes,
|
|
||||||
errors,
|
errors,
|
||||||
attributes,
|
attributes,
|
||||||
...params,
|
...params,
|
||||||
@ -219,7 +218,7 @@ export class CustomerInvoiceMapper
|
|||||||
if (taxesResults.isFailure) {
|
if (taxesResults.isFailure) {
|
||||||
errors.push({
|
errors.push({
|
||||||
path: "taxes",
|
path: "taxes",
|
||||||
message: recipientResult.error.message,
|
message: taxesResults.error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +261,7 @@ export class CustomerInvoiceMapper
|
|||||||
languageCode: attributes.languageCode!,
|
languageCode: attributes.languageCode!,
|
||||||
currencyCode: attributes.currencyCode!,
|
currencyCode: attributes.currencyCode!,
|
||||||
|
|
||||||
discountPercentage: attributes.discountPercentage!,
|
//discountPercentage: attributes.discountPercentage!,
|
||||||
|
|
||||||
taxes,
|
taxes,
|
||||||
items,
|
items,
|
||||||
@ -288,7 +287,9 @@ export class CustomerInvoiceMapper
|
|||||||
source: CustomerInvoice,
|
source: CustomerInvoice,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): CustomerInvoiceCreationAttributes {
|
): CustomerInvoiceCreationAttributes {
|
||||||
const items = this._itemsMapper.mapCollectionToPersistence(source.items, params);
|
throw new Error("not implemented");
|
||||||
|
|
||||||
|
/*const items = this._itemsMapper.mapCollectionToPersistence(source.items, params);
|
||||||
|
|
||||||
const customer = source.recipient.match(
|
const customer = source.recipient.match(
|
||||||
(recipient) =>
|
(recipient) =>
|
||||||
@ -363,6 +364,6 @@ export class CustomerInvoiceMapper
|
|||||||
|
|
||||||
items,
|
items,
|
||||||
...customer,
|
...customer,
|
||||||
};
|
};*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,7 @@ import {
|
|||||||
extractOrPushError,
|
extractOrPushError,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { Maybe, Result } from "@repo/rdx-utils";
|
import { Maybe, Result } from "@repo/rdx-utils";
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import { CustomerInvoiceProps, InvoiceRecipient } from "../../domain";
|
||||||
import { CustomerInvoice, CustomerInvoiceProps, InvoiceRecipient } from "../../domain";
|
|
||||||
import { CustomerInvoiceModel } from "../sequelize";
|
import { CustomerInvoiceModel } from "../sequelize";
|
||||||
|
|
||||||
export class InvoiceRecipientMapper {
|
export class InvoiceRecipientMapper {
|
||||||
@ -105,14 +104,4 @@ export class InvoiceRecipientMapper {
|
|||||||
|
|
||||||
return Result.ok(Maybe.some(createResult.data));
|
return Result.ok(Maybe.some(createResult.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public mapToPersistence(
|
|
||||||
source: InvoiceRecipient,
|
|
||||||
params?: MapperParamsType
|
|
||||||
): Partial<InferCreationAttributes<CustomerInvoiceModel, {}>> {
|
|
||||||
const { index, sourceParent } = params as {
|
|
||||||
index: number;
|
|
||||||
sourceParent: CustomerInvoice;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,68 @@
|
|||||||
import { MapperParamsType, Taxes } from "@erp/core/api";
|
import { JsonTaxCatalogProvider } from "@erp/core";
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import {
|
||||||
import { CustomerInvoiceItemModel, CustomerInvoiceItemTaxModel } from "../sequelize";
|
MapperParamsType,
|
||||||
|
SequelizeMapper,
|
||||||
|
Tax,
|
||||||
|
ValidationErrorCollection,
|
||||||
|
ValidationErrorDetail,
|
||||||
|
extractOrPushError,
|
||||||
|
} from "@erp/core/api";
|
||||||
|
import { Result } from "@repo/rdx-utils";
|
||||||
|
import { ItemTax } from "../../domain";
|
||||||
|
import { CustomerInvoiceItemCreationAttributes, CustomerInvoiceItemTaxModel } from "../sequelize";
|
||||||
|
|
||||||
export class ItemTaxesMapper {
|
export class ItemTaxesMapper extends SequelizeMapper<
|
||||||
public mapArrayToDomain(item: CustomerInvoiceItemModel, params?: MapperParamsType) {
|
CustomerInvoiceItemTaxModel,
|
||||||
const taxes = Taxes.create({ items: [] });
|
CustomerInvoiceItemCreationAttributes,
|
||||||
|
ItemTax
|
||||||
|
> {
|
||||||
|
private _taxCatalog!: JsonTaxCatalogProvider;
|
||||||
|
|
||||||
item.taxes.split(",").every((tax_code, taxIndex) => {
|
constructor(params: MapperParamsType) {
|
||||||
const taxResult = Tax.createFromCode(tax_code, this.taxCatalog);
|
super();
|
||||||
if (taxResult.isSuccess) {
|
const { taxCatalog } = params as {
|
||||||
taxes.add(taxResult.data);
|
taxCatalog: JsonTaxCatalogProvider;
|
||||||
} else {
|
};
|
||||||
this.errors.push({
|
|
||||||
path: `items[${itemIndex}].taxes[${taxIndex}]`,
|
if (!taxCatalog) {
|
||||||
message: taxResult.error.message,
|
throw new Error('taxCatalog not defined ("ItemTaxesMapper")');
|
||||||
});
|
}
|
||||||
}
|
|
||||||
});
|
this._taxCatalog = taxCatalog;
|
||||||
return taxes;
|
}
|
||||||
|
|
||||||
|
public mapToDomain(
|
||||||
|
source: CustomerInvoiceItemTaxModel,
|
||||||
|
params?: MapperParamsType
|
||||||
|
): Result<ItemTax, Error> {
|
||||||
|
const { errors, index } = params as {
|
||||||
|
index: number;
|
||||||
|
errors: ValidationErrorDetail[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const tax = extractOrPushError(
|
||||||
|
Tax.createFromCode(source.tax_code, this._taxCatalog),
|
||||||
|
`taxes[${index}].tax_code`,
|
||||||
|
errors
|
||||||
|
);
|
||||||
|
|
||||||
|
// Creación del objeto de dominio
|
||||||
|
const createResult = ItemTax.create({ tax: tax! });
|
||||||
|
if (createResult.isFailure) {
|
||||||
|
return Result.fail(
|
||||||
|
new ValidationErrorCollection("Invoice item tax creation failed", [
|
||||||
|
{ path: `taxes[${index}]`, message: createResult.error.message },
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public mapToPersistence(
|
public mapToPersistence(
|
||||||
source: Taxes,
|
source: ItemTax,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): InferCreationAttributes<CustomerInvoiceItemTaxModel, {}> {
|
): CustomerInvoiceItemCreationAttributes {
|
||||||
/*const { index, sourceParent } = params as {
|
throw new Error("not implemented");
|
||||||
index: number;
|
|
||||||
sourceParent: CustomerInvoice;
|
|
||||||
};*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,20 +3,14 @@ import {
|
|||||||
MapperParamsType,
|
MapperParamsType,
|
||||||
SequelizeMapper,
|
SequelizeMapper,
|
||||||
Tax,
|
Tax,
|
||||||
Taxes,
|
|
||||||
ValidationErrorCollection,
|
ValidationErrorCollection,
|
||||||
ValidationErrorDetail,
|
ValidationErrorDetail,
|
||||||
extractOrPushError,
|
extractOrPushError,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import { CustomerInvoiceProps } from "../../domain";
|
||||||
import { CustomerInvoiceProps, InvoiceAmount } from "../../domain";
|
|
||||||
import { InvoiceTax } from "../../domain/entities/invoice-taxes";
|
import { InvoiceTax } from "../../domain/entities/invoice-taxes";
|
||||||
import {
|
import { CustomerInvoiceTaxCreationAttributes, CustomerInvoiceTaxModel } from "../sequelize";
|
||||||
CustomerInvoiceItemTaxModel,
|
|
||||||
CustomerInvoiceTaxCreationAttributes,
|
|
||||||
CustomerInvoiceTaxModel,
|
|
||||||
} from "../sequelize";
|
|
||||||
|
|
||||||
export class TaxesMapper extends SequelizeMapper<
|
export class TaxesMapper extends SequelizeMapper<
|
||||||
CustomerInvoiceTaxModel,
|
CustomerInvoiceTaxModel,
|
||||||
@ -25,11 +19,16 @@ export class TaxesMapper extends SequelizeMapper<
|
|||||||
> {
|
> {
|
||||||
private _taxCatalog: JsonTaxCatalogProvider;
|
private _taxCatalog: JsonTaxCatalogProvider;
|
||||||
|
|
||||||
constructor(params: {
|
constructor(params: MapperParamsType) {
|
||||||
taxCatalog: JsonTaxCatalogProvider;
|
|
||||||
}) {
|
|
||||||
super();
|
super();
|
||||||
const { taxCatalog } = params;
|
const { taxCatalog } = params as {
|
||||||
|
taxCatalog: JsonTaxCatalogProvider;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!taxCatalog) {
|
||||||
|
throw new Error('taxCatalog not defined ("TaxesMapper")');
|
||||||
|
}
|
||||||
|
|
||||||
this._taxCatalog = taxCatalog;
|
this._taxCatalog = taxCatalog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +38,6 @@ export class TaxesMapper extends SequelizeMapper<
|
|||||||
): Result<InvoiceTax, Error> {
|
): Result<InvoiceTax, Error> {
|
||||||
const { errors, index, attributes } = params as {
|
const { errors, index, attributes } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
requireIncludes: boolean;
|
|
||||||
errors: ValidationErrorDetail[];
|
errors: ValidationErrorDetail[];
|
||||||
attributes: Partial<CustomerInvoiceProps>;
|
attributes: Partial<CustomerInvoiceProps>;
|
||||||
};
|
};
|
||||||
@ -50,48 +48,14 @@ export class TaxesMapper extends SequelizeMapper<
|
|||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const taxableAmount = extractOrPushError(
|
|
||||||
InvoiceAmount.create({
|
|
||||||
value: source.taxable_amount_value,
|
|
||||||
currency_code: attributes.currencyCode?.code,
|
|
||||||
}),
|
|
||||||
`taxes[${index}].taxable_amount_value`,
|
|
||||||
errors
|
|
||||||
);
|
|
||||||
|
|
||||||
if (source.taxable_amount_scale !== InvoiceAmount.DEFAULT_SCALE) {
|
|
||||||
errors.push({
|
|
||||||
path: `taxes[${index}].taxable_amount_scale`,
|
|
||||||
message: "Invalid taxable amount scale",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const taxesAmount = extractOrPushError(
|
|
||||||
InvoiceAmount.create({
|
|
||||||
value: source.taxes_amount_value,
|
|
||||||
currency_code: attributes.currencyCode?.code,
|
|
||||||
}),
|
|
||||||
`taxes[${index}].taxes_amount_value`,
|
|
||||||
errors
|
|
||||||
);
|
|
||||||
|
|
||||||
if (source.taxes_amount_scale !== InvoiceAmount.DEFAULT_SCALE) {
|
|
||||||
errors.push({
|
|
||||||
path: `taxes[${index}].taxes_amount_scale`,
|
|
||||||
message: "Invalid taxes amount scale",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creación del objeto de dominio
|
// Creación del objeto de dominio
|
||||||
const createResult = InvoiceTax.create({
|
const createResult = InvoiceTax.create({
|
||||||
tax: tax!,
|
tax: tax!,
|
||||||
taxableAmount: taxableAmount!,
|
|
||||||
taxesAmount: taxesAmount!,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (createResult.isFailure) {
|
if (createResult.isFailure) {
|
||||||
return Result.fail(
|
return Result.fail(
|
||||||
new ValidationErrorCollection("Invoice taxes creation failed", [
|
new ValidationErrorCollection("Invoice tax creation failed", [
|
||||||
{ path: `taxes[${index}]`, message: createResult.error.message },
|
{ path: `taxes[${index}]`, message: createResult.error.message },
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
@ -101,12 +65,9 @@ export class TaxesMapper extends SequelizeMapper<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public mapToPersistence(
|
public mapToPersistence(
|
||||||
source: Taxes,
|
source: InvoiceTax,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): InferCreationAttributes<CustomerInvoiceItemTaxModel, {}> {
|
): CustomerInvoiceTaxCreationAttributes {
|
||||||
/*const { index, sourceParent } = params as {
|
throw new Error("not implemented");
|
||||||
index: number;
|
|
||||||
sourceParent: CustomerInvoice;
|
|
||||||
};*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,9 @@ import { Collection, Result } from "@repo/rdx-utils";
|
|||||||
import { Sequelize, Transaction } from "sequelize";
|
import { Sequelize, Transaction } from "sequelize";
|
||||||
import { CustomerInvoice, ICustomerInvoiceRepository } from "../../domain";
|
import { CustomerInvoice, ICustomerInvoiceRepository } from "../../domain";
|
||||||
import { ICustomerInvoiceMapper } from "../mappers/customer-invoice.mapper";
|
import { ICustomerInvoiceMapper } from "../mappers/customer-invoice.mapper";
|
||||||
|
import { CustomerInvoiceItemTaxModel } from "./customer-invoice-item-tax.model";
|
||||||
|
import { CustomerInvoiceItemModel } from "./customer-invoice-item.model";
|
||||||
|
import { CustomerInvoiceTaxModel } from "./customer-invoice-tax.model";
|
||||||
import { CustomerInvoiceModel } from "./customer-invoice.model";
|
import { CustomerInvoiceModel } from "./customer-invoice.model";
|
||||||
|
|
||||||
export class CustomerInvoiceRepository
|
export class CustomerInvoiceRepository
|
||||||
@ -124,6 +127,23 @@ export class CustomerInvoiceRepository
|
|||||||
as: "current_customer",
|
as: "current_customer",
|
||||||
required: false, // false => LEFT JOIN
|
required: false, // false => LEFT JOIN
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
model: CustomerInvoiceItemModel,
|
||||||
|
as: "items",
|
||||||
|
required: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: CustomerInvoiceItemTaxModel,
|
||||||
|
as: "taxes",
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: CustomerInvoiceTaxModel,
|
||||||
|
as: "taxes",
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -49,4 +49,8 @@ export class CurrencyCode extends ValueObject<CurrencyCodeProps> {
|
|||||||
toPrimitive(): string {
|
toPrimitive(): string {
|
||||||
return this.props.value;
|
return this.props.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return String(this.props.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,4 +49,8 @@ export class LanguageCode extends ValueObject<LanguageCodeProps> {
|
|||||||
toPrimitive(): string {
|
toPrimitive(): string {
|
||||||
return this.props.value;
|
return this.props.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return String(this.props.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,10 @@ export class TextValue extends ValueObject<TextValueProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toPrimitive(): string {
|
toPrimitive(): string {
|
||||||
|
return this.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
return String(this.getProps());
|
return String(this.getProps());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user