Uecko_ERP/apps/server/archive/contexts/accounts/application/create-account.use-case.ts
2025-05-09 12:45:32 +02:00

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);
}
}