Presupuestador_web/server/src/contexts/support/application/SendIncidence.useCase.ts
2024-10-01 20:02:16 +02:00

126 lines
3.7 KiB
TypeScript

import {
IUseCase,
IUseCaseError,
IUseCaseRequest,
UseCaseError,
} from "@/contexts/common/application";
import {
DomainError,
IDomainError,
ISendIncidence_Request_DTO,
Result,
TextValueObject,
UTCDateValue,
UniqueID,
} from "@shared/contexts";
import { IInfrastructureError } from "@/contexts/common/infrastructure";
import { Dealer } from "@/contexts/sales/domain";
import { Incidence } from "../domain";
import { ISupportContext } from "../infrastructure";
export interface ISendIncidenceUseCaseRequest extends IUseCaseRequest {
incidenceDTO: ISendIncidence_Request_DTO;
}
export type SendIncidenceResponseOrError =
| Result<never, IUseCaseError> // Misc errors (value objects)
| Result<void, never>; // Success!
export class SendIncidenceUseCase
implements IUseCase<ISendIncidenceUseCaseRequest, Promise<SendIncidenceResponseOrError>>
{
private _context: ISupportContext;
constructor(context: ISupportContext) {
this._context = context;
}
async execute(request: ISendIncidenceUseCaseRequest): Promise<SendIncidenceResponseOrError> {
const { incidenceDTO } = request;
//const QuoteRepository = this._getQuoteRepository();
// Validaciones de datos
if (!this._context.user) {
const message = "Error. Missing User";
return Result.fail(UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message));
}
// Validaciones de datos
if (!this._context.dealer) {
const message = "Error. Missing Dealer";
return Result.fail(UseCaseError.create(UseCaseError.INVALID_INPUT_DATA, message));
}
const dealer = this._context.dealer;
const user = this._context.user;
// Send incidence
const incidenceOrError = this._tryIncidenceInstance(incidenceDTO, dealer);
if (incidenceOrError.isFailure) {
const { error: domainError } = incidenceOrError;
let errorCode = "";
let message = "";
switch (domainError.code) {
// Errores manuales
case DomainError.INVALID_INPUT_DATA:
errorCode = UseCaseError.INVALID_INPUT_DATA;
message = "The issue has some erroneous data.";
break;
default:
errorCode = UseCaseError.UNEXCEPTED_ERROR;
message = domainError.message;
break;
}
return Result.fail(UseCaseError.create(errorCode, message, domainError));
}
const incidence = incidenceOrError.object;
try {
const sendInfo = await this._context.services?.emailService.sendMail({
from: this._context.defaults.support.from,
to: this._context.defaults.support.from,
subject: this._context.defaults.support.subject,
html: `<p>Distribuidor: ${dealer.name.toString()}</p>
<p>Email: ${user.email.toString()}</p>
<br>
<p>${incidence.description.toString()}</p>`,
});
return Result.ok<void>();
} catch (error: unknown) {
const _error = error as IInfrastructureError;
return Result.fail(UseCaseError.create(UseCaseError.UNEXCEPTED_ERROR, _error.message));
}
}
private _tryIncidenceInstance(
incidenceDTO: ISendIncidence_Request_DTO,
dealer: Dealer
): Result<Incidence, IDomainError> {
const dateOrError = UTCDateValue.createCurrentDate();
if (dateOrError.isFailure) {
return Result.fail(dateOrError.error);
}
const descriptionOrError = TextValueObject.create(incidenceDTO.incidence);
if (descriptionOrError.isFailure) {
return Result.fail(descriptionOrError.error);
}
return Incidence.create(
{
date: dateOrError.object,
description: descriptionOrError.object,
dealerId: dealer.id,
},
UniqueID.generateNewID().object
);
}
}