PurchaseOrderLineLoad
Purchase order line items. A line belongs to a PO header (referenced by
po_number and by source_document_id/source_line_id for upsert
keying).
Import
from lib.objects.purchase_order_line import PurchaseOrderLineLoad
Standard BaseLoad methods
See baseload.md.
PurchaseOrderLine fields
| Field | Required | Notes |
|---|---|---|
id | (assigned) | UUID |
po_number | yes | Must match a purchase_order.po_number |
po_line_number | yes | Line number within the PO (e.g. 1, 2...) |
source_document_id | yes | Source-system PO id (matches PO header's source_document_id) |
source_line_id | yes | Source-system line id — upsert key |
line_type | Free-form (ITEM, SERVICE, FREIGHT, ...) | |
product_code_1 | Primary product / SKU code | |
product_name | ||
product_code_2 | Alternate / customer-side product code | |
unspsc_code | ||
description | Long-form description, separate from product_name | |
requester / buyer | ||
quantity | yes | float |
unit_of_measure | e.g. EA, KG, HR | |
unit_price | yes | float |
currency_code | ||
expected_delivery_date | ||
ship_to_location_code | ||
net_amount | yes | float — usually quantity * unit_price |
tax_amount / gross_amount | floats; auto-filled to net_amount + tax_amount if absent | |
status | ||
is_deleted | Soft-delete flag. PO-line supports soft-delete only — there is no is_active / deactivate path. | |
custom_text_1..15 | text | |
custom_number_1..10 | numeric | |
custom_date_1..10 | ISO date |
Example
from lib.objects.purchase_order_line import PurchaseOrderLineLoad
def run(context):
load = PurchaseOrderLineLoad(context)
line = load.new()
line.po_number = 'PO-2026-0042'
line.po_line_number = '1'
line.source_document_id = 'ERP-PO-42'
line.source_line_id = 'ERP-PO-42-L1'
line.product_code_1 = 'WIDGET-A'
line.product_name = 'Office Widget'
line.quantity = 100
line.unit_of_measure = 'EA'
line.unit_price = 12.50
line.currency_code = 'EUR'
line.net_amount = 1250.00
line.custom_text_1 = 'urgent'
line.custom_number_1 = 5 # e.g. priority rank
line.custom_date_1 = '2026-05-10'
load.save_all()
return {'created': 1}
Search
# All lines for a specific PO
for line in load.search(po_number='PO-2026-0042'):
print(line.po_line_number, line.description, line.net_amount)
Bulk delete
The natural key is source_line_id, so:
load.delete_where(
parameters=[{'source_line_id': 'ERP-PO-42-L1'}],
action='delete',
)