Quotes: settings, costing and lookups
Upload a quote form image
/a/Quote_setFieldImage
Store image bytes and return an encoded image reference for a quote field or table cell.
When to use this endpoint
Use for quote form photos/signatures. Main-field mode writes the image reference into form_fields; table mode only returns a reference that the caller must save with the table rows.
Authentication and permissions
Authenticates a signed API key or CRM session as its tenant user. Requires Quotes View (pageQuotes_view). Non-admin users blocked by legacy crm_access bit 32 are denied. Roleless non-admin users fail closed. Also requires Quotes Edit (pageQuotes_edit); client administrators inherit page permissions.
Uses local tenant IDs. The active quote must also satisfy the account’s customer department/account-manager visibility filters for non-admin users, including signed-key requests.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Positive integer-compatible quote ID | Yes | Positive local quote ID, integer-converted; an active quote is required. |
field_id | Integer-compatible field ID | Yes, including table mode | Positive numeric field key; zero is allowed for isTableVal=1. Field schema/type is not validated. |
jpeg | Base64 string | One upload source | Strict base64 JPEG bytes; optional exact data:image/jpeg;base64, prefix. Overrides Filedata when present. |
Filedata | Multipart file | One upload source | Exact upload field used when jpeg is absent. Bytes are read from its temporary file; PHP upload limits apply. |
isTableVal | Value equal to 1 | No | When loosely equal to 1, stores the file but skips main-field assignment/history and returns only val. Default is main-field mode. |
Example request
$image = FM_api('Quote_setFieldImage', [
'id'=>'1042',
'field_id'=>'1042001',
'jpeg'=>base64_encode(file_get_contents('photo.jpg')),
]);
Example response
{"ok":1,"val":"{\"src\":\"1088x0123456789abcdef01234567.jpg\"}"}
val is an encoded JSON string, not an expanded image object. Its src uses acting-user ID, x and a random 24-character hexadecimal suffix, with a .jpg extension. Table mode returns {"val":"..."} without ok. No full URL or files-table ID 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":"quote does not exist"} | The active quote is missing (lookup failures are reported separately). |
{"error":"Unable to save quote. Check the saved state before retrying."} | Database, audit, transaction or commit acknowledgement failed. Refresh saved state before retrying an uncertain commit. |
{"error":"permission denied"} | Required Quotes permission is absent or the non-admin actor is blocked by legacy access settings. |
{"error":"missing or invalid parameter: id"} | Missing/nonpositive quote ID. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Accepts a successful multipart Filedata upload or strict base64 jpeg input, optionally prefixed by data:image/jpeg;base64,. jpeg takes precedence. Requires recognizable JPEG bytes and the configured file-library size limit; arbitrary bytes and other image types fail.
- Requires an active quote and numeric field_id; ordinary fields require a positive ID, while isTableVal=1 permits zero. Invalid existing form_fields is preserved and rejected. This does not verify the configured field type or resize images.
- Uses a collision-resistant actor-prefixed .jpg filename in the tenant images area. Requires filesLibSet ok=1 and a positive recorded file ID before returning a value. File attribution uses type_enum=12 and the quote ID.
- isTableVal=1 returns only val, an encoded JSON string containing src, and does not set a quote answer or audit a field edit. Otherwise stores that encoded string at form_fields[field_id] and returns ok/val.
- Database rows and field history use the tenant transaction. External storage cannot roll back with SQL: a later failure can leave an unreferenced uploaded file; do not assume retry removes it. Existing images with other filenames are retained.
- Locks the active quote in a tenant transaction. Bound writes, last_edited (server-local date/time), quote history and quotes cache invalidation are checked together. Audit or primary write failure rolls back. Existing caller transactions retain a savepoint; an uncertain commit returns an error and is never replayed automatically.
- No direct mobile app/m-service caller for this RPC was found.
Side effects
- Stores an attributed JPEG and file-library metadata. Ordinary field edits also update form_fields, last_edited and history; table-value uploads return a reference for a later table save. External storage can retain an orphan if the SQL transaction later fails.
See it in Fieldmotion
CRM1
Quotes → Notes/Fields photo Upload converts the browser image to JPEG, then calls Quote_setFieldImage. Table photos use isTableVal=1 and save the changed table separately.
CRM2
widgetPhoto uses Quote_setFieldImage for formFieldQuote/formFieldQuoteTable. Dropzone and deferred saves upload multipart Filedata; table mode sends field_id=0 and isTableVal=1.
Related endpoints
Quote_setFieldcan persist the parent table’s encoded rows after a table image upload.Quote_getTableColumnSumreads numerical table answers; it does not retrieve images.