.
This commit is contained in:
parent
167eaff171
commit
056e78548e
@ -36,11 +36,6 @@ export class Tax extends ValueObject<TaxProps> {
|
|||||||
.int()
|
.int()
|
||||||
.min(Tax.MIN_VALUE, "La tasa de impuesto no puede ser negativa.")
|
.min(Tax.MIN_VALUE, "La tasa de impuesto no puede ser negativa.")
|
||||||
.max(Tax.MAX_VALUE * 10 ** Tax.MAX_SCALE, "La tasa de impuesto es demasiado alta."),
|
.max(Tax.MAX_VALUE * 10 ** Tax.MAX_SCALE, "La tasa de impuesto es demasiado alta."),
|
||||||
scale: z
|
|
||||||
.number()
|
|
||||||
.int()
|
|
||||||
.min(Tax.MIN_SCALE)
|
|
||||||
.max(Tax.MAX_SCALE, `La escala debe estar entre ${Tax.MIN_SCALE} y ${Tax.MAX_SCALE}.`),
|
|
||||||
name: z
|
name: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, "El nombre del impuesto es obligatorio.")
|
.min(1, "El nombre del impuesto es obligatorio.")
|
||||||
|
|||||||
@ -32,8 +32,10 @@ export interface IIssuedInvoiceFullSnapshot {
|
|||||||
subtotal_amount: { value: string; scale: string; currency_code: string };
|
subtotal_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
items_discount_amount: { value: string; scale: string; currency_code: string };
|
items_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
global_discount_percentage: { value: string; scale: string };
|
global_discount_percentage: { value: string; scale: string };
|
||||||
global_discount_amount: { value: string; scale: string; currency_code: string };
|
global_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
total_discount_amount: { value: string; scale: string; currency_code: string };
|
total_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
taxable_amount: { value: string; scale: string; currency_code: string };
|
taxable_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|||||||
@ -9,8 +9,8 @@ export interface IIssuedInvoiceItemFullSnapshot {
|
|||||||
|
|
||||||
subtotal_amount: { value: string; scale: string; currency_code: string };
|
subtotal_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
discount_percentage: { value: string; scale: string };
|
item_discount_percentage: { value: string; scale: string };
|
||||||
discount_amount: { value: string; scale: string; currency_code: string };
|
item_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
global_discount_percentage: { value: string; scale: string };
|
global_discount_percentage: { value: string; scale: string };
|
||||||
global_discount_amount: { value: string; scale: string; currency_code: string };
|
global_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|||||||
@ -17,7 +17,8 @@ export class IssuedInvoiceItemsFullSnapshotBuilder
|
|||||||
implements IIssuedInvoiceItemsFullSnapshotBuilder
|
implements IIssuedInvoiceItemsFullSnapshotBuilder
|
||||||
{
|
{
|
||||||
private mapItem(invoiceItem: IssuedInvoiceItem, index: number): IIssuedInvoiceItemFullSnapshot {
|
private mapItem(invoiceItem: IssuedInvoiceItem, index: number): IIssuedInvoiceItemFullSnapshot {
|
||||||
const isValued = invoiceItem.isValued;
|
const isValued = invoiceItem.isValued();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: invoiceItem.id.toPrimitive(),
|
id: invoiceItem.id.toPrimitive(),
|
||||||
is_valued: String(isValued),
|
is_valued: String(isValued),
|
||||||
@ -32,14 +33,15 @@ export class IssuedInvoiceItemsFullSnapshotBuilder
|
|||||||
? invoiceItem.subtotalAmount.toObjectString()
|
? invoiceItem.subtotalAmount.toObjectString()
|
||||||
: ItemAmount.EMPTY_MONEY_OBJECT,
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
discount_percentage: maybeToEmptyPercentageObjectString(invoiceItem.itemDiscountPercentage),
|
item_discount_percentage: maybeToEmptyPercentageObjectString(
|
||||||
discount_amount: isValued
|
invoiceItem.itemDiscountPercentage
|
||||||
|
),
|
||||||
|
item_discount_amount: isValued
|
||||||
? invoiceItem.itemDiscountAmount.toObjectString()
|
? invoiceItem.itemDiscountAmount.toObjectString()
|
||||||
: ItemAmount.EMPTY_MONEY_OBJECT,
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
global_discount_percentage: maybeToEmptyPercentageObjectString(
|
global_discount_percentage: invoiceItem.globalDiscountPercentage.toObjectString(),
|
||||||
invoiceItem.globalDiscountPercentage
|
|
||||||
),
|
|
||||||
global_discount_amount: isValued
|
global_discount_amount: isValued
|
||||||
? invoiceItem.globalDiscountAmount.toObjectString()
|
? invoiceItem.globalDiscountAmount.toObjectString()
|
||||||
: ItemAmount.EMPTY_MONEY_OBJECT,
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
import type { ISnapshotBuilder } from "@erp/core/api";
|
import type { ISnapshotBuilder } from "@erp/core/api";
|
||||||
import {
|
import { maybeToEmptyPercentageObjectString, maybeToEmptyString } from "@repo/rdx-ddd";
|
||||||
maybeToEmptyMoneyObjectString,
|
|
||||||
maybeToEmptyPercentageObjectString,
|
|
||||||
maybeToEmptyString,
|
|
||||||
} from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
import type { IssuedInvoiceTax, IssuedInvoiceTaxes } from "../../../../domain";
|
import type { IssuedInvoiceTax, IssuedInvoiceTaxes } from "../../../../domain";
|
||||||
|
|
||||||
@ -25,11 +21,11 @@ export class IssuedInvoiceTaxesFullSnapshotBuilder
|
|||||||
|
|
||||||
rec_code: maybeToEmptyString(invoiceTax.recCode),
|
rec_code: maybeToEmptyString(invoiceTax.recCode),
|
||||||
rec_percentage: maybeToEmptyPercentageObjectString(invoiceTax.recPercentage),
|
rec_percentage: maybeToEmptyPercentageObjectString(invoiceTax.recPercentage),
|
||||||
rec_amount: maybeToEmptyMoneyObjectString(invoiceTax.recAmount),
|
rec_amount: invoiceTax.recAmount.toObjectString(),
|
||||||
|
|
||||||
retention_code: maybeToEmptyString(invoiceTax.retentionCode),
|
retention_code: maybeToEmptyString(invoiceTax.retentionCode),
|
||||||
retention_percentage: maybeToEmptyPercentageObjectString(invoiceTax.retentionPercentage),
|
retention_percentage: maybeToEmptyPercentageObjectString(invoiceTax.retentionPercentage),
|
||||||
retention_amount: maybeToEmptyMoneyObjectString(invoiceTax.retentionAmount),
|
retention_amount: invoiceTax.retentionAmount.toObjectString(),
|
||||||
|
|
||||||
taxes_amount: invoiceTax.taxesAmount.toObjectString(),
|
taxes_amount: invoiceTax.taxesAmount.toObjectString(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,14 +8,21 @@ import {
|
|||||||
ProformaRecipientFullSnapshotBuilder,
|
ProformaRecipientFullSnapshotBuilder,
|
||||||
ProformaReportSnapshotBuilder,
|
ProformaReportSnapshotBuilder,
|
||||||
ProformaTaxReportSnapshotBuilder,
|
ProformaTaxReportSnapshotBuilder,
|
||||||
|
ProformaTaxesFullSnapshotBuilder,
|
||||||
} from "../snapshot-builders";
|
} from "../snapshot-builders";
|
||||||
|
|
||||||
export function buildProformaSnapshotBuilders() {
|
export function buildProformaSnapshotBuilders() {
|
||||||
const itemsBuilder = new ProformaItemsFullSnapshotBuilder();
|
const itemsBuilder = new ProformaItemsFullSnapshotBuilder();
|
||||||
|
|
||||||
|
const taxesBuilder = new ProformaTaxesFullSnapshotBuilder();
|
||||||
|
|
||||||
const recipientBuilder = new ProformaRecipientFullSnapshotBuilder();
|
const recipientBuilder = new ProformaRecipientFullSnapshotBuilder();
|
||||||
|
|
||||||
const fullSnapshotBuilder = new ProformaFullSnapshotBuilder(itemsBuilder, recipientBuilder);
|
const fullSnapshotBuilder = new ProformaFullSnapshotBuilder(
|
||||||
|
itemsBuilder,
|
||||||
|
recipientBuilder,
|
||||||
|
taxesBuilder
|
||||||
|
);
|
||||||
|
|
||||||
const listSnapshotBuilder = new ProformaListItemSnapshotBuilder();
|
const listSnapshotBuilder = new ProformaListItemSnapshotBuilder();
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import type { ISnapshotBuilder } from "@erp/core/api";
|
import type { ISnapshotBuilder } from "@erp/core/api";
|
||||||
import { maybeToEmptyString } from "@repo/rdx-ddd";
|
import { maybeToEmptyString } from "@repo/rdx-ddd";
|
||||||
|
|
||||||
import { InvoiceAmount, type Proforma } from "../../../../domain";
|
import type { Proforma } from "../../../../domain";
|
||||||
|
|
||||||
import type { IProformaFullSnapshot } from "./proforma-full-snapshot.interface";
|
import type { IProformaFullSnapshot } from "./proforma-full-snapshot.interface";
|
||||||
import type { IProformaItemsFullSnapshotBuilder } from "./proforma-items-full-snapshot-builder";
|
import type { IProformaItemsFullSnapshotBuilder } from "./proforma-items-full-snapshot-builder";
|
||||||
import type { IProformaRecipientFullSnapshotBuilder } from "./proforma-recipient-full-snapshot-builder";
|
import type { IProformaRecipientFullSnapshotBuilder } from "./proforma-recipient-full-snapshot-builder";
|
||||||
|
import type { IProformaTaxesFullSnapshotBuilder } from "./proforma-taxes-full-snapshot-builder";
|
||||||
|
|
||||||
export interface IProformaFullSnapshotBuilder
|
export interface IProformaFullSnapshotBuilder
|
||||||
extends ISnapshotBuilder<Proforma, IProformaFullSnapshot> {}
|
extends ISnapshotBuilder<Proforma, IProformaFullSnapshot> {}
|
||||||
@ -13,14 +14,14 @@ export interface IProformaFullSnapshotBuilder
|
|||||||
export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder {
|
export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly itemsBuilder: IProformaItemsFullSnapshotBuilder,
|
private readonly itemsBuilder: IProformaItemsFullSnapshotBuilder,
|
||||||
private readonly recipientBuilder: IProformaRecipientFullSnapshotBuilder
|
private readonly recipientBuilder: IProformaRecipientFullSnapshotBuilder,
|
||||||
|
private readonly taxesBuilder: IProformaTaxesFullSnapshotBuilder
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
toOutput(invoice: Proforma): IProformaFullSnapshot {
|
toOutput(invoice: Proforma): IProformaFullSnapshot {
|
||||||
const items = this.itemsBuilder.toOutput(invoice.items);
|
const items = this.itemsBuilder.toOutput(invoice.items);
|
||||||
const recipient = this.recipientBuilder.toOutput(invoice);
|
const recipient = this.recipientBuilder.toOutput(invoice);
|
||||||
|
const taxes = this.taxesBuilder.toOutput(invoice.taxes());
|
||||||
const allAmounts = invoice.calculateAllAmounts();
|
|
||||||
|
|
||||||
const payment = invoice.paymentMethod.match(
|
const payment = invoice.paymentMethod.match(
|
||||||
(payment) => {
|
(payment) => {
|
||||||
@ -33,51 +34,7 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
|
|||||||
() => undefined
|
() => undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
let totalIvaAmount = InvoiceAmount.zero(invoice.currencyCode.code);
|
const allTotals = invoice.totals();
|
||||||
let totalRecAmount = InvoiceAmount.zero(invoice.currencyCode.code);
|
|
||||||
let totalRetentionAmount = InvoiceAmount.zero(invoice.currencyCode.code);
|
|
||||||
|
|
||||||
const invoiceTaxes = invoice.getTaxes().map((taxGroup) => {
|
|
||||||
const { ivaAmount, recAmount, retentionAmount, totalAmount } = taxGroup.calculateAmounts();
|
|
||||||
|
|
||||||
totalIvaAmount = totalIvaAmount.add(ivaAmount);
|
|
||||||
totalRecAmount = totalRecAmount.add(recAmount);
|
|
||||||
totalRetentionAmount = totalRetentionAmount.add(retentionAmount);
|
|
||||||
|
|
||||||
return {
|
|
||||||
taxable_amount: taxGroup.taxableAmount.toObjectString(),
|
|
||||||
|
|
||||||
iva_code: taxGroup.iva.code,
|
|
||||||
iva_percentage: taxGroup.iva.percentage.toObjectString(),
|
|
||||||
iva_amount: ivaAmount.toObjectString(),
|
|
||||||
|
|
||||||
rec_code: taxGroup.rec.match(
|
|
||||||
(rec) => rec.code,
|
|
||||||
() => ""
|
|
||||||
),
|
|
||||||
|
|
||||||
rec_percentage: taxGroup.rec.match(
|
|
||||||
(rec) => rec.percentage.toObjectString(),
|
|
||||||
() => ({ value: "", scale: "" })
|
|
||||||
),
|
|
||||||
|
|
||||||
rec_amount: recAmount.toObjectString(),
|
|
||||||
|
|
||||||
retention_code: taxGroup.retention.match(
|
|
||||||
(retention) => retention.code,
|
|
||||||
() => ""
|
|
||||||
),
|
|
||||||
|
|
||||||
retention_percentage: taxGroup.retention.match(
|
|
||||||
(retention) => retention.percentage.toObjectString(),
|
|
||||||
() => ({ value: "", scale: "" })
|
|
||||||
),
|
|
||||||
|
|
||||||
retention_amount: retentionAmount.toObjectString(),
|
|
||||||
|
|
||||||
taxes_amount: totalAmount.toObjectString(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: invoice.id.toString(),
|
id: invoice.id.toString(),
|
||||||
@ -102,22 +59,24 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
|
|||||||
|
|
||||||
payment_method: payment,
|
payment_method: payment,
|
||||||
|
|
||||||
subtotal_amount: allAmounts.subtotalAmount.toObjectString(),
|
subtotal_amount: allTotals.subtotalAmount.toObjectString(),
|
||||||
items_discount_amount: allAmounts.itemDiscountAmount.toObjectString(),
|
items_discount_amount: allTotals.itemDiscountAmount.toObjectString(),
|
||||||
|
|
||||||
discount_percentage: invoice.globalDiscountPercentage.toObjectString(),
|
global_discount_percentage: invoice.globalDiscountPercentage.toObjectString(),
|
||||||
discount_amount: allAmounts.globalDiscountAmount.toObjectString(),
|
global_discount_amount: allTotals.globalDiscountAmount.toObjectString(),
|
||||||
|
|
||||||
taxable_amount: allAmounts.taxableAmount.toObjectString(),
|
total_discount_amount: allTotals.totalDiscountAmount.toObjectString(),
|
||||||
|
|
||||||
iva_amount: totalIvaAmount.toObjectString(),
|
taxable_amount: allTotals.taxableAmount.toObjectString(),
|
||||||
rec_amount: totalRecAmount.toObjectString(),
|
|
||||||
retention_amount: totalRetentionAmount.toObjectString(),
|
|
||||||
|
|
||||||
taxes_amount: allAmounts.taxesAmount.toObjectString(),
|
iva_amount: allTotals.ivaAmount.toObjectString(),
|
||||||
total_amount: allAmounts.totalAmount.toObjectString(),
|
rec_amount: allTotals.recAmount.toObjectString(),
|
||||||
|
retention_amount: allTotals.retentionAmount.toObjectString(),
|
||||||
|
|
||||||
taxes: invoiceTaxes,
|
taxes_amount: allTotals.taxesAmount.toObjectString(),
|
||||||
|
total_amount: allTotals.totalAmount.toObjectString(),
|
||||||
|
|
||||||
|
taxes,
|
||||||
|
|
||||||
items,
|
items,
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import type { IProformaItemFullSnapshot } from "./proforma-item-full-snapshot.interface";
|
import type { IProformaItemFullSnapshot } from "./proforma-item-full-snapshot.interface";
|
||||||
import type { IProformaRecipientFullSnapshot } from "./proforma-recipient-full-snapshot.interface";
|
import type { IProformaRecipientFullSnapshot } from "./proforma-recipient-full-snapshot.interface";
|
||||||
|
import type { IProformaTaxFullSnapshot } from "./proforma-tax-full-snapshot-interface";
|
||||||
|
|
||||||
export interface IProformaFullSnapshot {
|
export interface IProformaFullSnapshot {
|
||||||
id: string;
|
id: string;
|
||||||
@ -30,8 +31,10 @@ export interface IProformaFullSnapshot {
|
|||||||
subtotal_amount: { value: string; scale: string; currency_code: string };
|
subtotal_amount: { value: string; scale: string; currency_code: string };
|
||||||
items_discount_amount: { value: string; scale: string; currency_code: string };
|
items_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
discount_percentage: { value: string; scale: string };
|
global_discount_percentage: { value: string; scale: string };
|
||||||
discount_amount: { value: string; scale: string; currency_code: string };
|
global_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
|
total_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
taxable_amount: { value: string; scale: string; currency_code: string };
|
taxable_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
@ -42,23 +45,7 @@ export interface IProformaFullSnapshot {
|
|||||||
taxes_amount: { value: string; scale: string; currency_code: string };
|
taxes_amount: { value: string; scale: string; currency_code: string };
|
||||||
total_amount: { value: string; scale: string; currency_code: string };
|
total_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
taxes: Array<{
|
taxes: IProformaTaxFullSnapshot[];
|
||||||
taxable_amount: { value: string; scale: string; currency_code: string };
|
|
||||||
|
|
||||||
iva_code: string;
|
|
||||||
iva_percentage: { value: string; scale: string };
|
|
||||||
iva_amount: { value: string; scale: string; currency_code: string };
|
|
||||||
|
|
||||||
rec_code: string;
|
|
||||||
rec_percentage: { value: string; scale: string };
|
|
||||||
rec_amount: { value: string; scale: string; currency_code: string };
|
|
||||||
|
|
||||||
retention_code: string;
|
|
||||||
retention_percentage: { value: string; scale: string };
|
|
||||||
retention_amount: { value: string; scale: string; currency_code: string };
|
|
||||||
|
|
||||||
taxes_amount: { value: string; scale: string; currency_code: string };
|
|
||||||
}>;
|
|
||||||
|
|
||||||
items: IProformaItemFullSnapshot[];
|
items: IProformaItemFullSnapshot[];
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,8 @@ export interface IProformaItemFullSnapshot {
|
|||||||
global_discount_percentage: { value: string; scale: string };
|
global_discount_percentage: { value: string; scale: string };
|
||||||
global_discount_amount: { value: string; scale: string; currency_code: string };
|
global_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
|
total_discount_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
taxable_amount: { value: string; scale: string; currency_code: string };
|
taxable_amount: { value: string; scale: string; currency_code: string };
|
||||||
|
|
||||||
iva_code: string;
|
iva_code: string;
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import {
|
|||||||
maybeToEmptyQuantityObjectString,
|
maybeToEmptyQuantityObjectString,
|
||||||
maybeToEmptyString,
|
maybeToEmptyString,
|
||||||
} from "@repo/rdx-ddd";
|
} from "@repo/rdx-ddd";
|
||||||
import { Maybe } from "@repo/rdx-utils";
|
|
||||||
|
|
||||||
import { ItemAmount, type ProformaItem, type ProformaItems } from "../../../../domain";
|
import { ItemAmount, type ProformaItem, type ProformaItems } from "../../../../domain";
|
||||||
|
|
||||||
@ -16,10 +15,8 @@ export interface IProformaItemsFullSnapshotBuilder
|
|||||||
|
|
||||||
export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnapshotBuilder {
|
export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnapshotBuilder {
|
||||||
private mapItem(proformaItem: ProformaItem, index: number): IProformaItemFullSnapshot {
|
private mapItem(proformaItem: ProformaItem, index: number): IProformaItemFullSnapshot {
|
||||||
const allAmounts = proformaItem.calculateAllAmounts();
|
const allAmounts = proformaItem.totals();
|
||||||
const isValued = proformaItem.isValued;
|
const isValued = proformaItem.isValued();
|
||||||
|
|
||||||
const noneIfNotValued = <T>(value: Maybe<T>): Maybe<T> => (isValued ? value : Maybe.none<T>());
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: proformaItem.id.toPrimitive(),
|
id: proformaItem.id.toPrimitive(),
|
||||||
@ -40,10 +37,11 @@ export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnaps
|
|||||||
? allAmounts.itemDiscountAmount.toObjectString()
|
? allAmounts.itemDiscountAmount.toObjectString()
|
||||||
: ItemAmount.EMPTY_MONEY_OBJECT,
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
global_discount_percentage: maybeToEmptyPercentageObjectString(
|
global_discount_percentage: proformaItem.globalDiscountPercentage.toObjectString(),
|
||||||
proformaItem.globalDiscountPercentage
|
|
||||||
),
|
global_discount_amount: isValued
|
||||||
global_discount_amount: maybeToEmptyMoneyObjectString(proformaItem.globalDiscountAmount),
|
? allAmounts.globalDiscountAmount.toObjectString()
|
||||||
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
total_discount_amount: isValued
|
total_discount_amount: isValued
|
||||||
? allAmounts.totalDiscountAmount.toObjectString()
|
? allAmounts.totalDiscountAmount.toObjectString()
|
||||||
@ -53,20 +51,26 @@ export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnaps
|
|||||||
? allAmounts.taxableAmount.toObjectString()
|
? allAmounts.taxableAmount.toObjectString()
|
||||||
: ItemAmount.EMPTY_MONEY_OBJECT,
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
iva_code: maybeToEmptyString(proformaItem.ivaCode),
|
iva_code: maybeToEmptyString(proformaItem.ivaCode()),
|
||||||
iva_percentage: maybeToEmptyPercentageObjectString(proformaItem.ivaPercentage),
|
iva_percentage: maybeToEmptyPercentageObjectString(proformaItem.ivaPercentage()),
|
||||||
iva_amount: maybeToEmptyMoneyObjectString(proformaItem.ivaAmount),
|
iva_amount: isValued ? allAmounts.ivaAmount.toObjectString() : ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
rec_code: maybeToEmptyString(proformaItem.recCode),
|
rec_code: maybeToEmptyString(proformaItem.recCode()),
|
||||||
rec_percentage: maybeToEmptyPercentageObjectString(proformaItem.recPercentage),
|
rec_percentage: maybeToEmptyPercentageObjectString(proformaItem.recPercentage()),
|
||||||
rec_amount: maybeToEmptyMoneyObjectString(proformaItem.recAmount),
|
rec_amount: isValued ? allAmounts.recAmount.toObjectString() : ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
retention_code: maybeToEmptyString(proformaItem.retentionCode),
|
retention_code: maybeToEmptyString(proformaItem.retentionCode()),
|
||||||
retention_percentage: maybeToEmptyPercentageObjectString(proformaItem.retentionPercentage),
|
retention_percentage: maybeToEmptyPercentageObjectString(proformaItem.retentionPercentage()),
|
||||||
retention_amount: maybeToEmptyMoneyObjectString(proformaItem.retentionAmount),
|
retention_amount: isValued
|
||||||
|
? allAmounts.retentionAmount.toObjectString()
|
||||||
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
|
||||||
taxes_amount: maybeToEmptyMoneyObjectString(proformaItem.taxesAmount),
|
taxes_amount: isValued
|
||||||
total_amount: maybeToEmptyMoneyObjectString(proformaItem.totalAmount),
|
? allAmounts.taxesAmount.toObjectString()
|
||||||
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
|
total_amount: isValued
|
||||||
|
? allAmounts.totalAmount.toObjectString()
|
||||||
|
: ItemAmount.EMPTY_MONEY_OBJECT,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,39 +1,36 @@
|
|||||||
import type { ISnapshotBuilder } from "@erp/core/api";
|
import type { ISnapshotBuilder } from "@erp/core/api";
|
||||||
import {
|
import { maybeToEmptyPercentageObjectString, maybeToEmptyString } from "@repo/rdx-ddd";
|
||||||
maybeToEmptyMoneyObjectString,
|
import type { Collection } from "@repo/rdx-utils";
|
||||||
maybeToEmptyPercentageObjectString,
|
|
||||||
maybeToEmptyString,
|
|
||||||
} from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
import type { ProformaTax, ProformaTaxes } from "../../../../domain";
|
import type { IProformaTaxTotals } from "../../../../domain";
|
||||||
|
|
||||||
import type { IProformaTaxFullSnapshot } from "./proforma-tax-full-snapshot-interface";
|
import type { IProformaTaxFullSnapshot } from "./proforma-tax-full-snapshot-interface";
|
||||||
|
|
||||||
export interface IProformaTaxesFullSnapshotBuilder
|
export interface IProformaTaxesFullSnapshotBuilder
|
||||||
extends ISnapshotBuilder<ProformaTaxes, IProformaTaxFullSnapshot[]> {}
|
extends ISnapshotBuilder<Collection<IProformaTaxTotals>, IProformaTaxFullSnapshot[]> {}
|
||||||
|
|
||||||
export class ProformaTaxesFullSnapshotBuilder implements IProformaTaxesFullSnapshotBuilder {
|
export class ProformaTaxesFullSnapshotBuilder implements IProformaTaxesFullSnapshotBuilder {
|
||||||
private mapItem(proformaTax: ProformaTax, index: number): IProformaTaxFullSnapshot {
|
private mapItem(proformaTax: IProformaTaxTotals, index: number): IProformaTaxFullSnapshot {
|
||||||
return {
|
return {
|
||||||
taxable_amount: proformaTax.taxableAmount.toObjectString(),
|
taxable_amount: proformaTax.taxableAmount.toObjectString(),
|
||||||
|
|
||||||
iva_code: proformaTax.ivaCode.toString(),
|
iva_code: maybeToEmptyString(proformaTax.ivaCode),
|
||||||
iva_percentage: proformaTax.ivaPercentage.toObjectString(),
|
iva_percentage: maybeToEmptyPercentageObjectString(proformaTax.ivaPercentage),
|
||||||
iva_amount: proformaTax.ivaAmount.toObjectString(),
|
iva_amount: proformaTax.ivaAmount.toObjectString(),
|
||||||
|
|
||||||
rec_code: maybeToEmptyString(proformaTax.recCode),
|
rec_code: maybeToEmptyString(proformaTax.recCode),
|
||||||
rec_percentage: maybeToEmptyPercentageObjectString(proformaTax.recPercentage),
|
rec_percentage: maybeToEmptyPercentageObjectString(proformaTax.recPercentage),
|
||||||
rec_amount: maybeToEmptyMoneyObjectString(proformaTax.recAmount),
|
rec_amount: proformaTax.recAmount.toObjectString(),
|
||||||
|
|
||||||
retention_code: maybeToEmptyString(proformaTax.retentionCode),
|
retention_code: maybeToEmptyString(proformaTax.retentionCode),
|
||||||
retention_percentage: maybeToEmptyPercentageObjectString(proformaTax.retentionPercentage),
|
retention_percentage: maybeToEmptyPercentageObjectString(proformaTax.retentionPercentage),
|
||||||
retention_amount: maybeToEmptyMoneyObjectString(proformaTax.retentionAmount),
|
retention_amount: proformaTax.retentionAmount.toObjectString(),
|
||||||
|
|
||||||
taxes_amount: proformaTax.taxesAmount.toObjectString(),
|
taxes_amount: proformaTax.taxesAmount.toObjectString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toOutput(invoiceTaxes: ProformaTaxes): IProformaTaxFullSnapshot[] {
|
toOutput(invoiceTaxes: Collection<IProformaTaxTotals>): IProformaTaxFullSnapshot[] {
|
||||||
return invoiceTaxes.map((item, index) => this.mapItem(item, index));
|
return invoiceTaxes.map((item, index) => this.mapItem(item, index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export type IssuedInvoiceItemProps = {
|
|||||||
itemDiscountPercentage: Maybe<DiscountPercentage>;
|
itemDiscountPercentage: Maybe<DiscountPercentage>;
|
||||||
itemDiscountAmount: ItemAmount;
|
itemDiscountAmount: ItemAmount;
|
||||||
|
|
||||||
globalDiscountPercentage: Maybe<DiscountPercentage>;
|
globalDiscountPercentage: DiscountPercentage;
|
||||||
globalDiscountAmount: ItemAmount;
|
globalDiscountAmount: ItemAmount;
|
||||||
|
|
||||||
totalDiscountAmount: ItemAmount;
|
totalDiscountAmount: ItemAmount;
|
||||||
@ -51,7 +51,14 @@ export type IssuedInvoiceItemProps = {
|
|||||||
currencyCode: CurrencyCode;
|
currencyCode: CurrencyCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class IssuedInvoiceItem extends DomainEntity<IssuedInvoiceItemProps> {
|
export interface IIssuedInvoiceItem extends IssuedInvoiceItemProps {
|
||||||
|
isValued(): boolean; // Indica si el item tiene cantidad o precio (o ambos) para ser considerado "valorizado"
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IssuedInvoiceItem
|
||||||
|
extends DomainEntity<IssuedInvoiceItemProps>
|
||||||
|
implements IIssuedInvoiceItem
|
||||||
|
{
|
||||||
public static create(
|
public static create(
|
||||||
props: IssuedInvoiceItemProps,
|
props: IssuedInvoiceItemProps,
|
||||||
id?: UniqueID
|
id?: UniqueID
|
||||||
@ -70,11 +77,6 @@ export class IssuedInvoiceItem extends DomainEntity<IssuedInvoiceItemProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
||||||
get isValued(): boolean {
|
|
||||||
return this.quantity.isSome() || this.unitAmount.isSome();
|
|
||||||
}
|
|
||||||
|
|
||||||
get description() {
|
get description() {
|
||||||
return this.props.description;
|
return this.props.description;
|
||||||
}
|
}
|
||||||
@ -168,4 +170,8 @@ export class IssuedInvoiceItem extends DomainEntity<IssuedInvoiceItemProps> {
|
|||||||
toPrimitive() {
|
toPrimitive() {
|
||||||
return this.getProps();
|
return this.getProps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isValued(): boolean {
|
||||||
|
return this.props.quantity.isSome() || this.props.unitAmount.isSome();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import type { CurrencyCode, LanguageCode, Percentage } from "@repo/rdx-ddd";
|
import type { CurrencyCode, LanguageCode, Percentage } from "@repo/rdx-ddd";
|
||||||
import { Collection } from "@repo/rdx-utils";
|
import { Collection } from "@repo/rdx-utils";
|
||||||
|
|
||||||
import { ItemDiscountPercentage } from "../../../common";
|
|
||||||
|
|
||||||
import type { IssuedInvoiceItem } from "./issued-invoice-item.entity";
|
import type { IssuedInvoiceItem } from "./issued-invoice-item.entity";
|
||||||
|
|
||||||
export type IssuedInvoiceItemsProps = {
|
export type IssuedInvoiceItemsProps = {
|
||||||
@ -44,16 +42,10 @@ export class IssuedInvoiceItems extends Collection<IssuedInvoiceItem> {
|
|||||||
!(
|
!(
|
||||||
this._languageCode.equals(item.languageCode) &&
|
this._languageCode.equals(item.languageCode) &&
|
||||||
this._currencyCode.equals(item.currencyCode) &&
|
this._currencyCode.equals(item.currencyCode) &&
|
||||||
this._globalDiscountPercentage.equals(
|
this._globalDiscountPercentage.equals(item.globalDiscountPercentage)
|
||||||
item.globalDiscountPercentage.match(
|
|
||||||
(v) => v,
|
|
||||||
() => ItemDiscountPercentage.zero()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
) {
|
)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return super.add(item);
|
return super.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -284,7 +284,7 @@ export class ProformaItem extends DomainEntity<ProformaItemProps> implements IPr
|
|||||||
const taxableAmount = subtotalAmount.subtract(totalDiscountAmount);
|
const taxableAmount = subtotalAmount.subtract(totalDiscountAmount);
|
||||||
|
|
||||||
// Calcular impuestos individuales a partir de la base imponible
|
// Calcular impuestos individuales a partir de la base imponible
|
||||||
const { ivaAmount, recAmount, retentionAmount } = this.taxes.calculateAmounts(taxableAmount);
|
const { ivaAmount, recAmount, retentionAmount } = this.taxes.totals(taxableAmount);
|
||||||
|
|
||||||
const taxesAmount = ivaAmount.add(recAmount).add(retentionAmount);
|
const taxesAmount = ivaAmount.add(recAmount).add(retentionAmount);
|
||||||
const totalAmount = taxableAmount.add(taxesAmount);
|
const totalAmount = taxableAmount.add(taxesAmount);
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
export * from "./aggregates";
|
export * from "./aggregates";
|
||||||
export * from "./entities";
|
export * from "./entities";
|
||||||
export * from "./errors";
|
export * from "./errors";
|
||||||
|
export * from "./services";
|
||||||
|
export * from "./value-objects";
|
||||||
|
|||||||
@ -10,10 +10,10 @@ import type { IProformaTaxTotals } from "./proforma-taxes-calculator";
|
|||||||
* 3) RET (None primero) (code, %)
|
* 3) RET (None primero) (code, %)
|
||||||
*/
|
*/
|
||||||
export function proformaCompareTaxTotals(a: IProformaTaxTotals, b: IProformaTaxTotals): number {
|
export function proformaCompareTaxTotals(a: IProformaTaxTotals, b: IProformaTaxTotals): number {
|
||||||
const byIvaCode = compareCode(a.ivaCode, b.ivaCode);
|
const byIvaCode = compareMaybeCodeNoneFirst(a.ivaCode, b.ivaCode);
|
||||||
if (byIvaCode !== 0) return byIvaCode;
|
if (byIvaCode !== 0) return byIvaCode;
|
||||||
|
|
||||||
const byIvaPct = comparePct(a.ivaPercentage, b.ivaPercentage);
|
const byIvaPct = compareMaybePctNoneFirst(a.ivaPercentage, b.ivaPercentage);
|
||||||
if (byIvaPct !== 0) return byIvaPct;
|
if (byIvaPct !== 0) return byIvaPct;
|
||||||
|
|
||||||
const byRecCode = compareMaybeCodeNoneFirst(a.recCode, b.recCode);
|
const byRecCode = compareMaybeCodeNoneFirst(a.recCode, b.recCode);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { TaxPercentage } from "@erp/core/api";
|
import type { Tax, TaxPercentage } from "@erp/core/api";
|
||||||
import { Maybe } from "@repo/rdx-utils";
|
import { Maybe } from "@repo/rdx-utils";
|
||||||
|
|
||||||
import { type InvoiceAmount, ItemAmount } from "../../common";
|
import { type InvoiceAmount, ItemAmount } from "../../common";
|
||||||
@ -7,8 +7,8 @@ import type { IProformaItems } from "../entities";
|
|||||||
type TaxGroupState = {
|
type TaxGroupState = {
|
||||||
taxableAmount: ItemAmount;
|
taxableAmount: ItemAmount;
|
||||||
|
|
||||||
ivaCode: string;
|
ivaCode: Maybe<string>;
|
||||||
ivaPercentage: TaxPercentage;
|
ivaPercentage: Maybe<TaxPercentage>;
|
||||||
ivaAmount: ItemAmount;
|
ivaAmount: ItemAmount;
|
||||||
|
|
||||||
recCode: Maybe<string>;
|
recCode: Maybe<string>;
|
||||||
@ -33,7 +33,7 @@ export function proformaComputeTaxGroups(items: IProformaItems): Map<string, Tax
|
|||||||
const currency = items.currencyCode;
|
const currency = items.currencyCode;
|
||||||
|
|
||||||
for (const item of items.valued()) {
|
for (const item of items.valued()) {
|
||||||
const iva = item.taxes.iva.unwrap(); // siempre existe
|
const iva = item.taxes.iva;
|
||||||
const rec = item.taxes.rec;
|
const rec = item.taxes.rec;
|
||||||
const retention = item.taxes.retention;
|
const retention = item.taxes.retention;
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ export function proformaComputeTaxGroups(items: IProformaItems): Map<string, Tax
|
|||||||
map.set(key, {
|
map.set(key, {
|
||||||
taxableAmount: ItemAmount.zero(currency.code),
|
taxableAmount: ItemAmount.zero(currency.code),
|
||||||
|
|
||||||
ivaCode: iva.code,
|
ivaCode: iva.isSome() ? Maybe.some(iva.unwrap().code) : Maybe.none(),
|
||||||
ivaPercentage: iva.percentage,
|
ivaPercentage: iva.isSome() ? Maybe.some(iva.unwrap().percentage) : Maybe.none(),
|
||||||
ivaAmount: ItemAmount.zero(currency.code),
|
ivaAmount: ItemAmount.zero(currency.code),
|
||||||
|
|
||||||
recCode: rec.isSome() ? Maybe.some(rec.unwrap().code) : Maybe.none(),
|
recCode: rec.isSome() ? Maybe.some(rec.unwrap().code) : Maybe.none(),
|
||||||
@ -71,12 +71,10 @@ export function proformaComputeTaxGroups(items: IProformaItems): Map<string, Tax
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTaxGroupKey(iva: any, rec: any, retention: any): string {
|
function buildTaxGroupKey(iva: Maybe<Tax>, rec: Maybe<Tax>, retention: Maybe<Tax>): string {
|
||||||
const recPart = rec.isSome() ? `${rec.unwrap().code}-${rec.unwrap().percentage.value}` : "NULL";
|
const ivaPart = iva.isSome() ? `${iva.unwrap().code}` : "NULL";
|
||||||
|
const recPart = rec.isSome() ? `${rec.unwrap().code}` : "NULL";
|
||||||
|
const retentionPart = retention.isSome() ? `${retention.unwrap().code}` : "NULL";
|
||||||
|
|
||||||
const retentionPart = retention.isSome()
|
return `${ivaPart}|${recPart}|${retentionPart}`;
|
||||||
? `${retention.unwrap().code}-${retention.unwrap().percentage.value}`
|
|
||||||
: "NULL";
|
|
||||||
|
|
||||||
return `${iva.code}-${iva.percentage.value}|${recPart}|${retentionPart}`;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import { proformaComputeTaxGroups } from "./proforma-compute-tax-groups";
|
|||||||
export interface IProformaTaxTotals {
|
export interface IProformaTaxTotals {
|
||||||
taxableAmount: InvoiceAmount;
|
taxableAmount: InvoiceAmount;
|
||||||
|
|
||||||
ivaCode: string;
|
ivaCode: Maybe<string>;
|
||||||
ivaPercentage: TaxPercentage;
|
ivaPercentage: Maybe<TaxPercentage>;
|
||||||
ivaAmount: InvoiceAmount;
|
ivaAmount: InvoiceAmount;
|
||||||
|
|
||||||
recCode: Maybe<string>;
|
recCode: Maybe<string>;
|
||||||
|
|||||||
@ -16,6 +16,12 @@ export interface IProformaItemTaxes {
|
|||||||
retention: Maybe<Tax>; // si existe
|
retention: Maybe<Tax>; // si existe
|
||||||
|
|
||||||
toKey(): string; // Clave para representar un trío.
|
toKey(): string; // Clave para representar un trío.
|
||||||
|
|
||||||
|
totals(taxableAmount: ItemAmount): {
|
||||||
|
ivaAmount: ItemAmount;
|
||||||
|
recAmount: ItemAmount;
|
||||||
|
retentionAmount: ItemAmount;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProformaItemTaxes
|
export class ProformaItemTaxes
|
||||||
@ -45,7 +51,7 @@ export class ProformaItemTaxes
|
|||||||
return `${ivaCode};${recCode};${retentionCode}`;
|
return `${ivaCode};${recCode};${retentionCode}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateAmounts(taxableAmount: ItemAmount) {
|
totals(taxableAmount: ItemAmount) {
|
||||||
const ivaAmount = this.props.iva.match(
|
const ivaAmount = this.props.iva.match(
|
||||||
(iva) => taxableAmount.percentage(iva.percentage),
|
(iva) => taxableAmount.percentage(iva.percentage),
|
||||||
() => ItemAmount.zero(taxableAmount.currencyCode)
|
() => ItemAmount.zero(taxableAmount.currencyCode)
|
||||||
|
|||||||
@ -2,11 +2,14 @@ import type { IModuleServer } from "@erp/core/api";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
type IssuedInvoicesInternalDeps,
|
type IssuedInvoicesInternalDeps,
|
||||||
|
buildIssuedInvoiceServices,
|
||||||
buildIssuedInvoicesDependencies,
|
buildIssuedInvoicesDependencies,
|
||||||
buildProformaServices,
|
buildProformaServices,
|
||||||
|
buildProformasDependencies,
|
||||||
models,
|
models,
|
||||||
} from "./infrastructure";
|
} from "./infrastructure";
|
||||||
import { issuedInvoicesRouter } from "./infrastructure/express";
|
import { issuedInvoicesRouter } from "./infrastructure/express";
|
||||||
|
import { proformasRouter } from './infrastructure/express';
|
||||||
|
|
||||||
export const customerInvoicesAPIModule: IModuleServer = {
|
export const customerInvoicesAPIModule: IModuleServer = {
|
||||||
name: "customer-invoices",
|
name: "customer-invoices",
|
||||||
@ -25,11 +28,11 @@ export const customerInvoicesAPIModule: IModuleServer = {
|
|||||||
|
|
||||||
// 1) Dominio interno
|
// 1) Dominio interno
|
||||||
const issuedInvoicesInternalDeps = buildIssuedInvoicesDependencies(params);
|
const issuedInvoicesInternalDeps = buildIssuedInvoicesDependencies(params);
|
||||||
//const proformasInternalDeps = buildProformasDependencies(params);
|
const proformasInternalDeps = buildProformasDependencies(params);
|
||||||
|
|
||||||
// 2) Servicios públicos (Application Services)
|
// 2) Servicios públicos (Application Services)
|
||||||
const issuedInvoicesServices = buildProformaServices(issuedInvoicesInternalDeps);
|
const issuedInvoicesServices = buildIssuedInvoiceServices(issuedInvoicesInternalDeps);
|
||||||
//const proformasServices = buildProformasServices(proformasInternalDeps);
|
const proformasServices = buildProformaServices(proformasInternalDeps);
|
||||||
|
|
||||||
logger.info("🚀 CustomerInvoices module dependencies registered", { label: this.name });
|
logger.info("🚀 CustomerInvoices module dependencies registered", { label: this.name });
|
||||||
|
|
||||||
@ -40,13 +43,13 @@ export const customerInvoicesAPIModule: IModuleServer = {
|
|||||||
// Servicios expuestos a otros módulos
|
// Servicios expuestos a otros módulos
|
||||||
services: {
|
services: {
|
||||||
issuedInvoices: issuedInvoicesServices,
|
issuedInvoices: issuedInvoicesServices,
|
||||||
//proformas: proformasServices
|
proformas: proformasServices
|
||||||
},
|
},
|
||||||
|
|
||||||
// Implementación privada del módulo
|
// Implementación privada del módulo
|
||||||
internal: {
|
internal: {
|
||||||
issuedInvoices: issuedInvoicesInternalDeps,
|
issuedInvoices: issuedInvoicesInternalDeps,
|
||||||
//proformas: proformasInternalDeps
|
proformas: proformasInternalDeps
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -66,11 +69,12 @@ export const customerInvoicesAPIModule: IModuleServer = {
|
|||||||
"customer-invoices",
|
"customer-invoices",
|
||||||
"issuedInvoices"
|
"issuedInvoices"
|
||||||
);
|
);
|
||||||
//const proformasInternalDeps = getInternal("customer-invoices", "proformas");
|
|
||||||
|
const proformasInternalDeps = getInternal("customer-invoices", "proformas");
|
||||||
|
|
||||||
// Registro de rutas HTTP
|
// Registro de rutas HTTP
|
||||||
issuedInvoicesRouter(params, issuedInvoicesInternalDeps);
|
issuedInvoicesRouter(params, issuedInvoicesInternalDeps);
|
||||||
//proformasRouter(params, proformasInternalDeps);
|
proformasRouter(params, proformasInternalDeps);
|
||||||
|
|
||||||
logger.info("🚀 CustomerInvoices module started", {
|
logger.info("🚀 CustomerInvoices module started", {
|
||||||
label: this.name,
|
label: this.name,
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export class CustomerInvoiceItemModel extends Model<
|
|||||||
declare item_discount_amount_scale: number;
|
declare item_discount_amount_scale: number;
|
||||||
|
|
||||||
// Porcentaje de descuento global proporcional a esta línea.
|
// Porcentaje de descuento global proporcional a esta línea.
|
||||||
declare global_discount_percentage_value: CreationOptional<number | null>;
|
declare global_discount_percentage_value: number;
|
||||||
declare global_discount_percentage_scale: number;
|
declare global_discount_percentage_scale: number;
|
||||||
|
|
||||||
// Importe del descuento global para esta línea
|
// Importe del descuento global para esta línea
|
||||||
@ -210,8 +210,8 @@ export default (database: Sequelize) => {
|
|||||||
|
|
||||||
global_discount_percentage_value: {
|
global_discount_percentage_value: {
|
||||||
type: new DataTypes.SMALLINT(),
|
type: new DataTypes.SMALLINT(),
|
||||||
allowNull: true,
|
allowNull: false,
|
||||||
defaultValue: null,
|
defaultValue: 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
global_discount_percentage_scale: {
|
global_discount_percentage_scale: {
|
||||||
|
|||||||
@ -29,9 +29,9 @@ export class CustomerInvoiceTaxModel extends Model<
|
|||||||
// Código de impuestos
|
// Código de impuestos
|
||||||
|
|
||||||
// IVA percentage
|
// IVA percentage
|
||||||
declare iva_code: string;
|
declare iva_code: CreationOptional<string | null>;
|
||||||
|
|
||||||
declare iva_percentage_value: number;
|
declare iva_percentage_value: CreationOptional<number | null>;
|
||||||
declare iva_percentage_scale: number;
|
declare iva_percentage_scale: number;
|
||||||
|
|
||||||
// IVA amount
|
// IVA amount
|
||||||
@ -124,6 +124,7 @@ export default (database: Sequelize) => {
|
|||||||
allowNull: true,
|
allowNull: true,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
iva_percentage_value: {
|
iva_percentage_value: {
|
||||||
type: DataTypes.SMALLINT,
|
type: DataTypes.SMALLINT,
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
|
|||||||
@ -73,7 +73,7 @@ export class CustomerInvoiceModel extends Model<
|
|||||||
declare items_discount_amount_scale: number;
|
declare items_discount_amount_scale: number;
|
||||||
|
|
||||||
// Global/header discount percentage
|
// Global/header discount percentage
|
||||||
declare global_discount_percentage_value: CreationOptional<number | null>;
|
declare global_discount_percentage_value: number;
|
||||||
declare global_discount_percentage_scale: number;
|
declare global_discount_percentage_scale: number;
|
||||||
|
|
||||||
// Global/header discount amount
|
// Global/header discount amount
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
export * from "./issued-invoices";
|
export * from "./issued-invoices";
|
||||||
//export * from "./proformas";
|
export * from "./proformas";
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
export * from "../../issued-invoices/express";
|
export * from "../../issued-invoices/express/controllers";
|
||||||
|
export * from "../../issued-invoices/express/issued-invoices.routes";
|
||||||
export * from "./issued-invoices.routes";
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
export * from "../../proformas/express";
|
export * from "../../proformas/express/controllers";
|
||||||
|
|
||||||
export * from "./proformas.routes";
|
export * from "./proformas.routes";
|
||||||
export * from "./proformas-api-error-mapper";
|
export * from "./proformas-api-error-mapper";
|
||||||
|
|||||||
@ -2,35 +2,18 @@ import { mockUser, requireAuthenticated, requireCompanyContext } from "@erp/auth
|
|||||||
import { type ModuleParams, type RequestWithAuth, validateRequest } from "@erp/core/api";
|
import { type ModuleParams, type RequestWithAuth, validateRequest } from "@erp/core/api";
|
||||||
import { type NextFunction, type Request, type Response, Router } from "express";
|
import { type NextFunction, type Request, type Response, Router } from "express";
|
||||||
|
|
||||||
|
import { GetProformaByIdRequestSchema, ListProformasRequestSchema } from "../../../../common";
|
||||||
import {
|
import {
|
||||||
ChangeStatusProformaByIdParamsRequestSchema,
|
|
||||||
ChangeStatusProformaByIdRequestSchema,
|
|
||||||
CreateProformaRequestSchema,
|
|
||||||
DeleteProformaByIdParamsRequestSchema,
|
|
||||||
GetProformaByIdRequestSchema,
|
|
||||||
IssueProformaByIdParamsRequestSchema,
|
|
||||||
ListProformasRequestSchema,
|
|
||||||
ReportProformaByIdParamsRequestSchema,
|
|
||||||
ReportProformaByIdQueryRequestSchema,
|
|
||||||
UpdateProformaByIdParamsRequestSchema,
|
|
||||||
UpdateProformaByIdRequestSchema,
|
|
||||||
} from "../../../../common";
|
|
||||||
import type { IssuedInvoicesInternalDeps } from "../../issued-invoices/di";
|
|
||||||
import {
|
|
||||||
ChangeStatusProformaController,
|
|
||||||
CreateProformaController,
|
|
||||||
DeleteProformaController,
|
|
||||||
GetProformaController,
|
GetProformaController,
|
||||||
IssueProformaController as IssuedProformaController,
|
|
||||||
ListProformasController,
|
ListProformasController,
|
||||||
ReportProformaController,
|
type ProformasInternalDeps,
|
||||||
UpdateProformaController,
|
} from "../../proformas";
|
||||||
} from "../../proformas/express";
|
|
||||||
|
|
||||||
export const proformasRouter = (params: ModuleParams, deps: IssuedInvoicesInternalDeps) => {
|
export const proformasRouter = (params: ModuleParams, deps: ProformasInternalDeps) => {
|
||||||
const { app, config } = params;
|
const { app, config } = params;
|
||||||
|
|
||||||
const router: Router = Router({ mergeParams: true });
|
const router: Router = Router({ mergeParams: true });
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||||
// 🔐 Autenticación + Tenancy para TODO el router
|
// 🔐 Autenticación + Tenancy para TODO el router
|
||||||
router.use(
|
router.use(
|
||||||
@ -54,7 +37,7 @@ export const proformasRouter = (params: ModuleParams, deps: IssuedInvoicesIntern
|
|||||||
//checkTabContext,
|
//checkTabContext,
|
||||||
validateRequest(ListProformasRequestSchema, "params"),
|
validateRequest(ListProformasRequestSchema, "params"),
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
const useCase = deps.useCases.listIssuedInvoices();
|
const useCase = deps.useCases.listProformas();
|
||||||
const controller = new ListProformasController(useCase /*, deps.presenters.list */);
|
const controller = new ListProformasController(useCase /*, deps.presenters.list */);
|
||||||
return controller.execute(req, res, next);
|
return controller.execute(req, res, next);
|
||||||
}
|
}
|
||||||
@ -65,13 +48,13 @@ export const proformasRouter = (params: ModuleParams, deps: IssuedInvoicesIntern
|
|||||||
//checkTabContext,
|
//checkTabContext,
|
||||||
validateRequest(GetProformaByIdRequestSchema, "params"),
|
validateRequest(GetProformaByIdRequestSchema, "params"),
|
||||||
(req: Request, res: Response, next: NextFunction) => {
|
(req: Request, res: Response, next: NextFunction) => {
|
||||||
const useCase = deps.useCases.getIssuedInvoiceById();
|
const useCase = deps.useCases.getProformaById();
|
||||||
const controller = new GetProformaController(useCase);
|
const controller = new GetProformaController(useCase);
|
||||||
return controller.execute(req, res, next);
|
return controller.execute(req, res, next);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
/*router.post(
|
||||||
"/",
|
"/",
|
||||||
//checkTabContext,
|
//checkTabContext,
|
||||||
|
|
||||||
@ -145,7 +128,7 @@ export const proformasRouter = (params: ModuleParams, deps: IssuedInvoicesIntern
|
|||||||
const controller = new IssuedProformaController(useCase);
|
const controller = new IssuedProformaController(useCase);
|
||||||
return controller.execute(req, res, next);
|
return controller.execute(req, res, next);
|
||||||
}
|
}
|
||||||
);
|
);*/
|
||||||
|
|
||||||
app.use(`${config.server.apiBasePath}/proformas`, router);
|
app.use(`${config.server.apiBasePath}/proformas`, router);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,9 +5,9 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import { GetIssuedInvoiceByIdResponseSchema } from "../../../../common/index.ts";
|
import { GetIssuedInvoiceByIdResponseSchema } from "../../../../../common/index.ts";
|
||||||
import type { GetIssuedInvoiceByIdUseCase } from "../../../application/issued-invoices/index.ts";
|
import type { GetIssuedInvoiceByIdUseCase } from "../../../../application/issued-invoices/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class GetIssuedInvoiceByIdController extends ExpressController {
|
export class GetIssuedInvoiceByIdController extends ExpressController {
|
||||||
public constructor(private readonly useCase: GetIssuedInvoiceByIdUseCase) {
|
public constructor(private readonly useCase: GetIssuedInvoiceByIdUseCase) {
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
export * from "./get-issued-invoice-by-id.controller";
|
||||||
|
export * from "./list-issued-invoices.controller";
|
||||||
|
export * from "./report-issued-invoice.controller";
|
||||||
@ -6,9 +6,9 @@ import {
|
|||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { Criteria } from "@repo/rdx-criteria/server";
|
import { Criteria } from "@repo/rdx-criteria/server";
|
||||||
|
|
||||||
import { ListIssuedInvoicesResponseSchema } from "../../../../common/index.ts";
|
import { ListIssuedInvoicesResponseSchema } from "../../../../../common/index.ts";
|
||||||
import type { ListIssuedInvoicesUseCase } from "../../../application/issued-invoices/index.ts";
|
import type { ListIssuedInvoicesUseCase } from "../../../../application/issued-invoices/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class ListIssuedInvoicesController extends ExpressController {
|
export class ListIssuedInvoicesController extends ExpressController {
|
||||||
public constructor(private readonly useCase: ListIssuedInvoicesUseCase) {
|
public constructor(private readonly useCase: ListIssuedInvoicesUseCase) {
|
||||||
@ -7,8 +7,8 @@ import {
|
|||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import type { ReportIssueInvoiceByIdQueryRequestDTO } from "@erp/customer-invoices/common";
|
import type { ReportIssueInvoiceByIdQueryRequestDTO } from "@erp/customer-invoices/common";
|
||||||
|
|
||||||
import type { ReportIssuedInvoiceUseCase } from "../../../application/index.ts";
|
import type { ReportIssuedInvoiceUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class ReportIssuedInvoiceController extends ExpressController {
|
export class ReportIssuedInvoiceController extends ExpressController {
|
||||||
public constructor(private readonly useCase: ReportIssuedInvoiceUseCase) {
|
public constructor(private readonly useCase: ReportIssuedInvoiceUseCase) {
|
||||||
@ -1,3 +1,2 @@
|
|||||||
export * from "./get-issued-invoice-by-id.controller";
|
export * from "./controllers";
|
||||||
export * from "./list-issued-invoices.controller";
|
export * from "./issued-invoices.routes";
|
||||||
export * from "./report-issued-invoice.controller";
|
|
||||||
|
|||||||
@ -7,18 +7,20 @@ import {
|
|||||||
ListIssuedInvoicesRequestSchema,
|
ListIssuedInvoicesRequestSchema,
|
||||||
ReportIssueInvoiceByIdParamsRequestSchema,
|
ReportIssueInvoiceByIdParamsRequestSchema,
|
||||||
ReportIssueInvoiceByIdQueryRequestSchema,
|
ReportIssueInvoiceByIdQueryRequestSchema,
|
||||||
} from "../../../../common/dto";
|
} from "../../../../common";
|
||||||
|
import type { IssuedInvoicesInternalDeps } from "../../issued-invoices/di";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GetIssuedInvoiceByIdController,
|
GetIssuedInvoiceByIdController,
|
||||||
|
ListIssuedInvoicesController,
|
||||||
ReportIssuedInvoiceController,
|
ReportIssuedInvoiceController,
|
||||||
} from "../../issued-invoices";
|
} from "./controllers";
|
||||||
import type { IssuedInvoicesInternalDeps } from "../../issued-invoices/di";
|
|
||||||
import { ListIssuedInvoicesController } from "../../issued-invoices/express/list-issued-invoices.controller";
|
|
||||||
|
|
||||||
export const issuedInvoicesRouter = (params: ModuleParams, deps: IssuedInvoicesInternalDeps) => {
|
export const issuedInvoicesRouter = (params: ModuleParams, deps: IssuedInvoicesInternalDeps) => {
|
||||||
const { app, config } = params;
|
const { app, config } = params;
|
||||||
|
|
||||||
const router: Router = Router({ mergeParams: true });
|
const router: Router = Router({ mergeParams: true });
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "production") {
|
||||||
// 🔐 Autenticación + Tenancy para TODO el router
|
// 🔐 Autenticación + Tenancy para TODO el router
|
||||||
router.use(
|
router.use(
|
||||||
@ -29,7 +29,7 @@ export type ProformasInternalDeps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function buildProformasDependencies(params: ModuleParams): ProformasInternalDeps {
|
export function buildProformasDependencies(params: ModuleParams): ProformasInternalDeps {
|
||||||
const { database, env } = params;
|
const { database } = params;
|
||||||
|
|
||||||
// Infrastructure
|
// Infrastructure
|
||||||
const transactionManager = buildTransactionManager(database);
|
const transactionManager = buildTransactionManager(database);
|
||||||
@ -37,10 +37,8 @@ export function buildProformasDependencies(params: ModuleParams): ProformasInter
|
|||||||
//const numberService = buildProformaNumberGenerator();
|
//const numberService = buildProformaNumberGenerator();
|
||||||
|
|
||||||
// Application helpers
|
// Application helpers
|
||||||
|
|
||||||
const finder = buildProformaFinder(repository);
|
const finder = buildProformaFinder(repository);
|
||||||
//const creator = buildProformaCreator(numberService, repository);
|
//const creator = buildProformaCreator(numberService, repository);
|
||||||
|
|
||||||
const snapshotBuilders = buildProformaSnapshotBuilders();
|
const snapshotBuilders = buildProformaSnapshotBuilders();
|
||||||
const documentGeneratorPipeline = buildproformaDocumentService(params);
|
const documentGeneratorPipeline = buildproformaDocumentService(params);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { ChangeStatusProformaByIdRequestDTO } from "../../../../common/dto/index.ts";
|
import type { ChangeStatusProformaByIdRequestDTO } from "../../../../../common/dto/index.ts";
|
||||||
|
|
||||||
export class ChangeStatusProformaController extends ExpressController {
|
export class ChangeStatusProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: ChangeStatusProformaUseCase) {
|
public constructor(private readonly useCase: ChangeStatusProformaUseCase) {
|
||||||
@ -5,9 +5,9 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { CreateProformaRequestDTO } from "../../../../common/dto/index.ts";
|
import type { CreateProformaRequestDTO } from "../../../../../common/dto/index.ts";
|
||||||
import type { CreateProformaUseCase } from "../../../application/index.ts";
|
import type { CreateProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class CreateProformaController extends ExpressController {
|
export class CreateProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: CreateProformaUseCase) {
|
public constructor(private readonly useCase: CreateProformaUseCase) {
|
||||||
@ -5,8 +5,8 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { DeleteProformaUseCase } from "../../../application/index.ts";
|
import type { DeleteProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class DeleteProformaController extends ExpressController {
|
export class DeleteProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: DeleteProformaUseCase) {
|
public constructor(private readonly useCase: DeleteProformaUseCase) {
|
||||||
@ -5,8 +5,8 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { GetProformaUseCase } from "../../../application/index.ts";
|
import type { GetProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class GetProformaController extends ExpressController {
|
export class GetProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: GetProformaUseCase) {
|
public constructor(private readonly useCase: GetProformaUseCase) {
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
//export * from "./change-status-proforma.controller";
|
||||||
|
//export * from "./create-proforma.controller";
|
||||||
|
//export * from "./delete-proforma.controller";
|
||||||
|
export * from "./get-proforma.controller";
|
||||||
|
//export * from "./issue-proforma.controller";
|
||||||
|
export * from "./list-proformas.controller";
|
||||||
|
export * from "./report-proforma.controller";
|
||||||
|
//export * from "./update-proforma.controller";
|
||||||
@ -5,8 +5,8 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { IssueProformaUseCase } from "../../../application/index.ts";
|
import type { IssueProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class IssueProformaController extends ExpressController {
|
export class IssueProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: IssueProformaUseCase) {
|
public constructor(private readonly useCase: IssueProformaUseCase) {
|
||||||
@ -6,8 +6,8 @@ import {
|
|||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { Criteria } from "@repo/rdx-criteria/server";
|
import { Criteria } from "@repo/rdx-criteria/server";
|
||||||
|
|
||||||
import type { ListProformasUseCase } from "../../../application/index.ts";
|
import type { ListProformasUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class ListProformasController extends ExpressController {
|
export class ListProformasController extends ExpressController {
|
||||||
public constructor(private readonly useCase: ListProformasUseCase) {
|
public constructor(private readonly useCase: ListProformasUseCase) {
|
||||||
@ -5,8 +5,8 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { ReportProformaUseCase } from "../../../application/index.ts";
|
import type { ReportProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class ReportProformaController extends ExpressController {
|
export class ReportProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: ReportProformaUseCase) {
|
public constructor(private readonly useCase: ReportProformaUseCase) {
|
||||||
@ -5,9 +5,9 @@ import {
|
|||||||
requireCompanyContextGuard,
|
requireCompanyContextGuard,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
|
|
||||||
import type { UpdateProformaByIdRequestDTO } from "../../../../common/dto/index.ts";
|
import type { UpdateProformaByIdRequestDTO } from "../../../../../common/dto/index.ts";
|
||||||
import type { UpdateProformaUseCase } from "../../../application/index.ts";
|
import type { UpdateProformaUseCase } from "../../../../application/index.ts";
|
||||||
import { customerInvoicesApiErrorMapper } from "../../express/proformas/proformas-api-error-mapper.ts";
|
import { customerInvoicesApiErrorMapper } from "../../../express/proformas/proformas-api-error-mapper.ts";
|
||||||
|
|
||||||
export class UpdateProformaController extends ExpressController {
|
export class UpdateProformaController extends ExpressController {
|
||||||
public constructor(private readonly useCase: UpdateProformaUseCase) {
|
public constructor(private readonly useCase: UpdateProformaUseCase) {
|
||||||
@ -1,8 +1 @@
|
|||||||
//export * from "./change-status-proforma.controller";
|
export * from "./controllers";
|
||||||
//export * from "./create-proforma.controller";
|
|
||||||
//export * from "./delete-proforma.controller";
|
|
||||||
export * from "./get-proforma.controller";
|
|
||||||
//export * from "./issue-proforma.controller";
|
|
||||||
export * from "./list-proformas.controller";
|
|
||||||
export * from "./report-proforma.controller";
|
|
||||||
//export * from "./update-proforma.controller";
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api";
|
import { DiscountPercentage, type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api";
|
||||||
import {
|
import {
|
||||||
CurrencyCode,
|
CurrencyCode,
|
||||||
LanguageCode,
|
LanguageCode,
|
||||||
@ -15,7 +15,6 @@ import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils";
|
|||||||
|
|
||||||
import type { IProformaDomainMapper } from "../../../../../../application";
|
import type { IProformaDomainMapper } from "../../../../../../application";
|
||||||
import {
|
import {
|
||||||
DiscountPercentage,
|
|
||||||
InvoiceNumber,
|
InvoiceNumber,
|
||||||
InvoicePaymentMethod,
|
InvoicePaymentMethod,
|
||||||
InvoiceSerie,
|
InvoiceSerie,
|
||||||
@ -191,14 +190,14 @@ export class SequelizeProformaDomainMapper
|
|||||||
// 2) Recipient (snapshot en la factura o include)
|
// 2) Recipient (snapshot en la factura o include)
|
||||||
const recipientResult = this._recipientMapper.mapToDomain(raw, {
|
const recipientResult = this._recipientMapper.mapToDomain(raw, {
|
||||||
errors,
|
errors,
|
||||||
attributes,
|
parent: attributes,
|
||||||
...params,
|
...params,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3) Items (colección)
|
// 3) Items (colección)
|
||||||
const itemsResults = this._itemsMapper.mapToDomainCollection(raw.items, raw.items.length, {
|
const itemsResults = this._itemsMapper.mapToDomainCollection(raw.items, raw.items.length, {
|
||||||
errors,
|
errors,
|
||||||
attributes,
|
parent: attributes,
|
||||||
...params,
|
...params,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -281,7 +280,7 @@ export class SequelizeProformaDomainMapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2) Taxes
|
// 2) Taxes
|
||||||
const taxesResult = this._taxesMapper.mapToPersistenceArray(source.getTaxes(), {
|
const taxesResult = this._taxesMapper.mapToPersistenceArray(source.taxes(), {
|
||||||
errors,
|
errors,
|
||||||
parent: source,
|
parent: source,
|
||||||
...params,
|
...params,
|
||||||
@ -311,7 +310,7 @@ export class SequelizeProformaDomainMapper
|
|||||||
const items = itemsResult.data;
|
const items = itemsResult.data;
|
||||||
const taxes = taxesResult.data;
|
const taxes = taxesResult.data;
|
||||||
|
|
||||||
const allAmounts = source.calculateAllAmounts(); // Da los totales ya calculados
|
const allAmounts = source.totals(); // Da los totales ya calculados
|
||||||
|
|
||||||
const invoiceValues: Partial<CustomerInvoiceCreationAttributes> = {
|
const invoiceValues: Partial<CustomerInvoiceCreationAttributes> = {
|
||||||
// Identificación
|
// Identificación
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
import type { JsonTaxCatalogProvider } from "@erp/core";
|
import type { JsonTaxCatalogProvider } from "@erp/core";
|
||||||
import { type MapperParamsType, SequelizeDomainMapper, Tax } from "@erp/core/api";
|
import {
|
||||||
|
DiscountPercentage,
|
||||||
|
type MapperParamsType,
|
||||||
|
SequelizeDomainMapper,
|
||||||
|
Tax,
|
||||||
|
} from "@erp/core/api";
|
||||||
import {
|
import {
|
||||||
UniqueID,
|
UniqueID,
|
||||||
ValidationErrorCollection,
|
ValidationErrorCollection,
|
||||||
@ -13,12 +18,12 @@ import { Result } from "@repo/rdx-utils";
|
|||||||
import {
|
import {
|
||||||
ItemAmount,
|
ItemAmount,
|
||||||
ItemDescription,
|
ItemDescription,
|
||||||
ItemDiscountPercentage,
|
|
||||||
ItemQuantity,
|
ItemQuantity,
|
||||||
ItemTaxGroup,
|
|
||||||
type Proforma,
|
type Proforma,
|
||||||
ProformaItem,
|
ProformaItem,
|
||||||
type ProformaItemProps,
|
type ProformaItemProps,
|
||||||
|
ProformaItemTaxes,
|
||||||
|
type ProformaItemTaxesProps,
|
||||||
type ProformaProps,
|
type ProformaProps,
|
||||||
} from "../../../../../../domain";
|
} from "../../../../../../domain";
|
||||||
import type {
|
import type {
|
||||||
@ -47,75 +52,63 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private mapAttributesToDomain(
|
private mapAttributesToDomain(
|
||||||
source: CustomerInvoiceItemModel,
|
raw: CustomerInvoiceItemModel,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): Partial<ProformaItemProps> & { itemId?: UniqueID } {
|
): Partial<ProformaItemProps & ProformaItemTaxesProps> & { itemId?: UniqueID } {
|
||||||
const { errors, index, attributes } = params as {
|
const { errors, index, parent } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
errors: ValidationErrorDetail[];
|
errors: ValidationErrorDetail[];
|
||||||
attributes: Partial<ProformaProps>;
|
parent: Partial<ProformaProps>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const itemId = extractOrPushError(
|
const itemId = extractOrPushError(
|
||||||
UniqueID.create(source.item_id),
|
UniqueID.create(raw.item_id),
|
||||||
`items[${index}].item_id`,
|
`items[${index}].item_id`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const description = extractOrPushError(
|
const description = extractOrPushError(
|
||||||
maybeFromNullableResult(source.description, (v) => ItemDescription.create(v)),
|
maybeFromNullableResult(raw.description, (v) => ItemDescription.create(v)),
|
||||||
`items[${index}].description`,
|
`items[${index}].description`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const quantity = extractOrPushError(
|
const quantity = extractOrPushError(
|
||||||
maybeFromNullableResult(source.quantity_value, (v) => ItemQuantity.create({ value: v })),
|
maybeFromNullableResult(raw.quantity_value, (v) => ItemQuantity.create({ value: v })),
|
||||||
`items[${index}].quantity`,
|
`items[${index}].quantity`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const unitAmount = extractOrPushError(
|
const unitAmount = extractOrPushError(
|
||||||
maybeFromNullableResult(source.unit_amount_value, (value) =>
|
maybeFromNullableResult(raw.unit_amount_value, (value) =>
|
||||||
ItemAmount.create({ value, currency_code: attributes.currencyCode?.code })
|
ItemAmount.create({ value, currency_code: parent.currencyCode?.code })
|
||||||
),
|
),
|
||||||
`items[${index}].unit_amount`,
|
`items[${index}].unit_amount`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const discountPercentage = extractOrPushError(
|
const itemDiscountPercentage = extractOrPushError(
|
||||||
maybeFromNullableResult(source.discount_percentage_value, (v) =>
|
maybeFromNullableResult(raw.item_discount_percentage_value, (v) =>
|
||||||
ItemDiscountPercentage.create({ value: v })
|
DiscountPercentage.create({ value: v })
|
||||||
),
|
),
|
||||||
`items[${index}].discount_percentage`,
|
`items[${index}].item_discount_percentage`,
|
||||||
errors
|
|
||||||
);
|
|
||||||
|
|
||||||
const globalDiscountPercentage = extractOrPushError(
|
|
||||||
maybeFromNullableResult(source.global_discount_percentage_value, (v) =>
|
|
||||||
ItemDiscountPercentage.create({ value: v })
|
|
||||||
),
|
|
||||||
`items[${index}].discount_percentage`,
|
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const iva = extractOrPushError(
|
const iva = extractOrPushError(
|
||||||
maybeFromNullableResult(source.iva_code, (code) =>
|
maybeFromNullableResult(raw.iva_code, (code) => Tax.createFromCode(code, this._taxCatalog)),
|
||||||
Tax.createFromCode(code, this._taxCatalog)
|
|
||||||
),
|
|
||||||
`items[${index}].iva_code`,
|
`items[${index}].iva_code`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const rec = extractOrPushError(
|
const rec = extractOrPushError(
|
||||||
maybeFromNullableResult(source.rec_code, (code) =>
|
maybeFromNullableResult(raw.rec_code, (code) => Tax.createFromCode(code, this._taxCatalog)),
|
||||||
Tax.createFromCode(code, this._taxCatalog)
|
|
||||||
),
|
|
||||||
`items[${index}].rec_code`,
|
`items[${index}].rec_code`,
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const retention = extractOrPushError(
|
const retention = extractOrPushError(
|
||||||
maybeFromNullableResult(source.retention_code, (code) =>
|
maybeFromNullableResult(raw.retention_code, (code) =>
|
||||||
Tax.createFromCode(code, this._taxCatalog)
|
Tax.createFromCode(code, this._taxCatalog)
|
||||||
),
|
),
|
||||||
`items[${index}].retention_code`,
|
`items[${index}].retention_code`,
|
||||||
@ -125,34 +118,32 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
return {
|
return {
|
||||||
itemId,
|
itemId,
|
||||||
|
|
||||||
languageCode: attributes.languageCode,
|
languageCode: parent.languageCode,
|
||||||
currencyCode: attributes.currencyCode,
|
currencyCode: parent.currencyCode,
|
||||||
description,
|
description,
|
||||||
quantity,
|
quantity,
|
||||||
unitAmount,
|
unitAmount,
|
||||||
itemDiscountPercentage: discountPercentage,
|
itemDiscountPercentage,
|
||||||
globalDiscountPercentage,
|
globalDiscountPercentage: parent.globalDiscountPercentage,
|
||||||
|
|
||||||
taxes: ItemTaxGroup.create({
|
iva,
|
||||||
iva: iva!,
|
rec,
|
||||||
rec: rec!,
|
retention,
|
||||||
retention: retention!,
|
|
||||||
}).data,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public mapToDomain(
|
public mapToDomain(
|
||||||
source: CustomerInvoiceItemModel,
|
raw: CustomerInvoiceItemModel,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): Result<ProformaItem, Error> {
|
): Result<ProformaItem, Error> {
|
||||||
const { errors, index } = params as {
|
const { errors, index } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
errors: ValidationErrorDetail[];
|
errors: ValidationErrorDetail[];
|
||||||
attributes: Partial<ProformaProps>;
|
parent: Partial<ProformaProps>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 1) Valores escalares (atributos generales)
|
// 1) Valores escalares (atributos generales)
|
||||||
const attributes = this.mapAttributesToDomain(source, params);
|
const attributes = this.mapAttributesToDomain(raw, params);
|
||||||
|
|
||||||
// Si hubo errores de mapeo, devolvemos colección de validación
|
// Si hubo errores de mapeo, devolvemos colección de validación
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
@ -161,6 +152,13 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2) Construcción del elemento de taxes
|
||||||
|
const taxesResult = ProformaItemTaxes.create({
|
||||||
|
iva: attributes.iva!,
|
||||||
|
rec: attributes.rec!,
|
||||||
|
retention: attributes.retention!,
|
||||||
|
});
|
||||||
|
|
||||||
// 2) Construcción del elemento de dominio
|
// 2) Construcción del elemento de dominio
|
||||||
const createResult = ProformaItem.create(
|
const createResult = ProformaItem.create(
|
||||||
{
|
{
|
||||||
@ -171,7 +169,7 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
unitAmount: attributes.unitAmount!,
|
unitAmount: attributes.unitAmount!,
|
||||||
itemDiscountPercentage: attributes.itemDiscountPercentage!,
|
itemDiscountPercentage: attributes.itemDiscountPercentage!,
|
||||||
globalDiscountPercentage: attributes.globalDiscountPercentage!,
|
globalDiscountPercentage: attributes.globalDiscountPercentage!,
|
||||||
taxes: attributes.taxes!,
|
taxes: taxesResult.data,
|
||||||
},
|
},
|
||||||
attributes.itemId
|
attributes.itemId
|
||||||
);
|
);
|
||||||
@ -197,8 +195,7 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
errors: ValidationErrorDetail[];
|
errors: ValidationErrorDetail[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const allAmounts = source.calculateAllAmounts();
|
const allAmounts = source.totals();
|
||||||
const taxesAmounts = source.taxes.calculateAmounts(allAmounts.taxableAmount);
|
|
||||||
|
|
||||||
return Result.ok({
|
return Result.ok({
|
||||||
item_id: source.id.toPrimitive(),
|
item_id: source.id.toPrimitive(),
|
||||||
@ -221,26 +218,20 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
subtotal_amount_scale: allAmounts.subtotalAmount.scale,
|
subtotal_amount_scale: allAmounts.subtotalAmount.scale,
|
||||||
|
|
||||||
//
|
//
|
||||||
discount_percentage_value: maybeToNullable(
|
item_discount_percentage_value: maybeToNullable(
|
||||||
source.itemDiscountPercentage,
|
source.itemDiscountPercentage,
|
||||||
(v) => v.toPrimitive().value
|
(v) => v.toPrimitive().value
|
||||||
),
|
),
|
||||||
discount_percentage_scale:
|
item_discount_percentage_scale:
|
||||||
maybeToNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ??
|
maybeToNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ??
|
||||||
ItemDiscountPercentage.DEFAULT_SCALE,
|
DiscountPercentage.DEFAULT_SCALE,
|
||||||
|
|
||||||
discount_amount_value: allAmounts.itemDiscountAmount.value,
|
item_discount_amount_value: allAmounts.itemDiscountAmount.value,
|
||||||
discount_amount_scale: allAmounts.itemDiscountAmount.scale,
|
item_discount_amount_scale: allAmounts.itemDiscountAmount.scale,
|
||||||
|
|
||||||
//
|
//
|
||||||
global_discount_percentage_value: maybeToNullable(
|
global_discount_percentage_value: source.globalDiscountPercentage.value,
|
||||||
source.globalDiscountPercentage,
|
global_discount_percentage_scale: source.globalDiscountPercentage.scale,
|
||||||
(v) => v.toPrimitive().value
|
|
||||||
),
|
|
||||||
|
|
||||||
global_discount_percentage_scale:
|
|
||||||
maybeToNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ??
|
|
||||||
ItemDiscountPercentage.DEFAULT_SCALE,
|
|
||||||
|
|
||||||
global_discount_amount_value: allAmounts.globalDiscountAmount.value,
|
global_discount_amount_value: allAmounts.globalDiscountAmount.value,
|
||||||
global_discount_amount_scale: allAmounts.globalDiscountAmount.scale,
|
global_discount_amount_scale: allAmounts.globalDiscountAmount.scale,
|
||||||
@ -257,19 +248,21 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
iva_code: maybeToNullable(source.taxes.iva, (v) => v.code),
|
iva_code: maybeToNullable(source.taxes.iva, (v) => v.code),
|
||||||
|
|
||||||
iva_percentage_value: maybeToNullable(source.taxes.iva, (v) => v.percentage.value),
|
iva_percentage_value: maybeToNullable(source.taxes.iva, (v) => v.percentage.value),
|
||||||
iva_percentage_scale: maybeToNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2,
|
iva_percentage_scale:
|
||||||
|
maybeToNullable(source.taxes.iva, (v) => v.percentage.scale) ?? Tax.DEFAULT_SCALE,
|
||||||
|
|
||||||
iva_amount_value: taxesAmounts.ivaAmount.value,
|
iva_amount_value: allAmounts.ivaAmount.value,
|
||||||
iva_amount_scale: taxesAmounts.ivaAmount.scale,
|
iva_amount_scale: allAmounts.ivaAmount.scale,
|
||||||
|
|
||||||
// REC
|
// REC
|
||||||
rec_code: maybeToNullable(source.taxes.rec, (v) => v.code),
|
rec_code: maybeToNullable(source.taxes.rec, (v) => v.code),
|
||||||
|
|
||||||
rec_percentage_value: maybeToNullable(source.taxes.rec, (v) => v.percentage.value),
|
rec_percentage_value: maybeToNullable(source.taxes.rec, (v) => v.percentage.value),
|
||||||
rec_percentage_scale: maybeToNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2,
|
rec_percentage_scale:
|
||||||
|
maybeToNullable(source.taxes.rec, (v) => v.percentage.scale) ?? Tax.DEFAULT_SCALE,
|
||||||
|
|
||||||
rec_amount_value: taxesAmounts.recAmount.value,
|
rec_amount_value: allAmounts.recAmount.value,
|
||||||
rec_amount_scale: taxesAmounts.recAmount.scale,
|
rec_amount_scale: allAmounts.recAmount.scale,
|
||||||
|
|
||||||
// RET
|
// RET
|
||||||
retention_code: maybeToNullable(source.taxes.retention, (v) => v.code),
|
retention_code: maybeToNullable(source.taxes.retention, (v) => v.code),
|
||||||
@ -279,10 +272,10 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper<
|
|||||||
(v) => v.percentage.value
|
(v) => v.percentage.value
|
||||||
),
|
),
|
||||||
retention_percentage_scale:
|
retention_percentage_scale:
|
||||||
maybeToNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2,
|
maybeToNullable(source.taxes.retention, (v) => v.percentage.scale) ?? Tax.DEFAULT_SCALE,
|
||||||
|
|
||||||
retention_amount_value: taxesAmounts.retentionAmount.value,
|
retention_amount_value: allAmounts.retentionAmount.value,
|
||||||
retention_amount_scale: taxesAmounts.retentionAmount.scale,
|
retention_amount_scale: allAmounts.retentionAmount.scale,
|
||||||
|
|
||||||
//
|
//
|
||||||
taxes_amount_value: allAmounts.taxesAmount.value,
|
taxes_amount_value: allAmounts.taxesAmount.value,
|
||||||
|
|||||||
@ -26,20 +26,18 @@ export class SequelizeProformaRecipientDomainMapper {
|
|||||||
* En proforma -> datos de "current_customer"
|
* En proforma -> datos de "current_customer"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { errors, attributes } = params as {
|
const { errors, parent } = params as {
|
||||||
errors: ValidationErrorDetail[];
|
errors: ValidationErrorDetail[];
|
||||||
attributes: Partial<ProformaProps>;
|
parent: Partial<ProformaProps>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { isProforma } = attributes;
|
/* if (!source.current_customer) {
|
||||||
|
|
||||||
if (isProforma && !source.current_customer) {
|
|
||||||
errors.push({
|
errors.push({
|
||||||
path: "current_customer",
|
path: "current_customer",
|
||||||
message: "Current customer not included in query (SequelizeProformaRecipientDomainMapper)",
|
message: "Current customer not included in query (SequelizeProformaRecipientDomainMapper)",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
const _name = source.current_customer.name;
|
const _name = source.current_customer.name;
|
||||||
const _tin = source.current_customer.tin;
|
const _tin = source.current_customer.tin;
|
||||||
const _street = source.current_customer.street;
|
const _street = source.current_customer.street;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import type { JsonTaxCatalogProvider } from "@erp/core";
|
import type { JsonTaxCatalogProvider } from "@erp/core";
|
||||||
import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api";
|
import { type MapperParamsType, SequelizeDomainMapper, TaxPercentage } from "@erp/core/api";
|
||||||
import { UniqueID, type ValidationErrorDetail, maybeToNullable } from "@repo/rdx-ddd";
|
import { UniqueID, type ValidationErrorDetail, maybeToNullable } from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
|
|
||||||
import type { InvoiceTaxGroup, Proforma } from "../../../../../../domain";
|
import type { IProformaTaxTotals, Proforma } from "../../../../../../domain";
|
||||||
import type {
|
import type {
|
||||||
CustomerInvoiceTaxCreationAttributes,
|
CustomerInvoiceTaxCreationAttributes,
|
||||||
CustomerInvoiceTaxModel,
|
CustomerInvoiceTaxModel,
|
||||||
@ -24,7 +24,7 @@ import type {
|
|||||||
export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper<
|
export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper<
|
||||||
CustomerInvoiceTaxModel,
|
CustomerInvoiceTaxModel,
|
||||||
CustomerInvoiceTaxCreationAttributes,
|
CustomerInvoiceTaxCreationAttributes,
|
||||||
InvoiceTaxGroup
|
IProformaTaxTotals
|
||||||
> {
|
> {
|
||||||
private taxCatalog!: JsonTaxCatalogProvider;
|
private taxCatalog!: JsonTaxCatalogProvider;
|
||||||
|
|
||||||
@ -44,12 +44,12 @@ export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper<
|
|||||||
public mapToDomain(
|
public mapToDomain(
|
||||||
source: CustomerInvoiceTaxModel,
|
source: CustomerInvoiceTaxModel,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): Result<InvoiceTaxGroup, Error> {
|
): Result<IProformaTaxTotals, Error> {
|
||||||
throw new Error("Se calcula a partir de las líneas de detalle");
|
throw new Error("Se calcula a partir de las líneas de detalle");
|
||||||
}
|
}
|
||||||
|
|
||||||
public mapToPersistence(
|
public mapToPersistence(
|
||||||
source: InvoiceTaxGroup,
|
source: IProformaTaxTotals,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): Result<CustomerInvoiceTaxCreationAttributes, Error> {
|
): Result<CustomerInvoiceTaxCreationAttributes, Error> {
|
||||||
const { errors, parent } = params as {
|
const { errors, parent } = params as {
|
||||||
@ -58,10 +58,6 @@ export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper<
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { ivaAmount, recAmount, retentionAmount, totalAmount } = source.calculateAmounts();
|
|
||||||
|
|
||||||
const totalTaxes = totalAmount;
|
|
||||||
|
|
||||||
const dto: CustomerInvoiceTaxCreationAttributes = {
|
const dto: CustomerInvoiceTaxCreationAttributes = {
|
||||||
tax_id: UniqueID.generateNewID().toPrimitive(),
|
tax_id: UniqueID.generateNewID().toPrimitive(),
|
||||||
invoice_id: parent.id.toPrimitive(),
|
invoice_id: parent.id.toPrimitive(),
|
||||||
@ -71,36 +67,39 @@ export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper<
|
|||||||
taxable_amount_scale: source.taxableAmount.scale,
|
taxable_amount_scale: source.taxableAmount.scale,
|
||||||
|
|
||||||
// IVA
|
// IVA
|
||||||
iva_code: source.iva.code,
|
iva_code: maybeToNullable(source.ivaCode, (v) => v),
|
||||||
|
|
||||||
iva_percentage_value: source.iva.value,
|
iva_percentage_value: maybeToNullable(source.ivaPercentage, (v) => v.value),
|
||||||
iva_percentage_scale: source.iva.scale,
|
iva_percentage_scale:
|
||||||
|
maybeToNullable(source.ivaPercentage, (v) => v.scale) ?? TaxPercentage.DEFAULT_SCALE,
|
||||||
|
|
||||||
iva_amount_value: ivaAmount.value,
|
iva_amount_value: source.ivaAmount.value,
|
||||||
iva_amount_scale: ivaAmount.scale,
|
iva_amount_scale: source.ivaAmount.scale,
|
||||||
|
|
||||||
// REC
|
// REC
|
||||||
rec_code: maybeToNullable(source.rec, (v) => v.code),
|
rec_code: maybeToNullable(source.recCode, (v) => v),
|
||||||
|
|
||||||
rec_percentage_value: maybeToNullable(source.rec, (v) => v.percentage.value),
|
rec_percentage_value: maybeToNullable(source.recPercentage, (v) => v.value),
|
||||||
rec_percentage_scale: maybeToNullable(source.rec, (v) => v.percentage.scale) ?? 2,
|
rec_percentage_scale:
|
||||||
|
maybeToNullable(source.recPercentage, (v) => v.scale) ?? TaxPercentage.DEFAULT_SCALE,
|
||||||
|
|
||||||
rec_amount_value: recAmount.value,
|
rec_amount_value: source.recAmount.value,
|
||||||
rec_amount_scale: recAmount.scale,
|
rec_amount_scale: source.recAmount.scale,
|
||||||
|
|
||||||
// RET
|
// RET
|
||||||
retention_code: maybeToNullable(source.retention, (v) => v.code),
|
retention_code: maybeToNullable(source.retentionCode, (v) => v),
|
||||||
|
|
||||||
retention_percentage_value: maybeToNullable(source.retention, (v) => v.percentage.value),
|
retention_percentage_value: maybeToNullable(source.retentionPercentage, (v) => v.value),
|
||||||
retention_percentage_scale:
|
retention_percentage_scale:
|
||||||
maybeToNullable(source.retention, (v) => v.percentage.scale) ?? 2,
|
maybeToNullable(source.retentionPercentage, (v) => v.scale) ??
|
||||||
|
TaxPercentage.DEFAULT_SCALE,
|
||||||
|
|
||||||
retention_amount_value: retentionAmount.value,
|
retention_amount_value: source.retentionAmount.value,
|
||||||
retention_amount_scale: retentionAmount.scale,
|
retention_amount_scale: source.retentionAmount.scale,
|
||||||
|
|
||||||
// TOTAL
|
// TOTAL
|
||||||
taxes_amount_value: totalTaxes.value,
|
taxes_amount_value: source.taxesAmount.value,
|
||||||
taxes_amount_scale: totalTaxes.scale,
|
taxes_amount_scale: source.taxesAmount.scale,
|
||||||
};
|
};
|
||||||
|
|
||||||
return Result.ok(dto);
|
return Result.ok(dto);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user