Uecko_ERP/modules/customer-invoices/src/api/application/services/customer-invoice-application.service.ts

257 lines
8.9 KiB
TypeScript
Raw Normal View History

2025-11-11 18:57:04 +00:00
import type { Criteria } from "@repo/rdx-criteria/server";
import type { UniqueID } from "@repo/rdx-ddd";
import { type Collection, Maybe, Result } from "@repo/rdx-utils";
import type { Transaction } from "sequelize";
import type {
CustomerInvoiceNumber,
CustomerInvoiceSerie,
2025-11-07 17:51:18 +00:00
CustomerInvoiceStatus,
ICustomerInvoiceNumberGenerator,
2025-11-07 17:51:18 +00:00
} from "../../domain";
2025-10-04 16:29:14 +00:00
import {
CustomerInvoice,
2025-11-11 18:57:04 +00:00
type CustomerInvoicePatchProps,
type CustomerInvoiceProps,
2025-11-07 17:51:18 +00:00
} from "../../domain/aggregates";
2025-11-11 18:57:04 +00:00
import type { ICustomerInvoiceRepository } from "../../domain/repositories";
import type { CustomerInvoiceListDTO } from "../../infrastructure";
2025-10-04 16:29:14 +00:00
export class CustomerInvoiceApplicationService {
constructor(
private readonly repository: ICustomerInvoiceRepository,
private readonly numberGenerator: ICustomerInvoiceNumberGenerator
) {}
2025-06-11 15:13:44 +00:00
2025-06-26 11:32:55 +00:00
/**
* Devuelve el siguiente para proformas
*
* @param companyId - Identificador de la empresa a la que pertenece la proforma.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoiceNumber, Error> - El agregado construido o un error si falla la creación.
*/
async getNextProformaNumber(
companyId: UniqueID,
transaction: Transaction
): Promise<Result<CustomerInvoiceNumber, Error>> {
return await this.numberGenerator.nextForCompany(companyId, Maybe.none(), transaction);
}
/**
* Devuelve el siguiente para facturas (issue)
2025-06-26 11:32:55 +00:00
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
* @param series - Serie por la que buscar la última factura
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoiceNumber, Error> - El agregado construido o un error si falla la creación.
*/
async getNextIssueInvoiceNumber(
companyId: UniqueID,
series: Maybe<CustomerInvoiceSerie>,
transaction: Transaction
): Promise<Result<CustomerInvoiceNumber, Error>> {
return await this.numberGenerator.nextForCompany(companyId, series, transaction);
}
/**
* Construye una proforma a partir de props validadas.
*
* @param companyId - Identificador de la empresa a la que pertenece la proforma.
* @param props - Las propiedades ya validadas para crear la proforma.
2025-11-11 18:57:04 +00:00
* @param proformaId - Identificador UUID de la proforma (opcional).
2025-06-26 11:32:55 +00:00
* @returns Result<CustomerInvoice, Error> - El agregado construido o un error si falla la creación.
*/
buildProformaInCompany(
2025-09-03 18:04:09 +00:00
companyId: UniqueID,
props: Omit<CustomerInvoiceProps, "companyId">,
2025-11-11 18:57:04 +00:00
proformaId?: UniqueID
2025-09-03 18:04:09 +00:00
): Result<CustomerInvoice, Error> {
2025-11-11 18:57:04 +00:00
return CustomerInvoice.create({ ...props, companyId }, proformaId);
2025-06-26 11:32:55 +00:00
}
/**
2025-11-11 18:57:04 +00:00
* Guarda una nueva proforma y devuelve la proforma guardada.
2025-06-26 11:32:55 +00:00
*
2025-11-11 18:57:04 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la proforma.
* @param proforma - La proforma a guardar.
2025-10-03 19:01:38 +00:00
* @param transaction - Transacción activa para la operación.
2025-11-11 18:57:04 +00:00
* @returns Result<CustomerInvoice, Error> - La proforma guardada o un error si falla la operación.
2025-10-03 19:01:38 +00:00
*/
2025-10-04 16:29:14 +00:00
async createInvoiceInCompany(
2025-10-03 19:01:38 +00:00
companyId: UniqueID,
2025-11-11 18:57:04 +00:00
proforma: CustomerInvoice,
2025-10-03 19:01:38 +00:00
transaction: Transaction
): Promise<Result<CustomerInvoice, Error>> {
2025-11-11 18:57:04 +00:00
const result = await this.repository.create(proforma, transaction);
2025-10-03 19:01:38 +00:00
if (result.isFailure) {
return Result.fail(result.error);
}
2025-11-11 18:57:04 +00:00
return this.getProformaByIdInCompany(companyId, proforma.id, transaction);
2025-10-03 19:01:38 +00:00
}
/**
2025-11-11 18:57:04 +00:00
* Actualiza una proforma existente y devuelve la proforma actualizada.
2025-10-03 19:01:38 +00:00
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
2025-11-11 18:57:04 +00:00
* @param proforma - La proforma a guardar.
2025-06-26 11:32:55 +00:00
* @param transaction - Transacción activa para la operación.
2025-11-11 18:57:04 +00:00
* @returns Result<CustomerInvoice, Error> - La proforma guardada o un error si falla la operación.
2025-06-26 11:32:55 +00:00
*/
2025-11-11 18:57:04 +00:00
async updateProformaInCompany(
2025-10-03 19:01:38 +00:00
companyId: UniqueID,
2025-11-11 18:57:04 +00:00
proforma: CustomerInvoice,
2025-10-03 19:01:38 +00:00
transaction: Transaction
2025-09-03 18:04:09 +00:00
): Promise<Result<CustomerInvoice, Error>> {
2025-11-11 18:57:04 +00:00
const result = await this.repository.update(proforma, transaction);
2025-10-03 19:01:38 +00:00
if (result.isFailure) {
return Result.fail(result.error);
}
2025-11-11 18:57:04 +00:00
return this.getProformaByIdInCompany(companyId, proforma.id, transaction);
2025-06-26 11:32:55 +00:00
}
2025-06-26 18:05:33 +00:00
/**
*
* Comprueba si existe o no en persistencia una factura con el ID proporcionado
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
2025-09-03 18:04:09 +00:00
* @param invoiceId - Identificador UUID de la factura.
2025-06-26 18:05:33 +00:00
* @param transaction - Transacción activa para la operación.
* @returns Result<Boolean, Error> - Existe la factura o no.
*/
2025-09-03 18:04:09 +00:00
async existsByIdInCompany(
companyId: UniqueID,
invoiceId: UniqueID,
2025-10-03 19:01:38 +00:00
transaction?: Transaction
2025-09-03 18:04:09 +00:00
): Promise<Result<boolean, Error>> {
return this.repository.existsByIdInCompany(companyId, invoiceId, transaction);
2025-06-26 18:05:33 +00:00
}
2025-06-26 11:32:55 +00:00
/**
* Obtiene una colección de facturas que cumplen con los filtros definidos en un objeto Criteria.
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
2025-06-26 11:32:55 +00:00
* @param criteria - Objeto con condiciones de filtro, paginación y orden.
* @param transaction - Transacción activa para la operación.
2025-09-11 17:52:50 +00:00
* @returns Result<Collection<CustomerInvoiceListDTO>, Error> - Colección de facturas o error.
2025-06-26 11:32:55 +00:00
*/
2025-09-03 18:04:09 +00:00
async findInvoiceByCriteriaInCompany(
companyId: UniqueID,
2025-06-11 15:13:44 +00:00
criteria: Criteria,
transaction?: Transaction
2025-09-11 17:52:50 +00:00
): Promise<Result<Collection<CustomerInvoiceListDTO>, Error>> {
2025-09-03 18:04:09 +00:00
return this.repository.findByCriteriaInCompany(companyId, criteria, transaction);
2025-06-11 15:13:44 +00:00
}
2025-06-26 11:32:55 +00:00
/**
* Recupera una factura por su identificador único.
*
2025-09-03 18:04:09 +00:00
* @param invoiceId - Identificador UUID de la factura.
2025-06-26 11:32:55 +00:00
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice, Error> - Factura encontrada o error.
*/
2025-11-11 18:57:04 +00:00
async getIssueInvoiceByIdInCompany(
2025-09-03 18:04:09 +00:00
companyId: UniqueID,
invoiceId: UniqueID,
transaction?: Transaction
): Promise<Result<CustomerInvoice>> {
2025-11-11 18:57:04 +00:00
return await this.repository.getByIdInCompany(companyId, invoiceId, transaction, {
where: {
is_proforma: false,
},
});
}
/**
* Recupera una proforma por su identificador único.
*
* @param proformaId - Identificador UUID de la proforma.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice, Error> - proforma encontrada o error.
*/
async getProformaByIdInCompany(
companyId: UniqueID,
proformaId: UniqueID,
transaction?: Transaction
): Promise<Result<CustomerInvoice>> {
return await this.repository.getByIdInCompany(companyId, proformaId, transaction, {
where: {
is_proforma: true,
},
});
2025-06-11 15:13:44 +00:00
}
2025-06-26 11:32:55 +00:00
/**
* Actualiza parcialmente una factura existente con nuevos datos.
2025-09-03 18:04:09 +00:00
* No lo guarda en el repositorio.
2025-06-26 11:32:55 +00:00
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
2025-11-11 18:57:04 +00:00
* @param proformaId - Identificador de la factura a actualizar.
2025-06-26 11:32:55 +00:00
* @param changes - Subconjunto de props válidas para aplicar.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice, Error> - Factura actualizada o error.
*/
2025-11-11 18:57:04 +00:00
async patchProformaByIdInCompany(
2025-09-03 18:04:09 +00:00
companyId: UniqueID,
2025-11-11 18:57:04 +00:00
proformaId: UniqueID,
2025-09-03 18:04:09 +00:00
changes: CustomerInvoicePatchProps,
2025-06-11 15:13:44 +00:00
transaction?: Transaction
): Promise<Result<CustomerInvoice, Error>> {
2025-11-11 18:57:04 +00:00
const invoiceResult = await this.getProformaByIdInCompany(companyId, proformaId, transaction);
2025-06-11 15:13:44 +00:00
2025-09-03 18:04:09 +00:00
if (invoiceResult.isFailure) {
return Result.fail(invoiceResult.error);
2025-06-11 15:13:44 +00:00
}
2025-10-04 16:29:14 +00:00
const updated = invoiceResult.data.update(changes);
2025-06-11 15:13:44 +00:00
2025-10-04 16:29:14 +00:00
if (updated.isFailure) {
return Result.fail(updated.error);
2025-06-11 15:13:44 +00:00
}
2025-10-04 16:29:14 +00:00
return Result.ok(updated.data);
2025-06-11 15:13:44 +00:00
}
2025-06-26 11:32:55 +00:00
/**
* Elimina (o marca como eliminada) una factura según su ID.
*
2025-10-23 17:29:52 +00:00
* @param companyId - Identificador de la empresa a la que pertenece la factura.
2025-09-03 18:04:09 +00:00
* @param invoiceId - Identificador UUID de la factura.
2025-06-26 11:32:55 +00:00
* @param transaction - Transacción activa para la operación.
* @returns Result<boolean, Error> - Resultado de la operación.
*/
2025-09-05 11:23:45 +00:00
async deleteInvoiceByIdInCompany(
2025-09-03 18:04:09 +00:00
companyId: UniqueID,
invoiceId: UniqueID,
transaction?: Transaction
2025-10-04 16:29:14 +00:00
): Promise<Result<boolean, Error>> {
2025-09-03 18:04:09 +00:00
return this.repository.deleteByIdInCompany(companyId, invoiceId, transaction);
2025-06-11 15:13:44 +00:00
}
2025-11-07 17:51:18 +00:00
/**
*
* Actualiza el "status" de una proforma
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
* @param proformaId - UUID de la factura a eliminar.
* @param newStatus - nuevo estado
* @param transaction - Transacción activa para la operación.
* @returns Result<boolean, Error>
*/
async updateProformaStatusByIdInCompany(
companyId: UniqueID,
proformaId: UniqueID,
newStatus: CustomerInvoiceStatus,
transaction?: Transaction
): Promise<Result<boolean, Error>> {
return this.repository.updateProformaStatusByIdInCompany(
companyId,
proformaId,
newStatus,
transaction
);
}
2025-06-11 15:13:44 +00:00
}