import { type CommonReservedFields, type NoReservedFields, defaultGqlPermission, defaultPermission, } from "@tailor-platform/erp-kit/core"; import { db, type TailorAnyDBField, type TailorAnyDBType } from "@tailor-platform/sdk"; import { accountPayableDocument } from "./accountPayableDocument"; export const ACCOUNT_PAYABLE_LINE_SOURCE_TYPES = ["PURCHASE_ORDER"] as const; export const ACCOUNT_PAYABLE_LINE_CORRECTION_TYPES = ["PRICE", "QUANTITY", "AMOUNT"] as const; const builtins = (params: { purchaseOrderLineType?: TailorAnyDBType; unitType?: TailorAnyDBType; }) => { const unitId = db .uuid({ optional: true }) .description("Supplier invoice unit of measure; required only for PURCHASE_ORDER source lines"); const purchaseOrderLineId = db .uuid({ optional: true }) .description("Foreign key to PurchaseOrderLine when sourceType is PURCHASE_ORDER"); return { accountPayableDocumentId: db .uuid() .relation({ type: "n-1", toward: { type: accountPayableDocument, as: "accountPayableDocument" }, backward: "lines", }) .description("Foreign key to AccountPayableDocument"), netAmount: db.decimal().description("Positive line amount excluding tax"), taxAmount: db.decimal({ optional: true }).description("Optional tax amount"), grossAmount: db.decimal().description("Positive line amount including tax"), correctionOfLineId: db .uuid({ optional: true }) .relation({ type: "n-1", toward: { type: "self" }, backward: "correctionLines", }) .description("Optional self-reference to the posted AP document line being corrected"), correctionType: db .enum(ACCOUNT_PAYABLE_LINE_CORRECTION_TYPES, { optional: true }) .description("Optional correction type for line-level AP corrections"), quantity: db .decimal({ optional: true }) .description("Supplier invoice quantity; required only for PURCHASE_ORDER source lines"), unitPrice: db .decimal({ optional: true }) .description("Supplier invoice unit price; required only for PURCHASE_ORDER source lines"), matchedPurchaseOrderUnitPrice: db .decimal({ optional: true }) .description( "Order unit price captured at matching; the base price variances are measured against", ), unitId: params.unitType ? unitId.relation({ type: "n-1", toward: { type: params.unitType, as: "unit" }, backward: "accountPayableDocumentLines", }) : unitId, description: db.string({ optional: true }).description("Optional line description"), sourceType: db .enum(ACCOUNT_PAYABLE_LINE_SOURCE_TYPES, { optional: true }) .description("Optional AP line source type; PURCHASE_ORDER means purchaseOrderLineId is set"), purchaseOrderLineId: params.purchaseOrderLineType ? purchaseOrderLineId.relation({ type: "n-1", toward: { type: params.purchaseOrderLineType, as: "purchaseOrderLine" }, backward: "accountPayableDocumentLines", }) : purchaseOrderLineId, }; }; type ReservedFields = keyof ReturnType | CommonReservedFields; export interface CreateAccountPayableDocumentLineTypeParams< F extends Record, > { fields?: NoReservedFields; purchaseOrderLineType?: TailorAnyDBType; unitType?: TailorAnyDBType; } export function createAccountPayableDocumentLineType< const F extends Record, >(params: CreateAccountPayableDocumentLineTypeParams) { return db .table("AccountPayableDocumentLine", { ...builtins(params), ...((params.fields ?? {}) as F), ...db.fields.timestamps(), }) .permission(defaultPermission) .gqlPermission(defaultGqlPermission); } export const accountPayableDocumentLine = createAccountPayableDocumentLineType({});