100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
import {
|
|
EmailAddress,
|
|
PhoneNumber,
|
|
PostalAddress,
|
|
TINNumber,
|
|
UniqueID,
|
|
} from "@/core/common/domain";
|
|
|
|
import {
|
|
type Account,
|
|
AccountStatus,
|
|
type IAccountProps,
|
|
type IAccountService,
|
|
} from "@/contexts/accounts/domain";
|
|
import { ITransactionManager } from "@/core/common/infrastructure/database";
|
|
import { logger } from "@/core/logger";
|
|
import { Maybe, Result } from "@repo/rdx-utils";
|
|
import { ICreateAccountRequestDTO } from "../presentation";
|
|
|
|
export class CreateAccountUseCase {
|
|
constructor(
|
|
private readonly accountService: IAccountService,
|
|
private readonly transactionManager: ITransactionManager
|
|
) {}
|
|
|
|
public execute(
|
|
accountID: UniqueID,
|
|
dto: ICreateAccountRequestDTO
|
|
): Promise<Result<Account, Error>> {
|
|
return this.transactionManager.complete(async (transaction) => {
|
|
try {
|
|
const validOrErrors = this.validateAccountData(dto);
|
|
if (validOrErrors.isFailure) {
|
|
return Result.fail(validOrErrors.error);
|
|
}
|
|
|
|
const data = validOrErrors.data;
|
|
|
|
// Update account with dto
|
|
return await this.accountService.createAccount(accountID, data, transaction);
|
|
} catch (error: unknown) {
|
|
logger.error(error as Error);
|
|
return Result.fail(error as Error);
|
|
}
|
|
});
|
|
}
|
|
|
|
private validateAccountData(dto: ICreateAccountRequestDTO): Result<IAccountProps, Error> {
|
|
const errors: Error[] = [];
|
|
|
|
const tinOrError = TINNumber.create(dto.tin);
|
|
const emailOrError = EmailAddress.create(dto.email);
|
|
const phoneOrError = PhoneNumber.create(dto.phone);
|
|
const faxOrError = PhoneNumber.createNullable(dto.fax);
|
|
const postalAddressOrError = PostalAddress.create({
|
|
street: dto.street,
|
|
city: dto.city,
|
|
state: dto.state,
|
|
postalCode: dto.postal_code,
|
|
country: dto.country,
|
|
});
|
|
|
|
const result = Result.combine([
|
|
tinOrError,
|
|
emailOrError,
|
|
phoneOrError,
|
|
faxOrError,
|
|
postalAddressOrError,
|
|
]);
|
|
|
|
if (result.isFailure) {
|
|
return Result.fail(result.error);
|
|
}
|
|
|
|
const validatedData: IAccountProps = {
|
|
status: AccountStatus.createInactive(),
|
|
isFreelancer: dto.is_freelancer,
|
|
name: dto.name,
|
|
tradeName: dto.trade_name ? Maybe.some(dto.trade_name) : Maybe.none(),
|
|
tin: tinOrError.data,
|
|
address: postalAddressOrError.data,
|
|
email: emailOrError.data,
|
|
phone: phoneOrError.data,
|
|
fax: faxOrError.data,
|
|
website: dto.website ? Maybe.some(dto.website) : Maybe.none(),
|
|
legalRecord: dto.legal_record,
|
|
defaultTax: dto.default_tax,
|
|
langCode: dto.lang_code,
|
|
currencyCode: dto.currency_code,
|
|
logo: dto.logo ? Maybe.some(dto.logo) : Maybe.none(),
|
|
};
|
|
|
|
if (errors.length > 0) {
|
|
const message = errors.map((err) => err.message).toString();
|
|
return Result.fail(new Error(message));
|
|
}
|
|
return Result.ok(validatedData);
|
|
}
|
|
}
|