> ## Documentation Index
> Fetch the complete documentation index at: https://agents.nanonets.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SAP Read Purchase Order

> Reads one purchase order in full by number, or searches for purchase orders by company code, type, supplier or date.

Reads purchase orders from SAP (`A_PurchaseOrder` in `API_PURCHASEORDER_PROCESS_SRV`). Display name **"SAP Read Purchase Order"**. Off by default.

One tool covers both shapes:

* **By key** — `purchase_order_number` returns that one order with its items, pricing conditions, account assignments and header texts.
* **By filter** — any of `company_code`, `purchase_order_type`, `supplier`, `purchase_order_date`, or `purchase_order_date_from` / `purchase_order_date_to` returns the matching orders, newest first.

Passing both a key and filters is refused, and so is a call with neither. `max_results` on its own is not a filter.

## Authentication and enablement

Requires a workspace SAP integration. `base_url` and `authorization` are injected. Enable the tool and bind the integration.

## Inputs

| Field | Required | Notes |
| - | - | - |
| `purchase_order_number` | for a key read | e.g. `4500000001`. |
| `company_code` | — | Exact match. |
| `purchase_order_type` | — | e.g. `NB` standard, `FO` framework. Exact match. |
| `supplier` | — | Supplier number. Exact match. |
| `purchase_order_date` | — | One day, `YYYY-MM-DD`. Not together with the range. |
| `purchase_order_date_from`, `purchase_order_date_to` | — | A range, `YYYY-MM-DD`. Either end works alone. |
| `max_results` | — | Cap on a filter search. Defaults to 20, capped at 100. Ignored on a key read. |

Filters combine with AND. Dates go to SAP as given, so a format other than `YYYY-MM-DD` comes back as SAP's error.

## Outputs

**By key**, the order itself:

* Header: `purchase_order_number`, `purchase_order_type`, `supplier_id`, `supplier_name`, `company_code`, `purchasing_organization`, `purchasing_group`, `payment_terms`, `incoterms`, `incoterms_location`, `status` (SAP's code, untranslated), `is_incomplete`, `release_is_not_completed`, `deletion_code`, `created_date`, `created_by`, `header_text`, `reference`, and every header note in `texts`.
* Totals: `total_items`, `total_amount` (the sum of the lines' `line_total`) and `net_amount` (the same sum with returns lines subtracted and deleted lines dropped — the one to match an invoice against). `currency`, `plant`, `storage_location` and `delivery_address` are taken from the first item.
* `items[]`: `item_number`, `material`, `description`, `quantity`, `unit`, `net_price`, `net_price_quantity`, `order_price_unit`, `line_total`, `currency`, `plant`, `storage_location`, `tax_code`, `tax_jurisdiction`, the delivery tolerances, the flags `invoice_is_goods_receipt_based`, `goods_receipt_is_expected`, `is_ers_allowed`, `is_completely_delivered`, `is_finally_invoiced`, `is_returns_item` and `deletion_code`, `pricing_conditions[]` and `account_assignments[]`.
* `sap_url` when the connection has a Fiori launchpad URL.

The supplier name comes from the supplier's business partner record, and from the order's address when that lookup returns nothing. The line-item values are citable, so an agent that passes them to `compare` links back to the order's rows.

**By filter**, `orders[]` in the same shape, plus `total_found` (the number returned) and `has_more`. A search result is lighter than a key read: no pricing conditions, no account assignments, and the supplier name is the order's address name. Read an order by key for the rest.

<Warning>
  `net_price` is the price per `net_price_quantity` units of `order_price_unit`, not per unit of `unit`. Use `line_total`, which applies both, rather than multiplying `quantity` by `net_price`.
</Warning>

Quantities, prices and totals are JSON numbers. `created_date` is written out (e.g. "October 8, 2026"). Items carry no delivery date: SAP holds it on the schedule lines, which this tool does not read.

## Store the result as a task variable

On by default: a successful read stores its structured result as a task variable, so the agent hands it to another tool as `${VAR_N}` instead of copying rows into the call. To keep the result inline only, bind `store_result_as_variable` to `false` on a configured tool. The binding is hidden from the agent, and any value other than `true` or `false` is rejected when saved. Set it through the API or the platform MCP's `update_configured_tool`; the configured-tool dialog keeps it when the tool is saved again.

* The variable holds the structured result as the tool returns it. A path such as `${VAR_N.items}` (or `${VAR_N.orders}` for a search) reads one part of it and arrives as parsed data.
* A bare `${VAR_N}` reaches a python tool as JSON text; parse it with `json.loads`.
* With harness\_v2 on, the agent's history keeps the reference and a short preview instead of the whole result, and the agent can read more with `request_variables`. The task feed still shows the full result.
* An error stores nothing. Set the binding to `false` to turn this off.

## Limits and errors

* A key read asks for pricing conditions, account assignments and header texts with the order. A system that does not serve one of them is read again without it, and `sap_messages` carries an `NN/EXPAND_UNAVAILABLE` warning saying they are absent rather than empty. The warning is in the structured result, not the text summary.
* A filter search that reached `max_results` sets `has_more` and adds an `NN/SEARCH_TRUNCATED` warning. SAP does not say how many orders matched, so narrow the filters or raise `max_results`.
* A filter search that matches nothing is an error that names the filters it used, e.g. "no purchase orders found matching company code 1000, supplier 17300001".
* A purchase order number that does not exist returns SAP's own not-found error.
* Without a bound SAP integration the call fails with "SAP integration not configured".


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.