Facturas de cliente
This commit is contained in:
parent
b7a58ebad5
commit
d40c2279bd
@ -5,7 +5,7 @@ import { Invoice } from "../aggregates";
|
|||||||
export interface IInvoiceRepository {
|
export interface IInvoiceRepository {
|
||||||
findAll(transaction?: any): Promise<Result<Collection<Invoice>, Error>>;
|
findAll(transaction?: any): Promise<Result<Collection<Invoice>, Error>>;
|
||||||
getById(id: UniqueID, transaction?: any): Promise<Result<Invoice, Error>>;
|
getById(id: UniqueID, transaction?: any): Promise<Result<Invoice, Error>>;
|
||||||
deleteById(id: UniqueID, transaction?: any): Promise<Result<boolean, Error>>;
|
deleteByIdInCompany(id: UniqueID, transaction?: any): Promise<Result<boolean, Error>>;
|
||||||
|
|
||||||
create(invoice: Invoice, transaction?: any): Promise<void>;
|
create(invoice: Invoice, transaction?: any): Promise<void>;
|
||||||
update(invoice: Invoice, transaction?: any): Promise<void>;
|
update(invoice: Invoice, transaction?: any): Promise<void>;
|
||||||
|
|||||||
@ -7,6 +7,9 @@ import { IInvoiceService } from "./invoice-service.interface";
|
|||||||
|
|
||||||
export class InvoiceService implements IInvoiceService {
|
export class InvoiceService implements IInvoiceService {
|
||||||
constructor(private readonly repo: IInvoiceRepository) {}
|
constructor(private readonly repo: IInvoiceRepository) {}
|
||||||
|
deleteInvoiceById(invoiceId: UniqueID, transaction?: any): Promise<Result<boolean, Error>> {
|
||||||
|
throw new Error("Method not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
async findInvoices(transaction?: Transaction): Promise<Result<Collection<Invoice>, Error>> {
|
async findInvoices(transaction?: Transaction): Promise<Result<Collection<Invoice>, Error>> {
|
||||||
const invoicesOrError = await this.repo.findAll(transaction);
|
const invoicesOrError = await this.repo.findAll(transaction);
|
||||||
@ -71,10 +74,11 @@ export class InvoiceService implements IInvoiceService {
|
|||||||
return Result.ok(newInvoice);
|
return Result.ok(newInvoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteInvoiceById(
|
async deleteInvoiceByIdInCompnay(
|
||||||
|
companyId: UniqueID,
|
||||||
invoiceId: UniqueID,
|
invoiceId: UniqueID,
|
||||||
transaction?: Transaction
|
transaction?: Transaction
|
||||||
): Promise<Result<boolean, Error>> {
|
): Promise<Result<boolean, Error>> {
|
||||||
return this.repo.deleteById(invoiceId, transaction);
|
return this.repo.deleteByIdInCompany(companyId, invoiceId, transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,35 @@
|
|||||||
|
import { Result } from "@repo/rdx-utils";
|
||||||
|
import { ILogger } from "../../logger";
|
||||||
import { ITransactionManager } from "./transaction-manager.interface";
|
import { ITransactionManager } from "./transaction-manager.interface";
|
||||||
|
|
||||||
export abstract class TransactionManager implements ITransactionManager {
|
export abstract class TransactionManager implements ITransactionManager {
|
||||||
protected _transaction: any | null = null;
|
protected _transaction: any | null = null;
|
||||||
|
protected _isCompleted = false;
|
||||||
|
protected readonly logger!: ILogger;
|
||||||
|
|
||||||
|
constructor(logger?: ILogger) {
|
||||||
|
// Si no hay logger, usa console adaptado
|
||||||
|
this.logger = logger ?? {
|
||||||
|
info: (msg, meta) => console.info(msg, meta),
|
||||||
|
warn: (msg, meta) => console.warn(msg, meta),
|
||||||
|
error: (msg, err) => console.error(msg, err),
|
||||||
|
debug: (msg, meta) => console.debug(msg, meta),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 🔹 Inicia una transacción si no hay una activa
|
* 🔹 Inicia una transacción si no hay una activa
|
||||||
*/
|
*/
|
||||||
async start(): Promise<void> {
|
async start(): Promise<void> {
|
||||||
if (!this._transaction) {
|
if (this._transaction) {
|
||||||
this._transaction = await this._startTransaction();
|
this.logger.error("❌ Transaction already started. Nested transactions are not allowed.", {
|
||||||
|
label: "TransactionManager.start",
|
||||||
|
});
|
||||||
|
throw new Error("A transaction is already active. Nested transactions are not allowed.");
|
||||||
}
|
}
|
||||||
|
this._transaction = await this._startTransaction();
|
||||||
|
this._isCompleted = false;
|
||||||
|
this.logger.debug("Transaction started", { label: "TransactionManager.start" });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,8 +37,16 @@ export abstract class TransactionManager implements ITransactionManager {
|
|||||||
*/
|
*/
|
||||||
getTransaction(): any {
|
getTransaction(): any {
|
||||||
if (!this._transaction) {
|
if (!this._transaction) {
|
||||||
|
this.logger.error("❌ No active transaction. Call start() first.", {
|
||||||
|
label: "TransactionManager.getTransaction",
|
||||||
|
});
|
||||||
throw new Error("No active transaction. Call start() first.");
|
throw new Error("No active transaction. Call start() first.");
|
||||||
}
|
}
|
||||||
|
if (this._isCompleted) {
|
||||||
|
this.logger.error("❌ Transaction already completed.");
|
||||||
|
throw new Error("Transaction already completed.");
|
||||||
|
}
|
||||||
|
|
||||||
return this._transaction;
|
return this._transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,13 +54,30 @@ export abstract class TransactionManager implements ITransactionManager {
|
|||||||
* 🔹 Ejecuta una función dentro de una transacción
|
* 🔹 Ejecuta una función dentro de una transacción
|
||||||
*/
|
*/
|
||||||
async complete<T>(work: (transaction: any) => Promise<T>): Promise<T> {
|
async complete<T>(work: (transaction: any) => Promise<T>): Promise<T> {
|
||||||
|
if (this._transaction) {
|
||||||
|
this.logger.error(
|
||||||
|
"❌ Cannot start a new transaction inside another. Nested transactions are not allowed.",
|
||||||
|
{ label: "TransactionManager.complete" }
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Error("A transaction is already active. Nested transactions are not allowed.");
|
||||||
|
}
|
||||||
|
|
||||||
await this.start();
|
await this.start();
|
||||||
try {
|
try {
|
||||||
const result = await work(this.getTransaction());
|
const result = await work(this.getTransaction());
|
||||||
|
if (result instanceof Result && result.isFailure) {
|
||||||
|
throw result.error;
|
||||||
|
}
|
||||||
await this.commit();
|
await this.commit();
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
await this.rollback();
|
await this.rollback();
|
||||||
|
const error = err as Error;
|
||||||
|
this.logger.error(`❌ Transaction rolled back due to error: ${error.message}`, {
|
||||||
|
stack: error.stack,
|
||||||
|
label: "TransactionManager.start",
|
||||||
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,16 +90,59 @@ export abstract class TransactionManager implements ITransactionManager {
|
|||||||
protected abstract _rollbackTransaction(): Promise<void>;
|
protected abstract _rollbackTransaction(): Promise<void>;
|
||||||
|
|
||||||
async commit(): Promise<void> {
|
async commit(): Promise<void> {
|
||||||
if (this._transaction) {
|
if (!this._transaction) {
|
||||||
|
this.logger.error("❌ No transaction to commit.", { label: "TransactionManager.commit" });
|
||||||
|
throw new Error("No transaction to commit.");
|
||||||
|
}
|
||||||
|
if (this._isCompleted) {
|
||||||
|
this.logger.error("❌ Transaction already completed. Cannot commit again.", {
|
||||||
|
label: "TransactionManager.commit",
|
||||||
|
});
|
||||||
|
throw new Error("Transaction already completed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
await this._commitTransaction();
|
await this._commitTransaction();
|
||||||
|
this.logger.info("Transaction committed.", { label: "TransactionManager.commit" });
|
||||||
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
|
this.logger.error(`❌ Error during commit: ${error.message}`, {
|
||||||
|
stack: error.stack,
|
||||||
|
label: "TransactionManager.commit",
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
// Siempre limpia el estado interno
|
||||||
this._transaction = null;
|
this._transaction = null;
|
||||||
|
this._isCompleted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async rollback(): Promise<void> {
|
async rollback(): Promise<void> {
|
||||||
if (this._transaction) {
|
if (!this._transaction) {
|
||||||
|
this.logger.error("❌ No transaction to rollback.", { label: "TransactionManager.rollback" });
|
||||||
|
throw new Error("No transaction to rollback.");
|
||||||
|
}
|
||||||
|
if (this._isCompleted) {
|
||||||
|
this.logger.error("❌ Transaction already completed. Cannot rollback again.", {
|
||||||
|
label: "TransactionManager.rollback",
|
||||||
|
});
|
||||||
|
throw new Error("Transaction already completed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
await this._rollbackTransaction();
|
await this._rollbackTransaction();
|
||||||
|
this.logger.info("Transaction rolled back.");
|
||||||
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
|
this.logger.error(`❌ Error during rollback: ${error.message}`, {
|
||||||
|
stack: error.stack,
|
||||||
|
label: "TransactionManager.rollback",
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
this._transaction = null;
|
this._transaction = null;
|
||||||
|
this._isCompleted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,17 @@
|
|||||||
|
import { DatabaseError } from "sequelize";
|
||||||
import { InfrastructureError } from "./infrastructure-errors";
|
import { InfrastructureError } from "./infrastructure-errors";
|
||||||
|
|
||||||
export class InfrastructureRepositoryError extends InfrastructureError {
|
export class InfrastructureRepositoryError extends InfrastructureError {
|
||||||
public readonly code = "REPOSITORY_ERROR" as const;
|
public readonly code = "REPOSITORY_ERROR" as const;
|
||||||
constructor(message = "Repository operation failed", options?: ErrorOptions) {
|
constructor(message = "Repository operation failed", options?: ErrorOptions) {
|
||||||
super(message, options);
|
const { cause } = options || {};
|
||||||
|
let _message = message;
|
||||||
|
|
||||||
|
if (cause && cause instanceof DatabaseError) {
|
||||||
|
_message = `${message}: ${(cause as DatabaseError).message}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
super(_message, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,14 +17,14 @@ import { Result } from "@repo/rdx-utils";
|
|||||||
import { CreateCustomerInvoiceRequestDTO } from "../../../common/dto";
|
import { CreateCustomerInvoiceRequestDTO } from "../../../common/dto";
|
||||||
import {
|
import {
|
||||||
CustomerInvoiceItemDescription,
|
CustomerInvoiceItemDescription,
|
||||||
CustomerInvoiceItemDiscount,
|
|
||||||
CustomerInvoiceItemProps,
|
CustomerInvoiceItemProps,
|
||||||
CustomerInvoiceItemQuantity,
|
CustomerInvoiceItemQuantity,
|
||||||
CustomerInvoiceItemUnitAmount,
|
|
||||||
CustomerInvoiceNumber,
|
CustomerInvoiceNumber,
|
||||||
CustomerInvoiceProps,
|
CustomerInvoiceProps,
|
||||||
CustomerInvoiceSerie,
|
CustomerInvoiceSerie,
|
||||||
CustomerInvoiceStatus,
|
CustomerInvoiceStatus,
|
||||||
|
ItemAmount,
|
||||||
|
ItemDiscount,
|
||||||
} from "../../domain";
|
} from "../../domain";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,15 +162,13 @@ function mapDTOToCreateCustomerInvoiceItemsProps(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const unitAmount = extractOrPushError(
|
const unitAmount = extractOrPushError(
|
||||||
maybeFromNullableVO(item.unit_amount, (value) => CustomerInvoiceItemUnitAmount.create(value)),
|
maybeFromNullableVO(item.unit_amount, (value) => ItemAmount.create(value)),
|
||||||
"unit_amount",
|
"unit_amount",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const discountPercentage = extractOrPushError(
|
const discountPercentage = extractOrPushError(
|
||||||
maybeFromNullableVO(item.discount_percentage, (value) =>
|
maybeFromNullableVO(item.discount_percentage, (value) => ItemDiscount.create(value)),
|
||||||
CustomerInvoiceItemDiscount.create(value)
|
|
||||||
),
|
|
||||||
"discount_percentage",
|
"discount_percentage",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,22 +1,23 @@
|
|||||||
import { EntityNotFoundError, ITransactionManager } from "@erp/core/api";
|
import { EntityNotFoundError, ITransactionManager } from "@erp/core/api";
|
||||||
import { UniqueID } from "@repo/rdx-ddd";
|
import { UniqueID } from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import { ICustomerInvoiceService } from "../../domain";
|
import { CustomerInvoiceService } from "../../domain";
|
||||||
|
|
||||||
type DeleteCustomerInvoiceUseCaseInput = {
|
type DeleteCustomerInvoiceUseCaseInput = {
|
||||||
tenantId: string;
|
companyId: UniqueID;
|
||||||
id: string;
|
invoice_id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class DeleteCustomerInvoiceUseCase {
|
export class DeleteCustomerInvoiceUseCase {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly service: ICustomerInvoiceService,
|
private readonly service: CustomerInvoiceService,
|
||||||
private readonly transactionManager: ITransactionManager
|
private readonly transactionManager: ITransactionManager
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public execute(params: DeleteCustomerInvoiceUseCaseInput) {
|
public execute(params: DeleteCustomerInvoiceUseCaseInput) {
|
||||||
const { id, tenantId } = params;
|
const { invoice_id, companyId } = params;
|
||||||
const idOrError = UniqueID.create(id);
|
|
||||||
|
const idOrError = UniqueID.create(invoice_id);
|
||||||
|
|
||||||
if (idOrError.isFailure) {
|
if (idOrError.isFailure) {
|
||||||
return Result.fail(idOrError.error);
|
return Result.fail(idOrError.error);
|
||||||
@ -26,17 +27,25 @@ export class DeleteCustomerInvoiceUseCase {
|
|||||||
|
|
||||||
return this.transactionManager.complete(async (transaction) => {
|
return this.transactionManager.complete(async (transaction) => {
|
||||||
try {
|
try {
|
||||||
const existsCheck = await this.service.existsById(invoiceId, transaction);
|
const existsCheck = await this.service.existsByIdInCompany(
|
||||||
|
companyId,
|
||||||
|
invoiceId,
|
||||||
|
transaction
|
||||||
|
);
|
||||||
|
|
||||||
if (existsCheck.isFailure) {
|
if (existsCheck.isFailure) {
|
||||||
return Result.fail(existsCheck.error);
|
return Result.fail(existsCheck.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existsCheck.data) {
|
const invoiceExists = existsCheck.data;
|
||||||
return Result.fail(new EntityNotFoundError("CustomerInvoice", "id", id.toString()));
|
|
||||||
|
if (!invoiceExists) {
|
||||||
|
return Result.fail(
|
||||||
|
new EntityNotFoundError("Customer invoice", "id", invoiceId.toString())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.service.deleteById(invoiceId, transaction);
|
return await this.service.deleteInvoiceByIdInCompany(companyId, invoiceId, transaction);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return Result.fail(error as Error);
|
return Result.fail(error as Error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,9 +4,9 @@ import { Result } from "@repo/rdx-utils";
|
|||||||
import {
|
import {
|
||||||
CustomerInvoiceItem,
|
CustomerInvoiceItem,
|
||||||
CustomerInvoiceItemDescription,
|
CustomerInvoiceItemDescription,
|
||||||
CustomerInvoiceItemDiscount,
|
|
||||||
CustomerInvoiceItemQuantity,
|
CustomerInvoiceItemQuantity,
|
||||||
CustomerInvoiceItemUnitAmount,
|
ItemAmount,
|
||||||
|
ItemDiscount,
|
||||||
} from "../../domain";
|
} from "../../domain";
|
||||||
import { extractOrPushError } from "./extract-or-push-error";
|
import { extractOrPushError } from "./extract-or-push-error";
|
||||||
import { hasNoUndefinedFields } from "./has-no-undefined-fields";
|
import { hasNoUndefinedFields } from "./has-no-undefined-fields";
|
||||||
@ -36,7 +36,7 @@ export function mapDTOToCustomerInvoiceItemsProps(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const unitPrice = extractOrPushError(
|
const unitPrice = extractOrPushError(
|
||||||
CustomerInvoiceItemUnitAmount.create({
|
ItemAmount.create({
|
||||||
value: item.unitPrice.amount,
|
value: item.unitPrice.amount,
|
||||||
scale: item.unitPrice.scale,
|
scale: item.unitPrice.scale,
|
||||||
currency_code: item.unitPrice.currency,
|
currency_code: item.unitPrice.currency,
|
||||||
@ -46,7 +46,7 @@ export function mapDTOToCustomerInvoiceItemsProps(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const discount = extractOrPushError(
|
const discount = extractOrPushError(
|
||||||
CustomerInvoiceItemDiscount.create({
|
ItemDiscount.create({
|
||||||
value: item.discount.amount,
|
value: item.discount.amount,
|
||||||
scale: item.discount.scale,
|
scale: item.discount.scale,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -9,26 +9,50 @@ import {
|
|||||||
import { Maybe, Result } from "@repo/rdx-utils";
|
import { Maybe, Result } from "@repo/rdx-utils";
|
||||||
import {
|
import {
|
||||||
CustomerInvoiceItemDescription,
|
CustomerInvoiceItemDescription,
|
||||||
CustomerInvoiceItemDiscount,
|
ItemAmount,
|
||||||
CustomerInvoiceItemQuantity,
|
ItemDiscount,
|
||||||
CustomerInvoiceItemSubtotalAmount,
|
ItemQuantity,
|
||||||
CustomerInvoiceItemTotalAmount,
|
|
||||||
CustomerInvoiceItemUnitAmount,
|
|
||||||
} from "../../value-objects";
|
} from "../../value-objects";
|
||||||
|
|
||||||
export interface CustomerInvoiceItemProps {
|
export interface CustomerInvoiceItemProps {
|
||||||
description: Maybe<CustomerInvoiceItemDescription>;
|
description: Maybe<CustomerInvoiceItemDescription>;
|
||||||
quantity: Maybe<CustomerInvoiceItemQuantity>; // Cantidad de unidades
|
quantity: Maybe<ItemQuantity>; // Cantidad de unidades
|
||||||
unitAmount: Maybe<CustomerInvoiceItemUnitAmount>; // Precio unitario en la moneda de la factura
|
unitAmount: Maybe<ItemAmount>; // Precio unitario en la moneda de la factura
|
||||||
discountPercentage: Maybe<CustomerInvoiceItemDiscount>; // % descuento
|
discountPercentage: Maybe<ItemDiscount>; // % descuento
|
||||||
|
|
||||||
languageCode: LanguageCode;
|
languageCode: LanguageCode;
|
||||||
currencyCode: CurrencyCode;
|
currencyCode: CurrencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps> {
|
export interface ICustomerInvoiceItem {
|
||||||
private _subtotalAmount!: CustomerInvoiceItemSubtotalAmount;
|
description: Maybe<CustomerInvoiceItemDescription>;
|
||||||
private _totalAmount!: CustomerInvoiceItemTotalAmount;
|
|
||||||
|
quantity: Maybe<ItemQuantity>; // Cantidad de unidades
|
||||||
|
unitAmount: Maybe<ItemAmount>; // Precio unitario en la moneda de la factura
|
||||||
|
subtotalAmount: ItemAmount;
|
||||||
|
|
||||||
|
discountPercentage: Maybe<ItemDiscount>; // % descuento
|
||||||
|
discountAmount: Maybe<ItemAmount>;
|
||||||
|
|
||||||
|
taxableAmount: ItemAmount;
|
||||||
|
taxesAmount: ItemAmount;
|
||||||
|
|
||||||
|
totalAmount: ItemAmount;
|
||||||
|
|
||||||
|
languageCode: LanguageCode;
|
||||||
|
currencyCode: CurrencyCode;
|
||||||
|
|
||||||
|
calculateSubtotal(): ItemAmount;
|
||||||
|
|
||||||
|
calculateTotal(): ItemAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CustomerInvoiceItem
|
||||||
|
extends DomainEntity<CustomerInvoiceItemProps>
|
||||||
|
implements ICustomerInvoiceItem
|
||||||
|
{
|
||||||
|
private _subtotalAmount!: ItemAmount;
|
||||||
|
private _totalAmount!: ItemAmount;
|
||||||
|
|
||||||
public static create(
|
public static create(
|
||||||
props: CustomerInvoiceItemProps,
|
props: CustomerInvoiceItemProps,
|
||||||
@ -51,19 +75,16 @@ export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps>
|
|||||||
return this.props.description;
|
return this.props.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
get quantity(): Maybe<CustomerInvoiceItemQuantity> {
|
get quantity(): Maybe<ItemQuantity> {
|
||||||
return this.props.quantity;
|
return this.props.quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
get unitAmount(): Maybe<CustomerInvoiceItemUnitAmount> {
|
get unitAmount(): Maybe<ItemAmount> {
|
||||||
return this.props.unitAmount;
|
return this.props.unitAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
get subtotalAmount(): CustomerInvoiceItemSubtotalAmount {
|
get subtotalAmount(): ItemAmount {
|
||||||
if (!this._subtotalAmount) {
|
throw new Error("Not implemented");
|
||||||
this._subtotalAmount = this.calculateSubtotal();
|
|
||||||
}
|
|
||||||
return this._subtotalAmount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get discountPercentage(): Maybe<Percentage> {
|
get discountPercentage(): Maybe<Percentage> {
|
||||||
@ -74,11 +95,16 @@ export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps>
|
|||||||
throw new Error("Not implemented");
|
throw new Error("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
get totalAmount(): CustomerInvoiceItemTotalAmount {
|
get taxableAmount(): ItemAmount {
|
||||||
if (!this._totalAmount) {
|
throw new Error("Not implemented");
|
||||||
this._totalAmount = this.calculateTotal();
|
}
|
||||||
}
|
|
||||||
return this._totalAmount;
|
get taxesAmount(): ItemAmount {
|
||||||
|
throw new Error("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
get totalAmount(): ItemAmount {
|
||||||
|
throw new Error("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
public get languageCode(): LanguageCode {
|
public get languageCode(): LanguageCode {
|
||||||
@ -89,15 +115,15 @@ export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps>
|
|||||||
return this.props.currencyCode;
|
return this.props.currencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(): CustomerInvoiceItemProps {
|
getProps(): CustomerInvoiceItemProps {
|
||||||
return this.props;
|
return this.props;
|
||||||
}
|
}
|
||||||
|
|
||||||
toPrimitive() {
|
toPrimitive() {
|
||||||
return this.getValue();
|
return this.getProps();
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateSubtotal(): CustomerInvoiceItemSubtotalAmount {
|
calculateSubtotal(): ItemAmount {
|
||||||
throw new Error("Not implemented");
|
throw new Error("Not implemented");
|
||||||
|
|
||||||
/*const unitPrice = this.unitPrice.isSome()
|
/*const unitPrice = this.unitPrice.isSome()
|
||||||
@ -106,7 +132,7 @@ export class CustomerInvoiceItem extends DomainEntity<CustomerInvoiceItemProps>
|
|||||||
return this.unitPrice.multiply(this.quantity.toNumber()); // Precio unitario * Cantidad*/
|
return this.unitPrice.multiply(this.quantity.toNumber()); // Precio unitario * Cantidad*/
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateTotal(): CustomerInvoiceItemTotalAmount {
|
calculateTotal(): ItemAmount {
|
||||||
throw new Error("Not implemented");
|
throw new Error("Not implemented");
|
||||||
//return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
//return this.subtotalPrice.subtract(this.subtotalPrice.percentage(this.discount.toNumber()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,7 +128,7 @@ export class CustomerInvoiceService {
|
|||||||
* @param transaction - Transacción activa para la operación.
|
* @param transaction - Transacción activa para la operación.
|
||||||
* @returns Result<boolean, Error> - Resultado de la operación.
|
* @returns Result<boolean, Error> - Resultado de la operación.
|
||||||
*/
|
*/
|
||||||
async deleteById(
|
async deleteInvoiceByIdInCompany(
|
||||||
companyId: UniqueID,
|
companyId: UniqueID,
|
||||||
invoiceId: UniqueID,
|
invoiceId: UniqueID,
|
||||||
transaction?: Transaction
|
transaction?: Transaction
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
import { Percentage } from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
export class CustomerInvoiceItemDiscount extends Percentage {}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
export class CustomerInvoiceItemSubtotalAmount extends MoneyValue {
|
|
||||||
public static DEFAULT_SCALE = 4;
|
|
||||||
|
|
||||||
static create({ value, currency_code }: MoneyValueProps) {
|
|
||||||
const props = {
|
|
||||||
value: Number(value),
|
|
||||||
scale: CustomerInvoiceItemSubtotalAmount.DEFAULT_SCALE,
|
|
||||||
currency_code,
|
|
||||||
};
|
|
||||||
return MoneyValue.create(props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
export class ItemTotalAmount extends MoneyValue {
|
|
||||||
public static DEFAULT_SCALE = 4;
|
|
||||||
|
|
||||||
static create({ value, currency_code, scale }: MoneyValueProps) {
|
|
||||||
const props = {
|
|
||||||
value: Number(value),
|
|
||||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
|
||||||
currency_code,
|
|
||||||
};
|
|
||||||
return MoneyValue.create(props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
|
||||||
|
|
||||||
export class CustomerInvoiceItemUnitAmount extends MoneyValue {
|
|
||||||
public static DEFAULT_SCALE = 4;
|
|
||||||
|
|
||||||
static create({ value: amount, currency_code, scale }: MoneyValueProps) {
|
|
||||||
const props = {
|
|
||||||
amount: Number(amount),
|
|
||||||
scale: scale ?? MoneyValue.DEFAULT_SCALE,
|
|
||||||
currency_code,
|
|
||||||
};
|
|
||||||
return MoneyValue.create(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
static zero(currency_code: string, scale: number = CustomerInvoiceItemUnitAmount.DEFAULT_SCALE) {
|
|
||||||
const props: MoneyValueProps = {
|
|
||||||
value: 0,
|
|
||||||
scale,
|
|
||||||
currency_code,
|
|
||||||
};
|
|
||||||
return MoneyValue.create(props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +1,8 @@
|
|||||||
export * from "./customer-invoice-address-type";
|
export * from "./customer-invoice-address-type";
|
||||||
export * from "./customer-invoice-item-description";
|
export * from "./customer-invoice-item-description";
|
||||||
export * from "./customer-invoice-item-discount";
|
|
||||||
export * from "./customer-invoice-item-subtotal-amount";
|
|
||||||
export * from "./customer-invoice-item-total-amount";
|
|
||||||
export * from "./customer-invoice-item-unit-amount";
|
|
||||||
export * from "./customer-invoice-number";
|
export * from "./customer-invoice-number";
|
||||||
export * from "./customer-invoice-serie";
|
export * from "./customer-invoice-serie";
|
||||||
export * from "./customer-invoice-status";
|
export * from "./customer-invoice-status";
|
||||||
|
export * from "./item-amount";
|
||||||
|
export * from "./item-discount";
|
||||||
export * from "./item-quantity";
|
export * from "./item-quantity";
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { MoneyValue, MoneyValueProps } from "@repo/rdx-ddd";
|
||||||
|
|
||||||
|
type ItemAmountProps = Pick<MoneyValueProps, "value" | "currency_code">;
|
||||||
|
|
||||||
|
export class ItemAmount extends MoneyValue {
|
||||||
|
public static DEFAULT_SCALE = 4;
|
||||||
|
|
||||||
|
static create({ value, currency_code }: ItemAmountProps) {
|
||||||
|
const props = {
|
||||||
|
value: Number(value),
|
||||||
|
scale: ItemAmount.DEFAULT_SCALE,
|
||||||
|
currency_code,
|
||||||
|
};
|
||||||
|
return MoneyValue.create(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static zero(currency_code: string) {
|
||||||
|
const props = {
|
||||||
|
value: 0,
|
||||||
|
currency_code,
|
||||||
|
};
|
||||||
|
return ItemAmount.create(props);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { Percentage, PercentageProps } from "@repo/rdx-ddd";
|
||||||
|
import { Result } from "@repo/rdx-utils";
|
||||||
|
|
||||||
|
type ItemDiscountProps = Pick<PercentageProps, "value">;
|
||||||
|
|
||||||
|
export class ItemDiscount extends Percentage {
|
||||||
|
static DEFAULT_SCALE = 2;
|
||||||
|
|
||||||
|
static create({ value }: ItemDiscountProps): Result<Percentage> {
|
||||||
|
return Percentage.create({
|
||||||
|
value,
|
||||||
|
scale: ItemDiscount.DEFAULT_SCALE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static zero() {
|
||||||
|
return ItemDiscount.create({ value: 0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,13 +1,18 @@
|
|||||||
import { Quantity, QuantityProps } from "@repo/rdx-ddd";
|
import { Quantity, QuantityProps } from "@repo/rdx-ddd";
|
||||||
|
|
||||||
|
type ItemQuantityProps = Pick<QuantityProps, "value">;
|
||||||
|
|
||||||
export class ItemQuantity extends Quantity {
|
export class ItemQuantity extends Quantity {
|
||||||
public static DEFAULT_SCALE = 2;
|
public static DEFAULT_SCALE = 2;
|
||||||
|
|
||||||
static create({ value }: QuantityProps) {
|
static create({ value }: ItemQuantityProps) {
|
||||||
const props = {
|
return Quantity.create({
|
||||||
value: Number(value),
|
value,
|
||||||
scale: ItemQuantity.DEFAULT_SCALE,
|
scale: ItemQuantity.DEFAULT_SCALE,
|
||||||
};
|
});
|
||||||
return Quantity.create(props);
|
}
|
||||||
|
|
||||||
|
static zero() {
|
||||||
|
return ItemQuantity.create({ value: 0 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,16 +5,22 @@ import {
|
|||||||
ValidationErrorDetail,
|
ValidationErrorDetail,
|
||||||
extractOrPushError,
|
extractOrPushError,
|
||||||
} from "@erp/core/api";
|
} from "@erp/core/api";
|
||||||
import { CurrencyCode, LanguageCode, Quantity, UniqueID, maybeFromNullableVO, toNullable } from "@repo/rdx-ddd";
|
import {
|
||||||
|
CurrencyCode,
|
||||||
|
LanguageCode,
|
||||||
|
UniqueID,
|
||||||
|
maybeFromNullableVO,
|
||||||
|
toNullable,
|
||||||
|
} from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import { InferCreationAttributes } from "sequelize";
|
import { InferCreationAttributes } from "sequelize";
|
||||||
import {
|
import {
|
||||||
CustomerInvoice,
|
CustomerInvoice,
|
||||||
CustomerInvoiceItem,
|
CustomerInvoiceItem,
|
||||||
CustomerInvoiceItemDescription,
|
CustomerInvoiceItemDescription,
|
||||||
CustomerInvoiceItemDiscount,
|
ItemAmount,
|
||||||
CustomerInvoiceItemQuantity,
|
ItemDiscount,
|
||||||
CustomerInvoiceItemUnitAmount,
|
ItemQuantity,
|
||||||
} from "../../domain";
|
} from "../../domain";
|
||||||
import {
|
import {
|
||||||
CustomerInvoiceItemCreationAttributes,
|
CustomerInvoiceItemCreationAttributes,
|
||||||
@ -48,17 +54,17 @@ export class CustomerInvoiceItemMapper
|
|||||||
|
|
||||||
const itemId = extractOrPushError(UniqueID.create(source.item_id), "item_id", errors);
|
const itemId = extractOrPushError(UniqueID.create(source.item_id), "item_id", errors);
|
||||||
|
|
||||||
const languageCode = extractOrPushError(
|
const languageCode = extractOrPushError(
|
||||||
LanguageCode.create(sourceParent.language_code),
|
LanguageCode.create(sourceParent.language_code),
|
||||||
"language_code",
|
"language_code",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const currencyCode = extractOrPushError(
|
const currencyCode = extractOrPushError(
|
||||||
CurrencyCode.create(sourceParent.currency_code),
|
CurrencyCode.create(sourceParent.currency_code),
|
||||||
"currency_code",
|
"currency_code",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const description = extractOrPushError(
|
const description = extractOrPushError(
|
||||||
maybeFromNullableVO(source.description, (value) =>
|
maybeFromNullableVO(source.description, (value) =>
|
||||||
@ -69,36 +75,27 @@ export class CustomerInvoiceItemMapper
|
|||||||
);
|
);
|
||||||
|
|
||||||
const quantity = extractOrPushError(
|
const quantity = extractOrPushError(
|
||||||
maybeFromNullableVO(source.quantity_value, (value) =>
|
maybeFromNullableVO(source.quantity_value, (value) => ItemQuantity.create({ value })),
|
||||||
Quantity.create({ value, })
|
|
||||||
|
|
||||||
CustomerInvoiceItemQuantity.create({
|
|
||||||
value: source.quantity_amouwnt,
|
|
||||||
scale: source.quantity_scale,
|
|
||||||
}),
|
|
||||||
"discount_percentage",
|
"discount_percentage",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const unitAmount = extractOrPushError(
|
const unitAmount = extractOrPushError(
|
||||||
CustomerInvoiceItemUnitAmount.create({
|
maybeFromNullableVO(source.unit_amount_value, (value) =>
|
||||||
value: source.unit_price_amount,
|
ItemAmount.create({ value, currency_code: currencyCode!.code })
|
||||||
scale: source.unit_price_scale,
|
),
|
||||||
}),
|
"unit_amount",
|
||||||
"discount_percentage",
|
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
const discountPercentage = extractOrPushError(
|
const discountPercentage = extractOrPushError(
|
||||||
CustomerInvoiceItemDiscount.create({
|
maybeFromNullableVO(source.discount_percentage_value, (value) =>
|
||||||
value: source.discount_amount,
|
ItemDiscount.create({ value })
|
||||||
scale: source.discount_scale,
|
),
|
||||||
}),
|
|
||||||
"discount_percentage",
|
"discount_percentage",
|
||||||
errors
|
errors
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Creación del objeto de dominio
|
// Creación del objeto de dominio
|
||||||
return CustomerInvoiceItem.create(
|
return CustomerInvoiceItem.create(
|
||||||
{
|
{
|
||||||
@ -108,8 +105,8 @@ export class CustomerInvoiceItemMapper
|
|||||||
quantity: quantity!,
|
quantity: quantity!,
|
||||||
unitAmount: unitAmount!,
|
unitAmount: unitAmount!,
|
||||||
discountPercentage: discountPercentage!,
|
discountPercentage: discountPercentage!,
|
||||||
},º
|
},
|
||||||
id
|
itemId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,14 +114,12 @@ export class CustomerInvoiceItemMapper
|
|||||||
source: CustomerInvoiceItem,
|
source: CustomerInvoiceItem,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): InferCreationAttributes<CustomerInvoiceItemModel, {}> {
|
): InferCreationAttributes<CustomerInvoiceItemModel, {}> {
|
||||||
1
|
1;
|
||||||
const { index, sourceParent } = params as {
|
const { index, sourceParent } = params as {
|
||||||
index: number;
|
index: number;
|
||||||
sourceParent: CustomerInvoice;
|
sourceParent: CustomerInvoice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
item_id: source.id.toPrimitive(),
|
item_id: source.id.toPrimitive(),
|
||||||
invoice_id: sourceParent.id.toPrimitive(),
|
invoice_id: sourceParent.id.toPrimitive(),
|
||||||
@ -135,23 +130,41 @@ export class CustomerInvoiceItemMapper
|
|||||||
quantity_value: toNullable(source.quantity, (value) => value.toPrimitive().value),
|
quantity_value: toNullable(source.quantity, (value) => value.toPrimitive().value),
|
||||||
quantity_scale: source.quantity.match(
|
quantity_scale: source.quantity.match(
|
||||||
(value) => value.toPrimitive().scale,
|
(value) => value.toPrimitive().scale,
|
||||||
() => CustomerInvoiceItemQuantity.DEFAULT_SCALE),
|
() => ItemQuantity.DEFAULT_SCALE
|
||||||
|
),
|
||||||
|
|
||||||
unit_amount_value: toNullable(source.unitAmount, (value) => value.toPrimitive().value),
|
unit_amount_value: toNullable(source.unitAmount, (value) => value.toPrimitive().value),
|
||||||
unit_amount_scale: source.unitAmount.match(
|
unit_amount_scale: source.unitAmount.match(
|
||||||
(value) => value.toPrimitive().scale,
|
(value) => value.toPrimitive().scale,
|
||||||
() => CustomerInvoiceItemUnitAmount.DEFAULT_SCALE),
|
() => ItemAmount.DEFAULT_SCALE
|
||||||
|
),
|
||||||
|
|
||||||
subtotal_amount_value: source.subtotalAmount.toPrimitive().value,
|
subtotal_amount_value: source.subtotalAmount.toPrimitive().value,
|
||||||
subtotal_amount_scale: source.subtotalAmount.toPrimitive().scale,
|
subtotal_amount_scale: source.subtotalAmount.toPrimitive().scale,
|
||||||
|
|
||||||
discount_percentage_value: toNullable(source.discountPercentage, (value) => value.toPrimitive().value),
|
discount_percentage_value: toNullable(
|
||||||
|
source.discountPercentage,
|
||||||
|
(value) => value.toPrimitive().value
|
||||||
|
),
|
||||||
discount_percentage_scale: source.discountPercentage.match(
|
discount_percentage_scale: source.discountPercentage.match(
|
||||||
(value) => value.toPrimitive().scale,
|
(value) => value.toPrimitive().scale,
|
||||||
() => CustomerInvoiceItemUnitAmount.DEFAULT_SCALE),
|
() => ItemAmount.DEFAULT_SCALE
|
||||||
|
),
|
||||||
|
|
||||||
discount_amount_value: source.subtotalAmount.toPrimitive().value,
|
discount_amount_value: toNullable(
|
||||||
discount_amount_scale: source.subtotalAmount.toPrimitive().scale,
|
source.discountAmount,
|
||||||
|
(value) => value.toPrimitive().value
|
||||||
|
),
|
||||||
|
discount_amount_scale: source.discountAmount.match(
|
||||||
|
(value) => value.toPrimitive().scale,
|
||||||
|
() => ItemDiscount.DEFAULT_SCALE
|
||||||
|
),
|
||||||
|
|
||||||
|
taxable_amount_value: source.taxableAmount.toPrimitive().value,
|
||||||
|
taxable_amount_scale: source.taxableAmount.toPrimitive().value,
|
||||||
|
|
||||||
|
taxes_amount_value: source.taxesAmount.toPrimitive().value,
|
||||||
|
taxes_amount_scale: source.taxesAmount.toPrimitive().value,
|
||||||
|
|
||||||
total_amount_value: source.totalAmount.toPrimitive().value,
|
total_amount_value: source.totalAmount.toPrimitive().value,
|
||||||
total_amount_scale: source.totalAmount.toPrimitive().scale,
|
total_amount_scale: source.totalAmount.toPrimitive().scale,
|
||||||
|
|||||||
@ -14,10 +14,12 @@ import {
|
|||||||
UniqueID,
|
UniqueID,
|
||||||
UtcDate,
|
UtcDate,
|
||||||
maybeFromNullableVO,
|
maybeFromNullableVO,
|
||||||
|
toNullable,
|
||||||
} from "@repo/rdx-ddd";
|
} from "@repo/rdx-ddd";
|
||||||
import { Result } from "@repo/rdx-utils";
|
import { Result } from "@repo/rdx-utils";
|
||||||
import {
|
import {
|
||||||
CustomerInvoice,
|
CustomerInvoice,
|
||||||
|
CustomerInvoiceItems,
|
||||||
CustomerInvoiceNumber,
|
CustomerInvoiceNumber,
|
||||||
CustomerInvoiceProps,
|
CustomerInvoiceProps,
|
||||||
CustomerInvoiceSerie,
|
CustomerInvoiceSerie,
|
||||||
@ -149,7 +151,10 @@ export class CustomerInvoiceMapper
|
|||||||
|
|
||||||
discountPercentage: discountPercentage!,
|
discountPercentage: discountPercentage!,
|
||||||
|
|
||||||
items: items!,
|
items: CustomerInvoiceItems.create({
|
||||||
|
languageCode: languageCode!,
|
||||||
|
currencyCode: currencyCode!,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
return CustomerInvoice.create(invoiceProps, invoiceId);
|
return CustomerInvoice.create(invoiceProps, invoiceId);
|
||||||
@ -162,26 +167,41 @@ export class CustomerInvoiceMapper
|
|||||||
source: CustomerInvoice,
|
source: CustomerInvoice,
|
||||||
params?: MapperParamsType
|
params?: MapperParamsType
|
||||||
): CustomerInvoiceCreationAttributes {
|
): CustomerInvoiceCreationAttributes {
|
||||||
const subtotal = source.calculateSubtotal();
|
//const subtotal = source.calculateSubtotal();
|
||||||
const total = source.calculateTotal();
|
//const total = source.calculateTotal();
|
||||||
|
|
||||||
const items = this._itemsMapper.mapCollectionToPersistence(source.items, params);
|
const items = this._itemsMapper.mapCollectionToPersistence(source.items, params);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: source.id.toString(),
|
id: source.id.toPrimitive(),
|
||||||
invoice_status: source.status.toPrimitive(),
|
company_id: source.companyId.toPrimitive(),
|
||||||
invoice_series: source.invoiceSeries.toPrimitive(),
|
|
||||||
|
status: source.status.toPrimitive(),
|
||||||
|
series: toNullable(source.series, (series) => series.toPrimitive()),
|
||||||
|
|
||||||
invoice_number: source.invoiceNumber.toPrimitive(),
|
invoice_number: source.invoiceNumber.toPrimitive(),
|
||||||
invoice_date: source.invoiceDate.toPrimitive(),
|
invoice_date: source.invoiceDate.toPrimitive(),
|
||||||
operation_date: source.operationDate.toPrimitive(),
|
|
||||||
invoice_language: "es",
|
|
||||||
invoice_currency: source.currency || "EUR",
|
|
||||||
|
|
||||||
subtotal_amount: subtotal.amount,
|
operation_date: toNullable(source.operationDate, (operationDate) =>
|
||||||
subtotal_scale: subtotal.scale,
|
operationDate.toPrimitive()
|
||||||
|
),
|
||||||
|
|
||||||
total_amount: total.amount,
|
notes: toNullable(source.notes, (notes) => notes.toPrimitive()),
|
||||||
total_scale: total.scale,
|
|
||||||
|
language_code: source.languageCode.code,
|
||||||
|
currency_code: source.currencyCode.code,
|
||||||
|
|
||||||
|
subtotal_amount_value: 0, //subtotal.amount,
|
||||||
|
subtotal_amount_scale: 2, //subtotal.scale,
|
||||||
|
|
||||||
|
/*discount_percentage_value: source.discountPercentage.value,
|
||||||
|
discount_percentage_scale: source.discountPercentage.scale,
|
||||||
|
|
||||||
|
discount_amount_value: source.discountAmount.value,
|
||||||
|
discount_amount_scale: source.discountAmount.scale,*/
|
||||||
|
|
||||||
|
total_amount_value: 0, //total.amount,
|
||||||
|
total_amount_scale: 2, //total.scale,
|
||||||
|
|
||||||
items,
|
items,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export class CustomerInvoiceItemTaxesModel extends Model<
|
|||||||
InferAttributes<CustomerInvoiceItemTaxesModel>,
|
InferAttributes<CustomerInvoiceItemTaxesModel>,
|
||||||
InferCreationAttributes<CustomerInvoiceItemTaxesModel>
|
InferCreationAttributes<CustomerInvoiceItemTaxesModel>
|
||||||
> {
|
> {
|
||||||
declare id: string;
|
declare tax_id: string;
|
||||||
declare item_id: string;
|
declare item_id: string;
|
||||||
|
|
||||||
declare tax_code: string; //"iva_21"
|
declare tax_code: string; //"iva_21"
|
||||||
@ -38,7 +38,7 @@ export class CustomerInvoiceItemTaxesModel extends Model<
|
|||||||
|
|
||||||
CustomerInvoiceItemTaxesModel.belongsTo(CustomerInvoiceItemModel, {
|
CustomerInvoiceItemTaxesModel.belongsTo(CustomerInvoiceItemModel, {
|
||||||
as: "item",
|
as: "item",
|
||||||
targetKey: "id",
|
targetKey: "item_id",
|
||||||
foreignKey: "item_id",
|
foreignKey: "item_id",
|
||||||
onDelete: "CASCADE",
|
onDelete: "CASCADE",
|
||||||
});
|
});
|
||||||
@ -50,7 +50,7 @@ export class CustomerInvoiceItemTaxesModel extends Model<
|
|||||||
export default (database: Sequelize) => {
|
export default (database: Sequelize) => {
|
||||||
CustomerInvoiceItemTaxesModel.init(
|
CustomerInvoiceItemTaxesModel.init(
|
||||||
{
|
{
|
||||||
id: {
|
tax_id: {
|
||||||
type: new DataTypes.UUID(),
|
type: new DataTypes.UUID(),
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -195,10 +195,7 @@ export default (database: Sequelize) => {
|
|||||||
|
|
||||||
underscored: true,
|
underscored: true,
|
||||||
|
|
||||||
indexes: [
|
indexes: [{ name: "invoice_idx", fields: ["invoice_id"], unique: false }],
|
||||||
{ name: "invoice_idx", fields: ["invoice_id"], unique: false },
|
|
||||||
{ name: "parent_idx", fields: ["parent_id"], unique: false },
|
|
||||||
],
|
|
||||||
|
|
||||||
whereMergeStrategy: "and", // <- cómo tratar el merge de un scope
|
whereMergeStrategy: "and", // <- cómo tratar el merge de un scope
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export class CustomerInvoiceTaxesModel extends Model<
|
|||||||
InferAttributes<CustomerInvoiceTaxesModel>,
|
InferAttributes<CustomerInvoiceTaxesModel>,
|
||||||
InferCreationAttributes<CustomerInvoiceTaxesModel>
|
InferCreationAttributes<CustomerInvoiceTaxesModel>
|
||||||
> {
|
> {
|
||||||
declare id: string;
|
declare tax_id: string;
|
||||||
declare invoice_id: string;
|
declare invoice_id: string;
|
||||||
|
|
||||||
declare tax_code: string; //"iva_21"
|
declare tax_code: string; //"iva_21"
|
||||||
@ -50,7 +50,7 @@ export class CustomerInvoiceTaxesModel extends Model<
|
|||||||
export default (database: Sequelize) => {
|
export default (database: Sequelize) => {
|
||||||
CustomerInvoiceTaxesModel.init(
|
CustomerInvoiceTaxesModel.init(
|
||||||
{
|
{
|
||||||
id: {
|
tax_id: {
|
||||||
type: new DataTypes.UUID(),
|
type: new DataTypes.UUID(),
|
||||||
primaryKey: true,
|
primaryKey: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,9 +1,19 @@
|
|||||||
|
import customerInvoiceItemTaxesModelInit from "./customer-invoice-item-taxes.model";
|
||||||
import customerInvoiceItemModelInit from "./customer-invoice-item.model";
|
import customerInvoiceItemModelInit from "./customer-invoice-item.model";
|
||||||
|
import customerInvoiceTaxesModelInit from "./customer-invoice-taxes.model";
|
||||||
import customerInvoiceModelInit from "./customer-invoice.model";
|
import customerInvoiceModelInit from "./customer-invoice.model";
|
||||||
|
|
||||||
export * from "./customer-invoice-item.model"; // exporta las clases, tipos
|
export * from "./customer-invoice-item-taxes.model";
|
||||||
|
export * from "./customer-invoice-item.model";
|
||||||
|
export * from "./customer-invoice-taxes.model";
|
||||||
export * from "./customer-invoice.model";
|
export * from "./customer-invoice.model";
|
||||||
export * from "./customer-invoice.repository";
|
export * from "./customer-invoice.repository";
|
||||||
|
|
||||||
// Array de inicializadores para que registerModels() lo use
|
// Array de inicializadores para que registerModels() lo use
|
||||||
export const models = [customerInvoiceItemModelInit, customerInvoiceModelInit];
|
export const models = [
|
||||||
|
customerInvoiceModelInit,
|
||||||
|
customerInvoiceItemModelInit,
|
||||||
|
|
||||||
|
customerInvoiceTaxesModelInit,
|
||||||
|
customerInvoiceItemTaxesModelInit,
|
||||||
|
];
|
||||||
|
|||||||
@ -38,6 +38,10 @@ export class CurrencyCode extends ValueObject<CurrencyCodeProps> {
|
|||||||
return Result.ok(new CurrencyCode({ value: valueIsValid.data }));
|
return Result.ok(new CurrencyCode({ value: valueIsValid.data }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get code(): string {
|
||||||
|
return this.props.value;
|
||||||
|
}
|
||||||
|
|
||||||
getProps(): string {
|
getProps(): string {
|
||||||
return this.props.value;
|
return this.props.value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,10 @@ export class LanguageCode extends ValueObject<LanguageCodeProps> {
|
|||||||
return Result.ok(new LanguageCode({ value: valueIsValid.data }));
|
return Result.ok(new LanguageCode({ value: valueIsValid.data }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get code(): string {
|
||||||
|
return this.props.value;
|
||||||
|
}
|
||||||
|
|
||||||
getProps(): string {
|
getProps(): string {
|
||||||
return this.props.value;
|
return this.props.value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,6 @@ export class TextValue extends ValueObject<TextValueProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toPrimitive(): string {
|
toPrimitive(): string {
|
||||||
return this.getProps();
|
return String(this.getProps());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,10 +37,10 @@ export class UniqueID extends ValueObject<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return this.getProps();
|
return String(this.getProps());
|
||||||
}
|
}
|
||||||
|
|
||||||
toPrimitive() {
|
toPrimitive() {
|
||||||
return this.getProps();
|
return this.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user