2025-08-11 17:49:52 +00:00
|
|
|
import { DuplicateEntityError, ITransactionManager } from "@erp/core/api";
|
2025-08-26 18:55:59 +00:00
|
|
|
import { UniqueID } from "@repo/rdx-ddd";
|
2025-08-11 17:49:52 +00:00
|
|
|
import { Result } from "@repo/rdx-utils";
|
|
|
|
|
import { Transaction } from "sequelize";
|
2025-08-26 18:55:59 +00:00
|
|
|
import { CreateCustomerRequestDTO } from "../../../common";
|
2025-09-01 14:07:59 +00:00
|
|
|
import { CustomerService } from "../../domain";
|
2025-08-14 14:58:13 +00:00
|
|
|
import { CreateCustomersAssembler } from "./assembler";
|
2025-09-01 14:07:59 +00:00
|
|
|
import { mapDTOToCreateCustomerProps } from "./map-dto-to-create-customer-props";
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-25 17:42:56 +00:00
|
|
|
type CreateCustomerUseCaseInput = {
|
2025-08-26 18:55:59 +00:00
|
|
|
dto: CreateCustomerRequestDTO;
|
2025-09-01 16:38:00 +00:00
|
|
|
companyId: UniqueID;
|
2025-08-25 17:42:56 +00:00
|
|
|
};
|
|
|
|
|
|
2025-08-11 17:49:52 +00:00
|
|
|
export class CreateCustomerUseCase {
|
|
|
|
|
constructor(
|
2025-09-01 14:07:59 +00:00
|
|
|
private readonly service: CustomerService,
|
2025-08-11 17:49:52 +00:00
|
|
|
private readonly transactionManager: ITransactionManager,
|
2025-08-14 14:58:13 +00:00
|
|
|
private readonly assembler: CreateCustomersAssembler
|
2025-08-11 17:49:52 +00:00
|
|
|
) {}
|
|
|
|
|
|
2025-08-25 17:42:56 +00:00
|
|
|
public execute(params: CreateCustomerUseCaseInput) {
|
2025-09-01 16:38:00 +00:00
|
|
|
const { dto, companyId } = params;
|
2025-08-25 17:42:56 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
// 1) Mapear DTO → props de dominio
|
2025-09-01 14:07:59 +00:00
|
|
|
const dtoResult = mapDTOToCreateCustomerProps(dto);
|
2025-08-26 18:55:59 +00:00
|
|
|
if (dtoResult.isFailure) {
|
|
|
|
|
return Result.fail(dtoResult.error);
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-09-01 16:38:00 +00:00
|
|
|
const { props, id } = dtoResult.data;
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-09-01 16:38:00 +00:00
|
|
|
console.debug("Creating customer with props:", props);
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
// 3) Construir entidad de dominio
|
2025-09-01 16:38:00 +00:00
|
|
|
const buildResult = this.service.buildCustomerInCompany(companyId, props, id);
|
2025-08-26 18:55:59 +00:00
|
|
|
if (buildResult.isFailure) {
|
|
|
|
|
return Result.fail(buildResult.error);
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
|
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
const newCustomer = buildResult.data;
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
console.debug("Built new customer entity:", newCustomer);
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
// 4) Ejecutar bajo transacción: verificar duplicado → persistir → ensamblar vista
|
|
|
|
|
return this.transactionManager.complete(async (tx: Transaction) => {
|
|
|
|
|
const existsGuard = await this.ensureNotExists(companyId, id, tx);
|
|
|
|
|
if (existsGuard.isFailure) {
|
|
|
|
|
return Result.fail(existsGuard.error);
|
|
|
|
|
}
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
console.debug("No existing customer with same ID found, proceeding to save.");
|
2025-08-11 17:49:52 +00:00
|
|
|
|
2025-08-26 18:55:59 +00:00
|
|
|
const saveResult = await this.service.saveCustomer(newCustomer, tx);
|
|
|
|
|
if (saveResult.isFailure) {
|
|
|
|
|
return Result.fail(saveResult.error);
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|
2025-08-26 18:55:59 +00:00
|
|
|
|
|
|
|
|
const viewDTO = this.assembler.toDTO(saveResult.data);
|
|
|
|
|
console.debug("Assembled view DTO:", viewDTO);
|
|
|
|
|
|
|
|
|
|
return Result.ok(viewDTO);
|
2025-08-11 17:49:52 +00:00
|
|
|
});
|
|
|
|
|
}
|
2025-08-26 18:55:59 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
Verifica que no exista un Customer con el mismo id en la companyId.
|
|
|
|
|
*/
|
|
|
|
|
private async ensureNotExists(
|
|
|
|
|
companyId: UniqueID,
|
|
|
|
|
id: UniqueID,
|
|
|
|
|
transaction: Transaction
|
|
|
|
|
): Promise<Result<void, Error>> {
|
|
|
|
|
const existsResult = await this.service.existsByIdInCompany(companyId, id, transaction);
|
|
|
|
|
if (existsResult.isFailure) {
|
|
|
|
|
return Result.fail(existsResult.error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (existsResult.data) {
|
|
|
|
|
return Result.fail(new DuplicateEntityError("Customer", "id", String(id)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Result.ok<void>(undefined);
|
|
|
|
|
}
|
2025-08-11 17:49:52 +00:00
|
|
|
}
|