import { buildPaginatedResult, DEFAULT_PAGE_SIZE, err, ok, type PaginationInput, type ReadonlyDB, } from "@tailor-platform/erp-kit/core"; import type { DB, Selectable } from "../generated/kysely-tailordb"; import { CompanyScopeRequiredError } from "../lib/errors.generated"; import { summarizeOrderProgress } from "./getSalesOrder"; type SO = Selectable<"SalesOrder">; type OrderByField = "createdAt" | "orderDate" | "orderStatus"; export type ListSalesOrdersInput = Pick & Partial> & { dateFrom?: Date; dateTo?: Date; } & PaginationInput; export async function run(db: ReadonlyDB, input: ListSalesOrdersInput) { if (!input.companyId) { return err(new CompanyScopeRequiredError("sales-orders")); } const limit = input.limit ?? DEFAULT_PAGE_SIZE; const offset = input.offset ?? 0; const orderBy = input.orderBy ?? "orderDate"; const orderDirection = input.orderDirection ?? "desc"; let query = db.selectFrom("SalesOrder").selectAll().where("companyId", "=", input.companyId); if (input.customerAccountId) { query = query.where("customerAccountId", "=", input.customerAccountId); } if (input.orderStatus) { query = query.where("orderStatus", "=", input.orderStatus); } if (input.fulfillmentStatus) { query = query.where("fulfillmentStatus", "=", input.fulfillmentStatus); } if (input.billingStatus) { query = query.where("billingStatus", "=", input.billingStatus); } const salesOrders = await query .orderBy(orderBy, orderDirection) .limit(limit + 1) .offset(offset) .execute(); const filteredByDate = salesOrders.filter((row) => { if (input.dateFrom && row.orderDate < input.dateFrom) return false; if (input.dateTo && row.orderDate > input.dateTo) return false; return true; }); const pageRows = filteredByDate.slice(0, limit + 1); const lineRows = pageRows.length === 0 ? [] : await db .selectFrom("SalesOrderLine") .selectAll() .where( "salesOrderId", "in", pageRows.map((row) => row.id), ) .execute(); const items = pageRows.map((row) => ({ ...row, fulfillmentTotals: summarizeOrderProgress( lineRows.filter((lineRow) => lineRow.salesOrderId === row.id), ), })); return ok(buildPaginatedResult(items, limit)); }