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