Uecko_ERP/modules/customer-invoices/src/api/infrastructure/sequelize/customer-invoice.repository.ts

193 lines
5.8 KiB
TypeScript
Raw Normal View History

2025-09-03 10:41:12 +00:00
import { EntityNotFoundError, SequelizeRepository, translateSequelizeError } from "@erp/core/api";
2025-06-26 11:32:55 +00:00
import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/server";
2025-06-11 15:13:44 +00:00
import { UniqueID } from "@repo/rdx-ddd";
import { Collection, Result } from "@repo/rdx-utils";
import { Transaction } from "sequelize";
2025-06-12 06:55:17 +00:00
import { CustomerInvoice, ICustomerInvoiceRepository } from "../../domain";
import { ICustomerInvoiceMapper } from "../mappers/customer-invoice.mapper";
import { CustomerInvoiceModel } from "./customer-invoice.model";
2025-06-11 15:13:44 +00:00
2025-06-12 06:55:17 +00:00
export class CustomerInvoiceRepository
extends SequelizeRepository<CustomerInvoice>
implements ICustomerInvoiceRepository
{
2025-06-26 11:32:55 +00:00
private readonly mapper!: ICustomerInvoiceMapper;
2025-06-11 15:13:44 +00:00
constructor(mapper: ICustomerInvoiceMapper) {
super();
2025-06-26 11:32:55 +00:00
this.mapper = mapper;
2025-06-11 15:13:44 +00:00
}
2025-08-23 11:57:48 +00:00
// Listado por tenant con criteria saneada
/* async searchInCompany(criteria: any, companyId: string): Promise<{
rows: InvoiceListRow[];
total: number;
limit: number;
offset: number;
}> {
const { where, order, limit, offset, attributes } = sanitizeListCriteria(criteria);
// WHERE con scope de company
const scopedWhere = { ...where, company_id: companyId };
const options: FindAndCountOptions = {
where: scopedWhere,
order,
limit,
offset,
attributes,
raw: true, // devolvemos objetos planos -> más rápido
nest: false,
distinct: true // por si en el futuro añadimos includes no duplicar count
};
const { rows, count } = await CustomerInvoiceModel.findAndCountAll(options);
return {
rows: rows as unknown as InvoiceListRow[],
total: typeof count === "number" ? count : (count as any[]).length,
limit,
offset,
};
} */
2025-06-26 11:32:55 +00:00
/**
*
* Persiste una nueva factura o actualiza una existente.
*
* @param invoice - El agregado a guardar.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice, Error>
*/
async save(
invoice: CustomerInvoice,
transaction: Transaction
): Promise<Result<CustomerInvoice, Error>> {
try {
const data = this.mapper.mapToPersistence(invoice);
2025-09-03 10:41:12 +00:00
const [instance] = await CustomerInvoiceModel.upsert(data, { transaction, returning: true });
const savedInvoice = this.mapper.mapToDomain(instance);
return savedInvoice;
2025-06-26 11:32:55 +00:00
} catch (err: unknown) {
2025-08-26 18:55:59 +00:00
return Result.fail(translateSequelizeError(err));
2025-06-26 11:32:55 +00:00
}
2025-06-11 15:13:44 +00:00
}
2025-09-03 10:41:12 +00:00
/**
* Comprueba si existe una factura con un `id` dentro de una `company`.
*
* @param companyId - Identificador UUID de la empresa a la que pertenece la factura.
* @param id - Identificador UUID de la factura.
* @param transaction - Transacción activa para la operación.
* @returns Result<boolean, Error>
*/
async existsByIdInCompany(
companyId: UniqueID,
id: UniqueID,
transaction?: Transaction
): Promise<Result<boolean, Error>> {
try {
const count = await CustomerInvoiceModel.count({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
return Result.ok(Boolean(count > 0));
} catch (error: any) {
return Result.fail(translateSequelizeError(error));
}
}
2025-06-26 11:32:55 +00:00
/**
*
* Busca una factura por su identificador único.
2025-09-03 10:41:12 +00:00
*
* @param companyId - Identificador UUID de la empresa a la que pertenece la factura.
2025-06-26 11:32:55 +00:00
* @param id - UUID de la factura.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice, Error>
*/
2025-09-03 10:41:12 +00:00
async getByIdInCompany(
companyId: UniqueID,
id: UniqueID,
transaction: Transaction
): Promise<Result<CustomerInvoice, Error>> {
2025-06-11 15:13:44 +00:00
try {
2025-09-03 10:41:12 +00:00
const row = await CustomerInvoiceModel.findOne({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
2025-06-26 11:32:55 +00:00
2025-09-03 10:41:12 +00:00
if (!row) {
return Result.fail(new EntityNotFoundError("CustomerInvoice", "id", id.toString()));
2025-06-26 11:32:55 +00:00
}
2025-06-11 15:13:44 +00:00
2025-09-03 10:41:12 +00:00
const customer = this.mapper.mapToDomain(row);
return customer;
2025-06-26 11:32:55 +00:00
} catch (err: unknown) {
2025-08-26 18:55:59 +00:00
return Result.fail(translateSequelizeError(err));
2025-06-11 15:13:44 +00:00
}
}
2025-06-26 11:32:55 +00:00
/**
*
* Consulta facturas usando un objeto Criteria (filtros, orden, paginación).
2025-09-03 10:41:12 +00:00
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
2025-06-26 11:32:55 +00:00
* @param criteria - Criterios de búsqueda.
* @param transaction - Transacción activa para la operación.
* @returns Result<CustomerInvoice[], Error>
*
* @see Criteria
*/
2025-09-03 10:41:12 +00:00
public async findByCriteriaInCompany(
companyId: UniqueID,
2025-06-11 15:13:44 +00:00
criteria: Criteria,
2025-06-26 11:32:55 +00:00
transaction: Transaction
2025-06-11 15:13:44 +00:00
): Promise<Result<Collection<CustomerInvoice>, Error>> {
try {
2025-06-26 11:32:55 +00:00
const converter = new CriteriaToSequelizeConverter();
const query = converter.convert(criteria);
2025-09-03 10:41:12 +00:00
query.where = {
...query.where,
company_id: companyId.toString(),
};
2025-06-26 18:05:33 +00:00
const instances = await CustomerInvoiceModel.findAll({
2025-06-26 11:32:55 +00:00
...query,
2025-06-11 15:13:44 +00:00
transaction,
});
2025-06-26 11:32:55 +00:00
return this.mapper.mapArrayToDomain(instances);
} catch (err: unknown) {
2025-08-26 18:55:59 +00:00
return Result.fail(translateSequelizeError(err));
2025-06-11 15:13:44 +00:00
}
}
2025-06-26 11:32:55 +00:00
/**
*
* Elimina o marca como eliminada una factura.
2025-09-03 10:41:12 +00:00
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
2025-06-26 11:32:55 +00:00
* @param id - UUID de la factura a eliminar.
* @param transaction - Transacción activa para la operación.
* @returns Result<void, Error>
*/
2025-09-03 10:41:12 +00:00
async deleteByIdInCompany(
companyId: UniqueID,
id: UniqueID,
transaction: any
): Promise<Result<void, Error>> {
2025-06-11 15:13:44 +00:00
try {
2025-09-03 10:41:12 +00:00
const deleted = await CustomerInvoiceModel.destroy({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
2025-06-26 11:32:55 +00:00
return Result.ok<void>();
} catch (err: unknown) {
2025-08-26 18:55:59 +00:00
return Result.fail(translateSequelizeError(err));
2025-06-11 15:13:44 +00:00
}
}
}