.
This commit is contained in:
parent
1f6de61a4b
commit
42320f2012
@ -121,35 +121,22 @@ export class CreateUserUseCase
|
||||
|
||||
switch (domainError.code) {
|
||||
case User.ERROR_USER_WITHOUT_NAME:
|
||||
return Result.fail(
|
||||
UseCaseError.create(
|
||||
UseCaseError.INVALID_INPUT_DATA,
|
||||
"El usuario debe tener un nombre.",
|
||||
domainError,
|
||||
),
|
||||
);
|
||||
errorCode = UseCaseError.INVALID_INPUT_DATA;
|
||||
message = "El usuario debe tener un nombre.";
|
||||
break;
|
||||
|
||||
case DomainError.INVALID_INPUT_DATA:
|
||||
errorCode = UseCaseError.INVALID_INPUT_DATA;
|
||||
message = domainError.message;
|
||||
return Result.fail(
|
||||
UseCaseError.create(
|
||||
UseCaseError.INVALID_INPUT_DATA,
|
||||
"El usuario tiene algún dato erróneo.",
|
||||
domainError,
|
||||
),
|
||||
);
|
||||
message = "El usuario tiene algún dato erróneo.";
|
||||
break;
|
||||
|
||||
default:
|
||||
errorCode = UseCaseError.UNEXCEPTED_ERROR;
|
||||
message = domainError.message;
|
||||
return Result.fail(
|
||||
UseCaseError.create(errorCode, message, domainError),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return Result.fail(UseCaseError.create(errorCode, message, domainError));
|
||||
}
|
||||
|
||||
return this._saveUser(userOrError.object);
|
||||
|
||||
@ -3,45 +3,20 @@ import {
|
||||
IUseCaseError,
|
||||
IUseCaseRequest,
|
||||
UseCaseError,
|
||||
} from "@/contexts/common/application/useCases";
|
||||
import { IRepositoryManager } from "@/contexts/common/domain";
|
||||
} from "@/contexts/common/application";
|
||||
import { IRepositoryManager, Password } from "@/contexts/common/domain";
|
||||
import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
||||
import { ISequelizeAdapter } from "@/contexts/common/infrastructure/sequelize";
|
||||
import {
|
||||
AddressTitle,
|
||||
City,
|
||||
Collection,
|
||||
Country,
|
||||
DomainError,
|
||||
Email,
|
||||
IDomainError,
|
||||
IUpdateUser_DTO,
|
||||
IUpdateUser_Request_DTO,
|
||||
Note,
|
||||
PostalCode,
|
||||
Province,
|
||||
Name,
|
||||
Result,
|
||||
ResultCollection,
|
||||
Street,
|
||||
UniqueID,
|
||||
UserEmail,
|
||||
UserJobTitle,
|
||||
UserName,
|
||||
UserPhone,
|
||||
UserTIN,
|
||||
ensureIdIsValid,
|
||||
} from "@shared/contexts";
|
||||
|
||||
import { IInfrastructureError } from "@/contexts/common/infrastructure";
|
||||
import {
|
||||
IBillingAddressUser_DTO,
|
||||
IShippingAddressUser_DTO,
|
||||
} from "@shared/contexts/users/application/dto/IUserAddressDTO";
|
||||
import {
|
||||
IUserRepository,
|
||||
User,
|
||||
UserAddressType,
|
||||
UserShippingAddress,
|
||||
} from "../domain";
|
||||
import { existsUserByID } from "./userServices";
|
||||
import { IUserRepository, User } from "../domain";
|
||||
|
||||
export interface IUpdateUserUseCaseRequest extends IUseCaseRequest {
|
||||
id: UniqueID;
|
||||
@ -67,277 +42,64 @@ export class UpdateUserUseCase
|
||||
this._repositoryManager = props.repositoryManager;
|
||||
}
|
||||
|
||||
private getRepositoryByName<T>(name: string) {
|
||||
return this._repositoryManager.getRepository<T>(name);
|
||||
}
|
||||
|
||||
async execute(
|
||||
request: IUpdateUserUseCaseRequest,
|
||||
): Promise<UpdateUserResponseOrError> {
|
||||
const { id, userDTO } = request;
|
||||
const userRepository = this.getRepositoryByName<IUserRepository>("User");
|
||||
|
||||
// Validaciones de datos
|
||||
const userIdOrError = ensureIdIsValid(userDTO.id);
|
||||
if (userIdOrError.isFailure) {
|
||||
return Result.fail(
|
||||
UseCaseError.create(
|
||||
UseCaseError.INVALID_INPUT_DATA,
|
||||
"User ID is not valid",
|
||||
userIdOrError.error,
|
||||
),
|
||||
);
|
||||
}
|
||||
const userRepository = this._getUserRepository();
|
||||
|
||||
// Comprobar que existe el user
|
||||
const idExists = await existsUserByID(
|
||||
userIdOrError.object,
|
||||
this._adapter,
|
||||
userRepository,
|
||||
);
|
||||
const idExists = await userRepository().existsUserWithId(id);
|
||||
if (!idExists) {
|
||||
const message = `User with ID ${id.toString()} not found`;
|
||||
return Result.fail<IUseCaseError>(
|
||||
UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, message, [
|
||||
{ path: "id" },
|
||||
]),
|
||||
const message = `User ID not found`;
|
||||
return Result.fail(
|
||||
UseCaseError.create(UseCaseError.NOT_FOUND_ERROR, message, {
|
||||
path: "id",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Crear user
|
||||
// Crear usuario
|
||||
const userOrError = this._tryCreateUserInstance(userDTO, id);
|
||||
|
||||
if (userOrError.isFailure) {
|
||||
const { error: domainError } = userOrError;
|
||||
let errorCode = "";
|
||||
let message = "";
|
||||
let payload = {};
|
||||
|
||||
switch (domainError.code) {
|
||||
// Errores manuales
|
||||
case User.ERROR_CUSTOMER_WITHOUT_NAME:
|
||||
case User.ERROR_USER_WITHOUT_NAME:
|
||||
errorCode = UseCaseError.INVALID_INPUT_DATA;
|
||||
message = "El usuario debe ser una compañía o tener nombre.";
|
||||
payload = [{ path: "first_name" }, { path: "company_name" }];
|
||||
message = "El usuario debe tener un nombre.";
|
||||
break;
|
||||
|
||||
// Value object error
|
||||
case DomainError.INVALID_INPUT_DATA:
|
||||
errorCode = UseCaseError.INVALID_INPUT_DATA;
|
||||
message = domainError.message;
|
||||
payload = domainError.payload;
|
||||
message = "El usuario tiene algún dato erróneo.";
|
||||
break;
|
||||
|
||||
default:
|
||||
errorCode = UseCaseError.UNEXCEPTED_ERROR;
|
||||
message = domainError.message;
|
||||
payload = domainError.payload;
|
||||
break;
|
||||
}
|
||||
|
||||
return Result.fail<IUseCaseError>(
|
||||
UseCaseError.create(errorCode, message, payload),
|
||||
);
|
||||
return Result.fail(UseCaseError.create(errorCode, message, domainError));
|
||||
}
|
||||
|
||||
return this._updateUser(userOrError.object);
|
||||
}
|
||||
|
||||
private _tryCreateUserAddress(
|
||||
addressDTO: IBillingAddressUser_DTO | IShippingAddressUser_DTO | undefined,
|
||||
addressType: UserAddressType,
|
||||
) {
|
||||
const titleOrError = AddressTitle.create(addressDTO?.title);
|
||||
if (titleOrError.isFailure) {
|
||||
return Result.fail(titleOrError.error);
|
||||
}
|
||||
|
||||
const streetOrError = Street.create(addressDTO?.street);
|
||||
if (streetOrError.isFailure) {
|
||||
return Result.fail(streetOrError.error);
|
||||
}
|
||||
|
||||
const postalCodeOrError = PostalCode.create(addressDTO?.postal_code);
|
||||
if (postalCodeOrError.isFailure) {
|
||||
return Result.fail(postalCodeOrError.error);
|
||||
}
|
||||
|
||||
const cityOrError = City.create(addressDTO?.city);
|
||||
if (cityOrError.isFailure) {
|
||||
return Result.fail(cityOrError.error);
|
||||
}
|
||||
|
||||
const provinceOrError = Province.create(addressDTO?.province);
|
||||
if (provinceOrError.isFailure) {
|
||||
return Result.fail(provinceOrError.error);
|
||||
}
|
||||
|
||||
const countryOrError = Country.create(addressDTO?.country);
|
||||
if (countryOrError.isFailure) {
|
||||
return Result.fail(countryOrError.error);
|
||||
}
|
||||
|
||||
const emailOrError = UserEmail.create(addressDTO?.email);
|
||||
if (emailOrError.isFailure) {
|
||||
return Result.fail(emailOrError.error);
|
||||
}
|
||||
|
||||
const phoneOrError = UserPhone.create(addressDTO?.phone);
|
||||
if (phoneOrError.isFailure) {
|
||||
return Result.fail(phoneOrError.error);
|
||||
}
|
||||
|
||||
const notesOrError = Note.create(addressDTO?.notes);
|
||||
if (notesOrError.isFailure) {
|
||||
return Result.fail(notesOrError.error);
|
||||
}
|
||||
|
||||
const addressProps = {
|
||||
title: titleOrError.object,
|
||||
street: streetOrError.object,
|
||||
city: cityOrError.object,
|
||||
province: provinceOrError.object,
|
||||
postalCode: postalCodeOrError.object,
|
||||
country: countryOrError.object,
|
||||
email: emailOrError.object,
|
||||
phone: phoneOrError.object,
|
||||
notes: notesOrError.object,
|
||||
};
|
||||
|
||||
return addressType === "billing"
|
||||
? UserShippingAddress.create(addressProps)
|
||||
: UserShippingAddress.create(addressProps);
|
||||
}
|
||||
|
||||
private _tryCreateUserShippingAddresses(
|
||||
addressesDTO: IShippingAddressUser_DTO[] | undefined,
|
||||
) {
|
||||
const shippingAddressesOrError = new ResultCollection<
|
||||
UserShippingAddress,
|
||||
DomainError
|
||||
>();
|
||||
|
||||
if (addressesDTO) {
|
||||
addressesDTO.map((value) => {
|
||||
const result = this._tryCreateUserAddress(value, "shipping");
|
||||
shippingAddressesOrError.add(result);
|
||||
});
|
||||
}
|
||||
|
||||
if (shippingAddressesOrError.hasSomeFaultyResult()) {
|
||||
return Result.fail(shippingAddressesOrError.getFirstFaultyResult().error);
|
||||
}
|
||||
|
||||
return Result.ok(new Collection(shippingAddressesOrError.objects));
|
||||
}
|
||||
|
||||
private _tryCreateUserInstance(
|
||||
userDTO: IUpdateUser_DTO,
|
||||
userId: UniqueID,
|
||||
): Result<User, IDomainError> {
|
||||
const userTINOrError = UserTIN.create(userDTO.tin, {
|
||||
label: "tin",
|
||||
path: "tin",
|
||||
});
|
||||
if (userTINOrError.isFailure) {
|
||||
return Result.fail(userTINOrError.error);
|
||||
}
|
||||
|
||||
const companyNameOrError = UserName.create(userDTO.company_name);
|
||||
if (companyNameOrError.isFailure) {
|
||||
return Result.fail(companyNameOrError.error);
|
||||
}
|
||||
|
||||
const firstNameOrError = UserName.create(userDTO.first_name);
|
||||
if (firstNameOrError.isFailure) {
|
||||
return Result.fail(firstNameOrError.error);
|
||||
}
|
||||
|
||||
const lastNameOrError = UserName.create(userDTO.last_name);
|
||||
if (lastNameOrError.isFailure) {
|
||||
return Result.fail(lastNameOrError.error);
|
||||
}
|
||||
|
||||
const jobTitleOrError = UserJobTitle.create(userDTO.job_title);
|
||||
if (jobTitleOrError.isFailure) {
|
||||
return Result.fail(jobTitleOrError.error);
|
||||
}
|
||||
|
||||
const emailOrError = UserEmail.create(userDTO.email);
|
||||
if (emailOrError.isFailure) {
|
||||
return Result.fail(emailOrError.error);
|
||||
}
|
||||
|
||||
const phoneOrError = UserPhone.create(userDTO.phone);
|
||||
if (phoneOrError.isFailure) {
|
||||
return Result.fail(phoneOrError.error);
|
||||
}
|
||||
|
||||
/*const taxIdOrError = UniqueID.create(userDTO.tax_id);
|
||||
if (taxIdOrError.isFailure) {
|
||||
return Result.fail(taxIdOrError.error);
|
||||
}*/
|
||||
|
||||
const notesOrError = Note.create(userDTO.notes);
|
||||
if (notesOrError.isFailure) {
|
||||
return Result.fail(notesOrError.error);
|
||||
}
|
||||
|
||||
// Billing address
|
||||
const billingAddressOrError = this._tryCreateUserAddress(
|
||||
userDTO.billing_address,
|
||||
"billing",
|
||||
);
|
||||
if (billingAddressOrError.isFailure) {
|
||||
return Result.fail(billingAddressOrError.error);
|
||||
}
|
||||
|
||||
// Shipping address
|
||||
const shippingAddressesOrError = this._tryCreateUserShippingAddresses(
|
||||
userDTO.shipping_addresses,
|
||||
);
|
||||
|
||||
if (shippingAddressesOrError.isFailure) {
|
||||
return Result.fail(shippingAddressesOrError.error);
|
||||
}
|
||||
|
||||
return User.create(
|
||||
{
|
||||
tin: userTINOrError.object,
|
||||
companyName: companyNameOrError.object,
|
||||
firstName: firstNameOrError.object,
|
||||
lastName: lastNameOrError.object,
|
||||
jobTitle: jobTitleOrError.object,
|
||||
email: emailOrError.object,
|
||||
phone: phoneOrError.object,
|
||||
//taxId: taxIdOrError.object,
|
||||
notes: notesOrError.object,
|
||||
|
||||
billingAddress: billingAddressOrError.object,
|
||||
shippingAddresses: shippingAddressesOrError.object,
|
||||
},
|
||||
userId,
|
||||
);
|
||||
}
|
||||
|
||||
private async _findUserTIN(tin: UserTIN) {
|
||||
const userRepoBuilder = this.getRepositoryByName<IUserRepository>("User");
|
||||
return await userRepoBuilder().existsWithSameTIN(tin);
|
||||
}
|
||||
|
||||
private async _findUserID(id: UniqueID) {
|
||||
const userRepoBuilder = this.getRepositoryByName<IUserRepository>("User");
|
||||
return await userRepoBuilder().exists(id);
|
||||
}
|
||||
|
||||
private async _updateUser(user: User) {
|
||||
// Guardar el contacto
|
||||
const transaction = this._adapter.startTransaction();
|
||||
const userRepoBuilder = this.getRepositoryByName<IUserRepository>("User");
|
||||
const userRepository = this._getUserRepository();
|
||||
let userRepo: IUserRepository;
|
||||
|
||||
try {
|
||||
await transaction.complete(async (t) => {
|
||||
const userRepo = userRepoBuilder({ transaction: t });
|
||||
userRepo = userRepository({ transaction: t });
|
||||
await userRepo.update(user);
|
||||
});
|
||||
|
||||
@ -345,12 +107,43 @@ export class UpdateUserUseCase
|
||||
} catch (error: unknown) {
|
||||
const _error = error as IInfrastructureError;
|
||||
return Result.fail(
|
||||
UseCaseError.create(
|
||||
UseCaseError.REPOSITORY_ERROR,
|
||||
"Error al guardar el usuario",
|
||||
_error,
|
||||
),
|
||||
UseCaseError.create(UseCaseError.REPOSITORY_ERROR, _error.message),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private _tryCreateUserInstance(
|
||||
userDTO: IUpdateUser_Request_DTO,
|
||||
userId: UniqueID,
|
||||
): Result<User, IDomainError> {
|
||||
const nameOrError = Name.create(userDTO.name);
|
||||
if (nameOrError.isFailure) {
|
||||
return Result.fail(nameOrError.error);
|
||||
}
|
||||
|
||||
const emailOrError = Email.create(userDTO.email);
|
||||
if (emailOrError.isFailure) {
|
||||
return Result.fail(emailOrError.error);
|
||||
}
|
||||
|
||||
const passwordOrError = Password.createFromPlainTextPassword(
|
||||
userDTO.password,
|
||||
);
|
||||
if (passwordOrError.isFailure) {
|
||||
return Result.fail(passwordOrError.error);
|
||||
}
|
||||
|
||||
return User.create(
|
||||
{
|
||||
name: nameOrError.object,
|
||||
email: emailOrError.object,
|
||||
password: passwordOrError.object,
|
||||
},
|
||||
userId,
|
||||
);
|
||||
}
|
||||
|
||||
private _getUserRepository() {
|
||||
return this._repositoryManager.getRepository<IUserRepository>("User");
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ export class UserRepository
|
||||
const userData = this.mapper.mapToPersistence(user);
|
||||
|
||||
// borrando y luego creando
|
||||
await this.removeById(user.id, true);
|
||||
// await this.removeById(user.id, true);
|
||||
await this._save("User_Model", user.id, userData, {});
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export class CreateUserController extends ExpressController {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
async executeImpl(): Promise<any> {
|
||||
async executeImpl() {
|
||||
try {
|
||||
const userDTO: ICreateUser_Request_DTO = this.req.body;
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ export class UpdateUserController extends ExpressController {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
async executeImpl(): Promise<any> {
|
||||
async executeImpl() {
|
||||
try {
|
||||
const { userId } = this.req.params;
|
||||
const userDTO: IUpdateUser_Request_DTO = this.req.body;
|
||||
@ -76,7 +76,7 @@ export class UpdateUserController extends ExpressController {
|
||||
});
|
||||
|
||||
if (result.isFailure) {
|
||||
return this.handleExecuteError(result.error);
|
||||
return this._handleExecuteError(result.error);
|
||||
}
|
||||
|
||||
const user = <User>result.object;
|
||||
@ -89,7 +89,7 @@ export class UpdateUserController extends ExpressController {
|
||||
}
|
||||
}
|
||||
|
||||
private handleExecuteError(error: IUseCaseError) {
|
||||
private _handleExecuteError(error: IUseCaseError) {
|
||||
let errorMessage: string;
|
||||
let infraError: IInfrastructureError;
|
||||
|
||||
@ -117,6 +117,16 @@ export class UpdateUserController extends ExpressController {
|
||||
return this.invalidInputError(errorMessage, infraError);
|
||||
break;
|
||||
|
||||
case UseCaseError.REPOSITORY_ERROR:
|
||||
errorMessage = "Error updating user";
|
||||
infraError = InfrastructureError.create(
|
||||
InfrastructureError.UNEXCEPTED_ERROR,
|
||||
errorMessage,
|
||||
error,
|
||||
);
|
||||
return this.conflictError(errorMessage, infraError);
|
||||
break;
|
||||
|
||||
case UseCaseError.UNEXCEPTED_ERROR:
|
||||
errorMessage = error.message;
|
||||
|
||||
|
||||
@ -2,18 +2,18 @@ import Joi from "joi";
|
||||
import { Result, RuleValidator } from "../../../../common";
|
||||
|
||||
export interface IUpdateUser_Request_DTO {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export function ensureUpdateUser_Request_DTOIsValid(
|
||||
userDTO: IUpdateUser_Request_DTO,
|
||||
): Result<boolean, Error> {
|
||||
) {
|
||||
const schema = Joi.object({
|
||||
id: Joi.string(),
|
||||
name: Joi.string(),
|
||||
email: Joi.string(),
|
||||
password: Joi.string(),
|
||||
}).unknown(true);
|
||||
|
||||
const result = RuleValidator.validate<IUpdateUser_Request_DTO>(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user