Uecko_ERP/modules/customers/src/api/infrastructure/sequelize/customer.repository.ts
2025-09-03 12:41:12 +02:00

155 lines
4.7 KiB
TypeScript

import { EntityNotFoundError, SequelizeRepository, translateSequelizeError } from "@erp/core/api";
import { Criteria, CriteriaToSequelizeConverter } from "@repo/rdx-criteria/server";
import { UniqueID } from "@repo/rdx-ddd";
import { Collection, Result } from "@repo/rdx-utils";
import { Transaction } from "sequelize";
import { Customer, ICustomerRepository } from "../../domain";
import { ICustomerMapper } from "../mappers/customer.mapper";
import { CustomerModel } from "./customer.model";
export class CustomerRepository
extends SequelizeRepository<Customer>
implements ICustomerRepository
{
private readonly mapper!: ICustomerMapper;
constructor(mapper: ICustomerMapper) {
super();
this.mapper = mapper;
}
/**
*
* Guarda un nuevo cliente o actualiza uno existente.
*
* @param customer - El cliente a guardar.
* @param transaction - Transacción activa para la operación.
* @returns Result<Customer, Error>
*/
async save(customer: Customer, transaction: Transaction): Promise<Result<Customer, Error>> {
try {
const data = this.mapper.mapToPersistence(customer);
const [instance] = await CustomerModel.upsert(data, { transaction, returning: true });
const savedCustomer = this.mapper.mapToDomain(instance);
return savedCustomer;
} catch (err: unknown) {
return Result.fail(translateSequelizeError(err));
}
}
/**
* Comprueba si existe un Customer con un `id` dentro de una `company`.
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
* @param id - Identificador UUID del cliente.
* @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 CustomerModel.count({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
return Result.ok(Boolean(count > 0));
} catch (error: any) {
return Result.fail(translateSequelizeError(error));
}
}
/**
* Recupera un cliente por su ID y companyId.
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
* @param id - Identificador UUID del cliente.
* @param transaction - Transacción activa para la operación.
* @returns Result<Customer, Error>
*/
async getByIdInCompany(
companyId: UniqueID,
id: UniqueID,
transaction?: Transaction
): Promise<Result<Customer, Error>> {
try {
const row = await CustomerModel.findOne({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
if (!row) {
return Result.fail(new EntityNotFoundError("Customer", "id", id.toString()));
}
const customer = this.mapper.mapToDomain(row);
return customer;
} catch (error: any) {
return Result.fail(translateSequelizeError(error));
}
}
/**
* Recupera múltiples customers dentro de una empresa según un criterio dinámico (búsqueda, paginación, etc.).
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
* @param criteria - Criterios de búsqueda.
* @param transaction - Transacción activa para la operación.
* @returns Result<Collection<Customer>, Error>
*
* @see Criteria
*/
async findByCriteriaInCompany(
companyId: UniqueID,
criteria: Criteria,
transaction?: Transaction
): Promise<Result<Collection<Customer>>> {
try {
const converter = new CriteriaToSequelizeConverter();
const query = converter.convert(criteria);
query.where = {
...query.where,
company_id: companyId.toString(),
};
const instances = await CustomerModel.findAll({
...query,
transaction,
});
return this.mapper.mapArrayToDomain(instances);
} catch (err: unknown) {
return Result.fail(translateSequelizeError(err));
}
}
/**
*
* Elimina o marca como eliminado un cliente.
*
* @param companyId - Identificador UUID de la empresa a la que pertenece el cliente.
* @param id - UUID del cliente a eliminar.
* @param transaction - Transacción activa para la operación.
* @returns Result<void, Error>
*/
async deleteByIdInCompany(
companyId: UniqueID,
id: UniqueID,
transaction: Transaction
): Promise<Result<void>> {
try {
const deleted = await CustomerModel.destroy({
where: { id: id.toString(), company_id: companyId.toString() },
transaction,
});
return Result.ok<void>();
} catch (err: unknown) {
return Result.fail(translateSequelizeError(err));
}
}
}