When to use this endpoint

Use after obtaining line IDs or a parent header ID. The layout and requested-details variants share the same DataProcess query and nominal normalization; neither is a paginated list endpoint.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Session requests use dispatcher CSRF protection when configured. API keys use their owner’s permissions.

Requires explicit View on Purchase Order or Purchase Orders. Non-administrators with legacy Purchase Orders visibility disabled (crm_access bit 256) are denied.

Explicit line IDs are checked against their active, visible parent orders. A supplied po_id must match the line’s owner. These are tenant-local record IDs, not displayed order numbers.

Parameters

ParameterTypeRequiredDescription
id / idsPositive scalar, native or JSON ID listIDs or parentid takes precedence. Explicit [] returns []; missing/null/malformed/nested/nonpositive IDs fail. Entry readers can alternatively select one positive parent.
poIDPositive integer or digit stringIDs or parentPositive parent header ID; po_id and roID normalize to the same bounded predicate. Conflicting aliases fail. The parent must be active and visible.
fieldsNative array of stringsNoNative list of mapped field names. Defaults to all fields; unknown names/layout-only totalGross are omitted, and id is always included. Malformed/JSON-encoded field lists fail.
Mapped field filtersScalar or native arrayNoValidated stored-field equality filters, ANDed with the explicit selection and parent scope. Text lowercases/trims; numeric filters integer-convert. Native picker components are validated and expanded.
orderNative arrayNoMapped field names, or objects {id:"sortNumber",dir:"desc"}; only exact desc selects descending. Default has no ORDER BY. Use sortNumber then id for deterministic display order.
advanceSearchNative arrayNoNative allowlisted column/id, condition, value and AND/OR rules. Raw where SQL and malformed/nested controls fail before querying.

Example request

$result = FM_api('PurchaseOrderEntry_getLayoutDetails', [
	'poID'=>'1042',
	'fields'=>['id','poID','stock','amt','costNet','totalNet','totalTax'],
	'order'=>['sortNumber','id'],
]);

Example response

[
  {
    "id": "2081",
    "poID": "1042",
    "stock": {
      "id": "0",
      "type": "2",
      "text": "Packing materials"
    },
    "amt": "1.5",
    "costNet": "10.0000",
    "totalNet": "15.00",
    "totalTax": "3.00",
    "nominal_id": 0,
    "nominal_code": ""
  }
]

The example shows database-style string scalars; decimal formatting and scalar types can vary by the database driver. Narrow projections can still receive the two nominal normalization fields.

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error": "permission denied"}Page/action rights or the legacy visibility setting deny access.
{"error": "purchase order does not exist"}An explicit parent/header ID is absent, deleted or outside the caller’s scope.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Requires explicit positive scalar/native/JSON line IDs or a positive parent selector poID/po_id/roID. An explicit empty ID list returns [] without querying. Conflicting parent aliases fail; all aliases normalize to the mapped parent predicate.
  • Every query also joins its logical parent through an EXISTS predicate requiring active, visible headers. Omitting IDs cannot widen beyond a supplied parent; broad requests without a selector are rejected.
  • Native fields/order/filter/advanced-search controls are validated before the shared reader. Raw where SQL is rejected. Text equality is case-insensitive/trimmed; numeric equality filters retain the shared integer conversion, including for quantity/cost fields.
  • Returns a bare object array with no ok/count wrapper, pagination, row cap or default sort. Use order=["sortNumber","id"] for deterministic display order. Missing matches are omitted; a failed shared query can still collapse to [].
  • Mapped fields include id, roID/poID, stockType/stockID/stockText/stock, amt, costNet, totalNet/totalTax, cDate/lastEdited, nominalCode/nominal_code, taxTypeID/taxType and sortNumber. Layout-only totalGross is not computed by the reader.
  • Ordinary scalars can be database strings. Nominal normalization always adds local integer nominal_id and stored text nominal_code; selected nominalCode/taxType.nominalID resolve to the local ID. Omitting nominal source fields can yield 0/empty in those added fields.

See it in Fieldmotion

CRM1

No direct CRM1 caller was found; the legacy line grid uses PurchaseOrderEntries_get instead.

CRM2

CRM2’s purchaseOrderEntry layout mapping invokes this route internally while loading the Purchase Order spreadsheet. Inspect the Layout request rather than expecting a literal separate browser call.

Related endpoints