import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import type { PrimitivesModule } from "../../primitives"; import { addBankAccount } from "../domain/businessPartner"; import type { Transaction } from "../generated/kysely-tailordb"; import { CurrencyNotFoundError, PartnerNotFoundError } from "../lib/errors.generated"; import { createBusinessPartnerRepository, type BusinessPartnerRepository, } from "../repository/businessPartnerRepository"; type PrimitivesQueries = PrimitivesModule["queries"]; export interface CreatePartnerBankAccountInput { partnerId: string; bankName: string; accountHolderName: string; accountNumber: string; routingNumber?: string; currencyId: string; } /** Adds reusable bank details to the BusinessPartner aggregate. */ export async function run>( db: Transaction, input: CreatePartnerBankAccountInput & CF, ctx: CommandContext, primitivesQueries?: Pick, repositoryFactory: ( db: Transaction, ) => BusinessPartnerRepository = createBusinessPartnerRepository, ) { const { partnerId, bankName, accountHolderName, accountNumber, routingNumber, currencyId, ...customFields } = input; const repository = repositoryFactory(db); const partner = await repository.findById(partnerId, { forUpdate: true }); if (!partner) return err(new PartnerNotFoundError(partnerId)); if (primitivesQueries?.getCurrency) { const currencyResult = await primitivesQueries.getCurrency(db, { id: currencyId }, ctx); if (!currencyResult.ok || !currencyResult.value.currency) { return err(new CurrencyNotFoundError(currencyId)); } } const created = addBankAccount(partner, { bankName, accountHolderName, accountNumber, routingNumber, currencyId, customFields, }); if (!created.ok) return created; await repository.save(created.value.partner); return ok({ partnerBankAccountId: created.value.bankAccount.id }); }