Skip to content

Open-Document Status Reports — Sales Order / Backorder / Picklist / Purchase Order

Date: 2026-07-01

Problem / motivation

Peachtree's operational fulfillment reports show, per open document line, quantity ordered vs fulfilled vs remaining: Sales Order Report ("open sales orders showing quantity ordered, shipped, and remaining"), Sales Backorder Report and Picklist Report ("items on open sales orders … used to pull items to fulfill"), and Purchase Order Report ("quantity ordered, received, and remaining"). We already track quantity_invoiced on order lines and quantity_received on PO lines, so these are straight derivations. Closes the Phase 2 rows on the Peachtree Report Parity tracker.

In scope

  • sales_order_report(generate_csv) — every non-canceled sales-order line with quantity ordered, shipped (quantity_invoiced), and remaining.
  • sales_backorder_report(generate_csv) / picklist_report(generate_csv) — the same lines filtered to remaining > 0 (items still to ship / pick). Same shape; two Peachtree names over one query.
  • purchase_order_report(generate_csv) — every open (non-closed) PO line with quantity ordered, received, and remaining.
  • CSV export via generate_csv. Path.REPORTS.

Out of scope

  • Drop-shipment flagging (Peachtree option) — not modeled.
  • Proposal lines in the picklist — proposals map to quotes, which don't carry fulfillment state.

Data model changes

None. Reads order_details (quantity, quantity_invoiced) + orders/clients, and purchase_order_details (quantity, quantity_received) + purchase_orders/suppliers, joined to items/unit_of_measures. Remaining = ordered − fulfilled. No migration, no new Path/Resource.

What's being implemented

  • Responsesapp/graphql/reports/strawberry/open_documents/open_document_report_response.py (SalesOrderLineResponse, PurchaseOrderLineResponse).
  • Repositoryapp/graphql/reports/repositories/open_documents/open_document_report_repository.py (sales_order_lines, purchase_order_lines).
  • Serviceapp/graphql/reports/services/open_documents/open_document_report_service.py.
  • Queriesapp/graphql/reports/queries/open_documents/open_document_report_queries.py.
  • Teststests/graphql/reports/test_open_document_reports.py.

GraphQL surface

salesOrderReport(generateCsv: Boolean! = false): GenericReportPage!
salesBackorderReport(generateCsv: Boolean! = false): GenericReportPage!
picklistReport(generateCsv: Boolean! = false): GenericReportPage!
purchaseOrderReport(generateCsv: Boolean! = false): GenericReportPage!

type SalesOrderLine { orderNumber: String!, orderDate: Date!, orderStatus: OrderStatus!, clientName: String!, itemNumber: String, description: String, unitOfMeasure: String!, quantityOrdered: Decimal!, quantityShipped: Decimal!, quantityRemaining: Decimal! }
type PurchaseOrderLine { purchaseOrderNumber: String!, purchaseOrderDate: Date!, purchaseOrderStatus: PurchaseOrderStatus!, supplierName: String!, itemNumber: String, description: String, unitOfMeasure: String!, quantityOrdered: Decimal!, quantityReceived: Decimal!, quantityRemaining: Decimal! }

Frontend contract

  • Four reports under Reports; each returns records + optional csvUrl.
  • salesBackorderReport and picklistReport return the same SalesOrderLine shape but only rows with quantityRemaining > 0.
  • Group by orderNumber / purchaseOrderNumber for a per-document view; quantityRemaining drives the fulfil/pick worklist.

Future additions

  • Drop-shipment column once modeled.
  • Proposal (quote) picklist lines if quotes gain fulfillment tracking.