Stock exports and reporting
Export selected stock movements
/a/Stock_exportHistories
Download incoming, outgoing and outgoing-allocation history rows.
When to use this endpoint
Use for movement review, not a complete ledger of every stock history type; use Write Off for write-off transactions.
Authentication and permissions
Authenticate with a signed API-key request or a logged-in CRM session. Requires Stock view (pageStocks_view) and table export (pageMain_exportTableData) permissions through the shared export guard; denial returns permission denied.
Client administrators and the all permission satisfy the checks. Legacy users with no role use the helper’s allow fallback when no explicit permission list is loaded. This is not merely the CRM1 export-button bit check.
Queries use the authenticated tenant. No department/owner restriction or stock-tracking feature gate is added by these handlers. CRM2 features2.stockTracking changes the export choices offered, not server authorization. Session CSRF and API signing still apply.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
yes | String | Yes | Must equal really. This compatibility confirmation is checked before the handler login/permission checks; it does not authorize the export. |
stockIDsFilter | Comma-separated string | No | A string such as 1042,1088, not a JSON or native array. Omitted or blank/whitespace means no selection restriction. Tokens must be positive decimal IDs; whitespace is trimmed and duplicates are removed. Malformed, zero/negative or non-string lists return invalid parameter: stockIDsFilter. |
Example request
$csv = FM_api('Stock_exportHistories', ['yes'=>'really']);
Example response
"Date of Transaction",ID,"Part Number","Manufacturer/Supplier Part Number",Description,"From (Type)","From (Location)","Transaction Type","To (Type)","To (Location)",Quantity,"Item Cost","Total Cost",Batch
"2026-10-05 09:00:00",1042,FLT-01,AC-01,"Replacement cartridge",Warehouse,Depot,Out,Job,2042,2,4,8,BATCH-01
Success is raw CSV, not JSON: retain the response body instead of JSON-decoding it. The response uses text/csv and the final download filename stock_movement.csv. Column positions and blank cells are meaningful.
Errors and unusual responses
| Response | Condition |
|---|---|
{"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"} | Either required export permission is denied. |
{"error":"yes is not really"} | yes is omitted or differs from really. |
Header-only CSV or interrupted output | Most database reads are not checked for failure. A blank export is not proof that the database contained no matching rows; malformed stored JSON can interrupt legacy reports. |
{"error":"invalid parameter: stockIDsFilter"} | A supplied selected-ID list is not a string of positive decimal IDs. |
{"error":"invalid parameter: search"} | A supplied stock/date filter is an array or other non-scalar value; the error names that parameter. |
{"error":"could not create stock export"} | The per-request CSV stream cannot be created, written or rewound. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Loads stock_histories left-joined to current stock, then only emits type 0 (In), 1 (Out) or 6 (OutAllocate, displayed Out). Allocate/Return/Damage/Transfer/Import/Write Off are not emitted.
- No date parameter is consumed, no ordering is declared, and stock/owner deleted/archive checks are absent except location destination names exclude deleted locations.
- Item Cost comes only from history meta.inventoryID joined to an inventory with a matching storage. Missing/unresolvable provenance leaves cost/reference/storage name at zero/blank; it does not use current stock average cost.
- Inventory cost and Total Cost preserve float values (history qty × inventory cost). Quantity itself is output raw. Date of Transaction formats cdate Unix seconds in server timezone.
- From is labeled Supplier only for GoodReceived type 4, with supplier name and GR ID; every other source is labeled Warehouse. Destination labels are mapped only through source type 18; OutVehicle type 20 has blank destination labels.
- The download filename is stock_movement.csv.
- No pagination or result limit is implemented. The entire result is exported; a header-only CSV is a valid empty result.
- No stock quantity, audit, edit timestamp, notification or event is changed. Reads across multiple queries are not a transactionally frozen snapshot.
- No direct caller for this exact endpoint was found in the current app JavaScript or
m/wwwintermediary; these are office reporting/source-selection calls, not the app download protocol. - The shared guard rejects non-scalar supplied stock/date filters and validates any supplied stockIDsFilter even on reports that do not use it for selection.
Side effects
- Builds CSV in a checked per-request php://temp stream, then streams it, closes it and exits. No shared tenant filename is written; concurrent requests generate independent files.
See it in Fieldmotion
CRM1
No direct caller for this exact endpoint was found in CRM1. Its Stock page has separate warehouse, user, vehicle, customer and cost export actions.
CRM2
Open Stocks, choose Export, select the matching report and submit. Filter Network for Stock_exportHistories (the posted form uses php/api.php with extra=/Stock_exportHistories). CRM2 supplies yes=really and a comma-separated stockIDsFilter for the selected export scope.
Related endpoints
Stock_exportSummaryprovides the CSV destination-type summary.Stock_getCostsprovides single-item costing defaults.Stock_getNamesresolves catalog labels.