Price bands and stock pricing
Import price-band configuration
/a/PriceBands_import
Create or update price bands from mapped tabular rows, reporting row-level validation errors.
When to use this endpoint
Use the finance price-band importer to load names, display order, pricing mode and multiplier. This imports band configuration, not stock-specific prices or customer assignments.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session; all normal calls use that tenant. These handlers do not enforce an additional role or finance-page permission.
Use strings for signed numeric values, including values inside native arrays. Only JSON-encode parameters explicitly described as JSON text; see Getting started.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
map | JSON array text | Yes | Each entry’s index selects that source-column index; its to key is one of id, name, order_num, is_relative, relative_multiple. from, idx, filter and options do not change source selection here. Unknown destinations are ignored. |
rows | JSON array text of positional rows | Yes | Each row supplies cells aligned with map. A positive ID must already exist and takes precedence over name; otherwise a trimmed nonblank name matches the in-memory name map or creates a row. |
Mapped name cell | String-compatible cell | Conditional | Trimmed, at most 64 bytes. Needed to create or locate by name. Blank preserves an existing name on ID updates; an existing blank name must be repaired. Unlike PriceBand_new, "0" is accepted. |
Mapped order_num cell | Integer text | No | Nonblank accepts digits with optional leading minus; no plus sign, decimal or exponent. Blank/missing preserves existing value or defaults to 0 on creation. |
Mapped is_relative cell | 0/1 or named boolean/type text | No | Case-insensitive trimmed false aliases: 0, false, no, n, fixed, fixed price, absolute. True aliases: 1, true, yes, y, percent, percentage, percent discount, relative, discount. Other nonblank values are row errors; blank preserves/defaults to 0. |
Mapped relative_multiple cell | Numeric text | No | Finite numeric text is float-coerced. Nonfinite/nonnumeric values produce a row error; finite negative factors remain allowed. Blank/missing preserves existing value or defaults to 1. |
Example request
$result = FM_api('PriceBands_import', [
'map'=>json_encode([['to'=>'name'], ['to'=>'is_relative'], ['to'=>'relative_multiple']]),
'rows'=>json_encode([['Trade', 'relative', '0.9'], ['', 'fixed', '1']]),
]);
Example response
{"ok":1,"created":1,"edited":0,"errors":[[2,"Row does not contain ID or name"]]}
Illustration assumes Trade does not already exist. created and edited are numeric counters; errors contains [one-based row number, message] pairs. One invalid row can produce several errors; unchanged rows do not increment edited. No created-ID list is returned.
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":"missing or invalid parameter: map"} | map absent before authentication. |
{"error":"missing or invalid parameter: rows"} | rows absent before authentication. |
{"error":"invalid parameter: map"} | Decoded map is not an array. |
{"error":"invalid parameter: rows"} | Decoded rows is not an array. |
{"ok":1,"created":0,"edited":0,"errors":[[1,"price band does not exist"]]} | Positive mapped ID is absent; it does not fall back to name creation. |
{"error":"pricing write failed"} | A primary write or required history write fails; the transaction is rolled back. |
{"error":"pricing read failed"} | A checked lookup fails; nothing is committed. |
{"error":"pricing transaction failed"} | Transaction start or commit fails. |
{"error":"pricing operation failed"} | Unexpected database/runtime failure; no success is returned. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Preloads all tenant bands. Matching names is case-sensitive in the PHP map after trimming, unlike SQL lookups whose collation can be case-insensitive. Duplicate stored names make the last prefetched row win, with no established query order.
- In-memory ID/name maps are updated as processing proceeds; repeated names can update an earlier created row. Renaming can change subsequent matching. There is no uniqueness constraint or rollback for a failed write.
- Row validation messages include name too long. max length 64, invalid order_num, invalid type value, invalid relative_multiple, Row does not contain ID or name, price band does not exist, missing or invalid parameter: name and invalid row. Nested/non-scalar cells and malformed row shapes are reported as invalid row.
- All changed/created rows use one server Unix-time value for last_edited; creation also sets cdate. Unchanged rows preserve timestamps; no external date format or tenant-timezone conversion. Empty decoded row arrays return zero counts and no errors.
- No finance-feature, department or role guard beyond login. Map/rows must be JSON text, not native arrays.
- The mobile app has no direct caller for this endpoint in the searched JavaScript or
m/wwwintermediary. It downloads price bands throughsyncDownloadsinto its localpriceBandstable.
Side effects
- Inserts/updates price_bands and invalidates its cache. Each created or changed field receives checked history; history and primary writes commit together. No configured events, customer assignment, stock override, notification or external request.
See it in Fieldmotion
CRM1
Open Settings → Finance → Price Bands → Import and map the raw fields. Filter PriceBands_import; the widget sends JSON map and rows. Other import widgets resolve named bands through listByNames/new instead.
CRM2
No direct CRM2 caller for this configuration importer was found. Its stock/customer imports resolve named bands through PriceBands_listByNames and PriceBand_new; finance edits use mapped writes.
Related endpoints
PriceBands_listrereads raw rows to confirm an import.PriceBands_listByNamesresolves names using database equality, not this importer’s PHP name map.