import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core"; import { Decimal } from "decimal.js"; import type { Transaction, Updateable } from "../generated/kysely-tailordb"; import { InvalidToleranceValueError, InvoiceToleranceConfigNotFoundError, } from "../lib/errors.generated"; export interface InvoiceToleranceConfigPatch { quantityAbsoluteTolerance?: string | null; quantityPercentageTolerance?: string | null; unitPriceAbsoluteTolerance?: string | null; unitPricePercentageTolerance?: string | null; } export interface UpdateInvoiceToleranceConfigInput { companyId: string; supplierAccountId: string; patch: InvoiceToleranceConfigPatch; } const toleranceFields = [ "quantityAbsoluteTolerance", "quantityPercentageTolerance", "unitPriceAbsoluteTolerance", "unitPricePercentageTolerance", ] as const; function validateToleranceValues(patch: InvoiceToleranceConfigPatch) { for (const field of toleranceFields) { const value = patch[field]; if (value != null && new Decimal(value).lt(0)) { return err(new InvalidToleranceValueError(field)); } } return ok({}); } export async function run( db: Transaction, input: UpdateInvoiceToleranceConfigInput, _ctx: CommandContext, ) { const { companyId, supplierAccountId, patch } = input; const config = await db .selectFrom("InvoiceToleranceConfig") .selectAll() .where("companyId", "=", companyId) .where("supplierAccountId", "=", supplierAccountId) .forUpdate() .executeTakeFirst(); if (!config) return err(new InvoiceToleranceConfigNotFoundError(`${companyId}:${supplierAccountId}`)); const toleranceResult = validateToleranceValues(patch); if (!toleranceResult.ok) return toleranceResult; const values: Updateable<"InvoiceToleranceConfig"> = {}; if (patch.quantityAbsoluteTolerance !== undefined) { values.quantityAbsoluteTolerance = patch.quantityAbsoluteTolerance; } if (patch.quantityPercentageTolerance !== undefined) { values.quantityPercentageTolerance = patch.quantityPercentageTolerance; } if (patch.unitPriceAbsoluteTolerance !== undefined) { values.unitPriceAbsoluteTolerance = patch.unitPriceAbsoluteTolerance; } if (patch.unitPricePercentageTolerance !== undefined) { values.unitPricePercentageTolerance = patch.unitPricePercentageTolerance; } if (Object.keys(values).length === 0) { return ok({ invoiceToleranceConfig: config }); } const invoiceToleranceConfig = await db .updateTable("InvoiceToleranceConfig") .set(values) .where("id", "=", config.id) .returningAll() .executeTakeFirstOrThrow(); return ok({ invoiceToleranceConfig }); }