155 lines
4.7 KiB
TypeScript
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));
|
|
}
|
|
}
|
|
}
|