137 lines
4.2 KiB
TypeScript
137 lines
4.2 KiB
TypeScript
import { IUseCase, IUseCaseError, UseCaseError } from "@/contexts/common/application";
|
|
import { IRepositoryManager } from "@/contexts/common/domain";
|
|
import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
|
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
|
import {
|
|
CurrencyData,
|
|
DomainError,
|
|
ICreateDealer_Request_DTO,
|
|
IDomainError,
|
|
Language,
|
|
Name,
|
|
Result,
|
|
UniqueID,
|
|
ensureIdIsValid,
|
|
ensureNameIsValid,
|
|
} from "@shared/contexts";
|
|
import { Dealer, DealerStatus, IDealerRepository } from "../../domain";
|
|
|
|
export type CreateDealerResponseOrError =
|
|
| Result<never, IUseCaseError> // Misc errors (value objects)
|
|
| Result<Dealer, never>; // Success!
|
|
|
|
export class CreateDealerUseCase
|
|
implements IUseCase<ICreateDealer_Request_DTO, Promise<CreateDealerResponseOrError>>
|
|
{
|
|
private _adapter: ISequelizeAdapter;
|
|
private _repositoryManager: IRepositoryManager;
|
|
|
|
constructor(props: { adapter: ISequelizeAdapter; repositoryManager: IRepositoryManager }) {
|
|
this._adapter = props.adapter;
|
|
this._repositoryManager = props.repositoryManager;
|
|
}
|
|
|
|
async execute(request: ICreateDealer_Request_DTO) {
|
|
const { id, name } = request;
|
|
|
|
// Validaciones de datos
|
|
const idOrError = ensureIdIsValid(id);
|
|
if (idOrError.isFailure) {
|
|
const message = idOrError.error.message; //`Dealer ID ${dealerDTO.id} is not valid`;
|
|
return Result.fail(
|
|
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [{ path: "id" }])
|
|
);
|
|
}
|
|
|
|
const nameOrError = ensureNameIsValid(name);
|
|
if (nameOrError.isFailure) {
|
|
const message = nameOrError.error.message; //`Dealer ID ${dealerDTO.id} is not valid`;
|
|
return Result.fail(
|
|
UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message, [{ path: "name" }])
|
|
);
|
|
}
|
|
|
|
// Comprobar que no existe un usuario previo con esos datos
|
|
const dealerRepository = this._getDealerRepository();
|
|
|
|
const idExists = await dealerRepository().exists(idOrError.object);
|
|
if (idExists) {
|
|
const message = `Another dealer with same ID exists`;
|
|
return Result.fail(
|
|
UseCaseError.create(UseCaseError.RESOURCE_ALREADY_EXITS, message, {
|
|
path: "id",
|
|
})
|
|
);
|
|
}
|
|
|
|
// Crear dealer
|
|
const dealerOrError = this._tryCreateDealerInstance(request, idOrError.object);
|
|
|
|
if (dealerOrError.isFailure) {
|
|
const { error: domainError } = dealerOrError;
|
|
let errorCode = "";
|
|
let message = "";
|
|
|
|
switch (domainError.code) {
|
|
case DomainError.INVALID_INPUT_DATA:
|
|
errorCode = UseCaseError.INVALID_INPUT_DATA;
|
|
message = "El distribuidor tiene algún dato erróneo.";
|
|
break;
|
|
|
|
default:
|
|
errorCode = UseCaseError.UNEXCEPTED_ERROR;
|
|
message = domainError.message;
|
|
break;
|
|
}
|
|
|
|
return Result.fail(UseCaseError.create(errorCode, message, domainError));
|
|
}
|
|
|
|
return this._saveDealer(dealerOrError.object);
|
|
}
|
|
|
|
private async _saveDealer(dealer: Dealer) {
|
|
// Guardar el contacto
|
|
const transaction = this._adapter.startTransaction();
|
|
const dealerRepository = this._getDealerRepository();
|
|
let dealerRepo: IDealerRepository;
|
|
|
|
try {
|
|
await transaction.complete(async (t) => {
|
|
dealerRepo = dealerRepository({ transaction: t });
|
|
await dealerRepo.create(dealer);
|
|
});
|
|
|
|
return Result.ok<Dealer>(dealer);
|
|
} catch (error: unknown) {
|
|
const _error = error as IInfrastructureError;
|
|
return Result.fail(UseCaseError.create(UseCaseError.REPOSITORY_ERROR, _error.message));
|
|
}
|
|
}
|
|
|
|
private _tryCreateDealerInstance(
|
|
dealerDTO: ICreateDealer_Request_DTO,
|
|
dealerId: UniqueID
|
|
): Result<Dealer, IDomainError> {
|
|
const nameOrError = Name.create(dealerDTO.name);
|
|
if (nameOrError.isFailure) {
|
|
return Result.fail(nameOrError.error);
|
|
}
|
|
|
|
return Dealer.create(
|
|
{
|
|
name: nameOrError.object,
|
|
currency: CurrencyData.createDefaultCode().object,
|
|
language: Language.createDefaultCode().object,
|
|
status: DealerStatus.createActive(),
|
|
//user_id: user
|
|
},
|
|
dealerId
|
|
);
|
|
}
|
|
|
|
private _getDealerRepository() {
|
|
return this._repositoryManager.getRepository<IDealerRepository>("Dealer");
|
|
}
|
|
}
|