Purchase Orders Imports - ION Manual

Overview

The Purchase Orders importer creates or updates Purchase Orders and their Purchase Order Lines from a single CSV. The CSV is denormalized: one row per PO line, with the PO header columns repeated across every row that belongs to the same PO. Example: two POs, three lines.

po_number supplier currency part_number quantity cost
PO-001 Acme USD WIDGET-A 10 5.00
PO-001 Acme USD WIDGET-B 5 12.00
PO-002 Globex EUR GADGET-X 1 100.00

Rows sharing the same po_number are merged into a single PO header. If a header column is included in your CSV, it must be populated on every row of that PO and all values must match. Any blank cell or any value that disagrees with another row of the same PO fails the import with a per-conflict error before any data is written.

Header columns

These describe the PO itself. If you include a header column in your CSV, it must be present and identical on every row that shares a po_number. Otherwise the import fails.

Column Required Description
po_number Yes PO identifier. The grouping key.
original_po_number No Existing PO number when renaming. Lookup column: an empty cell means “no rename,” not "".
po_description No Free-text PO description.
supplier No Supplier name. Must match an existing supplier.
ship_to_location No Ship-to location name. Must match an existing location.
bill_to_location No Bill-to location name. Must match an existing location.
currency No Currency type, such as USD or EUR. Must match an existing currency.
ordered_at No Order date. Parsed flexibly (any pandas-recognized date format).
assigned_to No Email of the user the PO is assigned to. Must match an existing user.
po_intent_option No Intent option value at the PO level. Prefixed with po_ to disambiguate from the line-level intent_option.
po_labels No Semicolon-delimited list of label values to attach to the PO.
terms_and_conditions No Title of a Requirement with type TERMS_AND_CONDITIONS. Overrides the org’s default.
fees No Semicolon-delimited list of fee records. See Fees below.

Line columns

These describe a single PO line. Every row contributes one line if any line column is populated.

Column Required Description
part_number No Part number for the line. Combined with revision to look up the part.
revision No Part revision. If omitted, the latest revision of part_number is used.
description No Line description.
quantity No Line quantity. Must be non-negative.
cost No Line unit cost. Must be non-negative.
need_date No Date needed. Parsed flexibly.
estimated_arrival_date No Estimated arrival date. Parsed flexibly.
paid No Marks the line as paid. Boolean field (see accepted values).
percentage_fee_exempt No Excludes this line from percentage-based PO fees. Boolean field (see accepted values).
labels No Semicolon-delimited list of label values to attach to the line.
quality_clauses No Semicolon-delimited list of quality clause titles. Must match Requirements with requirement_type = QUALITY_CLAUSE.
intent_option No Intent option value at the line level.

A row that populates only header columns (no part_number or other line column) contributes to the PO header but does not create a line. Use this to create or update a PO without lines.

Fees

The fees column accepts a semicolon-delimited list of fee records. Each record uses two bracketed fields after the fee name:

Name[value][type];Name[value][type]
Field Notes
Name Required. Must be unique within the PO.
value Required. Must parse as a number.
type Required. One of currency or percentage.

Example: Shipping[50.00][currency];VAT[8.5][percentage]

Fee names must be unique within a PO. Duplicate fee names in the same row’s fees cell are rejected at validation.

Custom attributes

Any column not in the standard set above is treated as a custom attribute. The importer routes each column to either PO-level or PO-line-level attributes based on which table defines it in your organization’s attribute configuration:

Matching is case- and format-sensitive, so a CSV header BatchID matches an attribute keyed BatchID only.

Header conflicts

Header-column conflicts are collected across all POs and reported together, so you can fix everything in one pass.