Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Reference

Trade documents

Reference for trade_documents in sales_orders, the packing list and delivery note generated from a frozen snapshot, with numbering, languages, PDF rendering, and versions.

This page describes the trade_documents sub-module of src/cluster_erp/modules/sales_orders/. A trade document (TradeDocument) is a packing list or a delivery note for one shipment. Generation freezes the shipment's data as a JSON snapshot, renders HTML from it in the document language, prints a PDF, and stores the PDF as an attachment of the record. The shipment itself is described on shipments.

Scope and source

  • Defined in: trade_documents/models.py (TradeDocument, DOCUMENT_TYPES), services.py (TradeDocumentService, compose_number), builder.py (SnapshotBuilder), render.py (RENDERERS), i18n/__init__.py with i18n/en.json and i18n/tr.json, templates/document.css, routes.py, and metadata.py.
  • Count: 1 table, 4 routes (@router. decorators), 2 document types.

Document fields

Name Meaning Source
shipment_id, sales_order_id The shipment and its order src/cluster_erp/modules/sales_orders/trade_documents/models.py:40-48
doc_type packing_list or delivery_note src/cluster_erp/modules/sales_orders/trade_documents/models.py:16, src/cluster_erp/modules/sales_orders/trade_documents/models.py:49
number, version_no Document number and version; unique per type among live rows src/cluster_erp/modules/sales_orders/trade_documents/models.py:28-38, src/cluster_erp/modules/sales_orders/trade_documents/models.py:50-51
language Language code of the labels src/cluster_erp/modules/sales_orders/trade_documents/models.py:52
snapshot Everything the PDF printed, money as strings src/cluster_erp/modules/sales_orders/trade_documents/models.py:53-54
attachment_id The rendered PDF in core attachments src/cluster_erp/modules/sales_orders/trade_documents/models.py:55-56
stale, superseded_by_id Source changed after generation; newer version src/cluster_erp/modules/sales_orders/trade_documents/models.py:57-67
generated_at, generated_by Generation record src/cluster_erp/modules/sales_orders/trade_documents/models.py:68-69

Document routes

Method and path Permission Source
GET /sales-orders/trade-documents/ trade_document.read src/cluster_erp/modules/sales_orders/trade_documents/routes.py:37
GET /sales-orders/trade-documents/{document_id} trade_document.read src/cluster_erp/modules/sales_orders/trade_documents/routes.py:68
GET /sales-orders/trade-documents/{document_id}/download trade_document.read src/cluster_erp/modules/sales_orders/trade_documents/routes.py:84
POST /sales-orders/shipments/{shipment_id}/generate-documents trade_document.create src/cluster_erp/modules/sales_orders/trade_documents/routes.py:102

Generation

The diagram shows one generation call.

flowchart TD
 G["TradeDocumentService.generate"] --> C["checks at level export"]
 C --> L["doc_labels for document_language"]
 L --> S["SnapshotBuilder.build over the EventBus"]
 S --> N["compose_number from the settings template"]
 N --> R["RENDERERS: HTML from snapshot and labels"]
 R --> P["PDF renderer"]
 P --> A["AttachmentService.create"]
 A --> V["previous version superseded_by_id set"]
 V --> E["shipment event"]

In prose: generation locks the shipment and runs the dispatch checks at the export level, whatever the tenant's dispatch level; any error refuses the whole call (src/cluster_erp/modules/sales_orders/trade_documents/services.py:169-200). It loads the labels of the setting document_language and builds one snapshot for all documents. The builder reads parties, addresses, products, units of measure, countries, and the project through EventBus queries (src/cluster_erp/modules/sales_orders/trade_documents/builder.py:1-30, src/cluster_erp/modules/sales_orders/trade_documents/services.py:201-205). The packing list is rendered first so that the delivery note can quote its number (src/cluster_erp/modules/sales_orders/trade_documents/services.py:209-210, src/cluster_erp/modules/sales_orders/trade_documents/services.py:264-265). For each type the service composes the number, renders HTML, prints the PDF with a footer, saves the record and the attachment, and marks the previous version superseded (src/cluster_erp/modules/sales_orders/trade_documents/services.py:211-263). Last, it writes a shipment event (src/cluster_erp/modules/sales_orders/trade_documents/services.py:267-278).

Numbering

The number comes from the settings templates packing_list_no_template (default PL-{shipment_code}) and delivery_note_no_template (default DN-{shipment_code}) (src/cluster_erp/modules/sales_orders/settings/models.py:37-44, src/cluster_erp/modules/sales_orders/trade_documents/services.py:145-152). The placeholders are {shipment_code}, {order_no}, {customer_po_no}, {project_no}, {year}, and {seq}. {seq} takes the next value of a sequence per document type. A placeholder with an empty value refuses the generation instead of printing a blank (src/cluster_erp/modules/sales_orders/trade_documents/services.py:42-85, src/cluster_erp/modules/sales_orders/trade_documents/services.py:213-226).

Languages and templates

The labels are JSON dictionaries, one file per language in trade_documents/i18n/. A file names itself under _language; adding a language is adding a file. An unknown code falls back to en (src/cluster_erp/modules/sales_orders/trade_documents/i18n/__init__.py:1-53). The renderers are pure functions that build HTML from the snapshot and the labels, with the stylesheet templates/document.css and the core font CSS (src/cluster_erp/modules/sales_orders/trade_documents/render.py:1-20, src/cluster_erp/modules/sales_orders/trade_documents/render.py:302-375). The PDF engine is described on PDF and system mail.

Constraints and validation

  • A document never changes after issue; a fix is made on the source record and the document regenerated as the next version (src/cluster_erp/modules/sales_orders/trade_documents/models.py:19-26).
  • Order changes such as a PO revision or a bill-to change mark every live, current document of the order stale (src/cluster_erp/modules/sales_orders/trade_documents/services.py:279-295, src/cluster_erp/modules/sales_orders/orders/services.py:965-980).
  • Download returns the filed PDF; a document without a rendered file returns 404 (src/cluster_erp/modules/sales_orders/trade_documents/services.py:130-142).
  • Only the two types in DOCUMENT_TYPES are produced; a request without a known type is refused (src/cluster_erp/modules/sales_orders/trade_documents/services.py:183-185).

Terms introduced

Term Code identifier Definition Turkish term Source
packing list packing_list The document that lists packages, weights, and contents of a shipment. Çeki listesi src/cluster_erp/modules/sales_orders/trade_documents/metadata.py:20
delivery note delivery_note The document that accompanies the goods to the receiver. Sevk irsaliyesi src/cluster_erp/modules/sales_orders/trade_documents/metadata.py:21
document snapshot snapshot The frozen JSON data a document printed. Belge anlık görüntüsü src/cluster_erp/modules/sales_orders/trade_documents/models.py:53-54
stale document stale A document whose source data changed after it was generated. Bayat belge src/cluster_erp/modules/sales_orders/trade_documents/models.py:57-61

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13