Presupuestador_web/server/src/contexts/sales/application/Quote/SendQuote.useCase.ts
2024-10-03 16:23:46 +02:00

107 lines
3.1 KiB
TypeScript

import {
IUseCase,
IUseCaseError,
IUseCaseRequest,
UseCaseError,
} from "@/contexts/common/application/useCases";
import { IRepositoryManager } from "@/contexts/common/domain";
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
import {
DomainError,
ISendQuote_Request_DTO,
Result,
UniqueID,
UTCDateValue,
} from "@shared/contexts";
import { IQuoteRepository } from "../../domain";
export interface ISendQuoteUseCaseRequest extends IUseCaseRequest {
id: UniqueID;
sentQuoteDTO: ISendQuote_Request_DTO;
}
export type SendQuoteResponseOrError =
| Result<never, IUseCaseError> // Misc errors (value objects)
| Result<void, never>; // Success!
export class SendQuoteUseCase
implements IUseCase<ISendQuoteUseCaseRequest, Promise<SendQuoteResponseOrError>>
{
private _adapter: ISequelizeAdapter;
private _repositoryManager: IRepositoryManager;
constructor(props: { adapter: ISequelizeAdapter; repositoryManager: IRepositoryManager }) {
this._adapter = props.adapter;
this._repositoryManager = props.repositoryManager;
}
async execute(request: ISendQuoteUseCaseRequest): Promise<SendQuoteResponseOrError> {
const {
id,
sentQuoteDTO: { sent_date },
} = request;
const quoteRepository = this._getQuoteRepository();
// Comprobar que existe el Quote
const idExists = await quoteRepository().exists(id);
if (!idExists) {
const message = `Quote ID not found`;
return Result.fail(
UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, message, {
path: "id",
})
);
}
// //
// regla de negocio -> no poder enviar un quote enviado
// regla de negocio -> no poder enviar un quote que no esté aceptado
// Comprobar el status
const sentDateOrError = UTCDateValue.create(sent_date);
if (sentDateOrError.isFailure) {
const { error: domainError } = sentDateOrError;
let errorCode = "";
let message = "";
switch (domainError.code) {
// Errores manuales
case DomainError.INVALID_INPUT_DATA:
errorCode = UseCaseError.INVALID_INPUT_DATA;
message = "La fecha de envío no es correcta";
break;
default:
errorCode = UseCaseError.UNEXCEPTED_ERROR;
message = domainError.message;
break;
}
return Result.fail(UseCaseError.create(errorCode, message, domainError));
}
const transaction = this._adapter.startTransaction();
try {
await transaction.complete(async (t) => {
const quoteRepo = quoteRepository({ transaction: t });
await quoteRepo.updateSentDateById(id, sentDateOrError.object);
});
return Result.ok<void>();
} catch (error: unknown) {
//const _error = error as IInfrastructureError;
return Result.fail(
UseCaseError.create(
UseCaseError.REPOSITORY_ERROR,
"Error al establecer el nuevo estado en la cotización"
)
);
}
}
private _getQuoteRepository() {
return this._repositoryManager.getRepository<IQuoteRepository>("Quote");
}
}