75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
import { DuplicateEntityError } from "@erp/core/api";
|
|
import type { UniqueID } from "@repo/rdx-ddd";
|
|
import { Result } from "@repo/rdx-utils";
|
|
|
|
import { Customer, type ICustomerCreateProps } from "../../domain";
|
|
import type { ICustomerRepository } from "../repositories";
|
|
import { CustomerNotExistsInCompanySpecification } from "../specs";
|
|
|
|
export interface ICustomerCreator {
|
|
create(params: {
|
|
companyId: UniqueID;
|
|
id: UniqueID;
|
|
props: ICustomerCreateProps;
|
|
transaction?: unknown;
|
|
}): Promise<Result<Customer, Error>>;
|
|
}
|
|
|
|
type CustomerCreatorDeps = {
|
|
repository: ICustomerRepository;
|
|
};
|
|
|
|
export class CustomerCreator implements ICustomerCreator {
|
|
private readonly repository: ICustomerRepository;
|
|
|
|
constructor(deps: CustomerCreatorDeps) {
|
|
this.repository = deps.repository;
|
|
}
|
|
|
|
async create(params: {
|
|
companyId: UniqueID;
|
|
id: UniqueID;
|
|
props: ICustomerCreateProps;
|
|
transaction?: unknown;
|
|
}): Promise<Result<Customer, Error>> {
|
|
const { companyId, id, props, transaction } = params;
|
|
|
|
// 1. Verificar unicidad
|
|
const spec = new CustomerNotExistsInCompanySpecification(
|
|
this.repository,
|
|
companyId,
|
|
transaction
|
|
);
|
|
|
|
const isNew = await spec.isSatisfiedBy(id);
|
|
|
|
if (!isNew) {
|
|
return Result.fail(new DuplicateEntityError("Customer", "id", String(id)));
|
|
}
|
|
|
|
// 2. Crear agregado
|
|
const createResult = Customer.create(
|
|
{
|
|
...props,
|
|
companyId,
|
|
},
|
|
id
|
|
);
|
|
|
|
if (createResult.isFailure) {
|
|
return createResult;
|
|
}
|
|
|
|
const newCustomer = createResult.data;
|
|
|
|
// 3. Persistir agregado
|
|
const saveResult = await this.repository.create(newCustomer, transaction);
|
|
|
|
if (saveResult.isFailure) {
|
|
return Result.fail(saveResult.error);
|
|
}
|
|
|
|
return Result.ok(newCustomer);
|
|
}
|
|
}
|