Presupuestador_web/server/src/contexts/profile/application/UpdateProfile.useCase.ts

107 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-06-17 16:54:30 +00:00
import {
IUseCase,
IUseCaseError,
IUseCaseRequest,
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 { DomainError, IUpdateProfile_Request_DTO, Result, UniqueID } from "@shared/contexts";
import { IProfileRepository, Profile } from "../domain";
export interface IUpdateProfileUseCaseRequest extends IUseCaseRequest {
id: UniqueID;
profileDTO: IUpdateProfile_Request_DTO;
}
export type UpdateProfileResponseOrError =
| Result<never, IUseCaseError> // Misc errors (value objects)
| Result<Profile, never>; // Success!
export class UpdateProfileUseCase
implements IUseCase<IUpdateProfileUseCaseRequest, Promise<UpdateProfileResponseOrError>>
{
private _adapter: ISequelizeAdapter;
private _repositoryManager: IRepositoryManager;
constructor(props: { adapter: ISequelizeAdapter; repositoryManager: IRepositoryManager }) {
this._adapter = props.adapter;
this._repositoryManager = props.repositoryManager;
}
async execute(request: IUpdateProfileUseCaseRequest): Promise<UpdateProfileResponseOrError> {
const { id, profileDTO } = request;
const profileRepository = this._getProfileRepository();
// Comprobar que existe el profile
const idExists = await profileRepository().exists(id);
if (!idExists) {
const message = `Profile not found`;
return Result.fail(
UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, message, {
path: "id",
})
);
}
// Crear perfil con datos actualizados
const profileOrError = Profile.create(
{
contactInformation: profileDTO.contact_information,
defaultPaymentMethod: profileDTO.default_payment_method,
defaultLegalTerms: profileDTO.default_legal_terms,
defaultNotes: profileDTO.default_notes,
defaultQuoteValidity: profileDTO.default_quote_validity,
},
id
);
if (profileOrError.isFailure) {
const { error: domainError } = profileOrError;
let errorCode = "";
let message = "";
switch (domainError.code) {
// Errores manuales
case DomainError.INVALID_INPUT_DATA:
errorCode = UseCaseError.INVALID_INPUT_DATA;
message = "The profile has some incorrect data";
break;
default:
errorCode = UseCaseError.UNEXCEPTED_ERROR;
message = domainError.message;
break;
}
return Result.fail(UseCaseError.create(errorCode, message, domainError));
}
// Guardar los cambios
return this._saveProfile(profileOrError.object);
}
private async _saveProfile(updatedProfile: Profile) {
// Guardar el contacto
const transaction = this._adapter.startTransaction();
const profileRepository = this._getProfileRepository();
try {
await transaction.complete(async (t) => {
const profileRepo = profileRepository({ transaction: t });
await profileRepo.update(updatedProfile);
});
return Result.ok<Profile>(updatedProfile);
} catch (error: unknown) {
const _error = error as IInfrastructureError;
return Result.fail(UseCaseError.create(UseCaseError.REPOSITORY_ERROR, _error.message));
}
}
private _getProfileRepository() {
return this._repositoryManager.getRepository<IProfileRepository>("Profile");
}
}