When to use this endpoint

Compare selected Job types across configured completion states, report periods and selected entities. Select the matching saved Reports dashboard chart or table, choose a bounded range, and use the returned series to render that report.

res has optional overall activity then type series plus unused zero rows. xLabels contains state names; xLabels1/xLabels2 contain the helper’s entity/period axes.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. The handler requires login and account reporting feature bit 8192. No separate Reports, Jobs, Tasks or finance page-permission check is added by the handler.

The dispatcher rejects this legacy Report route for configured TeamAccess record scope, including assigned-only/parent-manager access and applicable department hierarchy scope. It returns an explicit scope error rather than a silently filtered chart.

Allowed requests read the authenticated tenant. Entity selections are report filters or label controls, not authorization; the handler does not add customer account-manager ownership filtering.

Parameters

ParameterTypeRequiredDescription
daysFromInteger stringYesInclusive first date: relative day offset from current PHP time by default, or Unix seconds with durationType=1. Must be an integer; malformed/blank values are rejected. ISO strings are not parsed as dates.
daysToInteger stringYesInclusive last date, in the same mode as daysFrom. Expanded to 23:59:59 in the account timezone; no reversed-range validation.
durationTypeInteger stringNoDefault 0. Exactly 1 uses Unix seconds; other values convert integer day offsets through strtotime. Use 0/1; numeric values are validated before report SQL.
frequencyInteger stringNoDefault 0 monthly, 1 weekly, 2 quarterly, 3 yearly. Controls helper axis and grouping, using ISO week-year for weekly periods. Unsupported values are rejected.
userTypeInteger stringYes0 summary, 1 users, 2 customers, 3 asset-axis labels. User grouping is created_by for Invoices and assigned user_id for Jobs. Type 3 uses the same customer-key grouping as type 2 rather than an actual asset relationship.
userNative array of ID strings or ["All"]NoDefaults to ["All"]; a supplied empty list is rejected. Summary ignores the selection; individual axes include selected IDs by name. Pass a native array, not an encoded JSON string.
displayTypeInteger stringYes0 count; 1 meta.job_value sum. Other values fall back to count. Monetary aggregates are integer-converted; this is not a precise ledger export.
legendNative array of stringsYesNumeric Job type IDs, optionally Opportunity for all types within selected completion states. Overall alone is valid; native lists and tokens are validated.
statusNative array of state IDs or ["All"]NoDefaults to all configured completion states. Omitted, empty or ["All"] keeps all states; explicit numeric IDs are intersected with the configured list. No remaining known states returns No data in marketing source.

Example request

$report = FM_api('Report_getJobTypeStatusUser', [
	'daysFrom'=>'1768003200',
	'daysTo'=>'1768003200',
	'durationType'=>'1',
	'userType'=>'0',
	'frequency'=>'0',
	'displayType'=>'0',
	'user'=>['All'],
	'legend'=>['1'],
]);

Example response

{
  "res": [
    [
      0,
      0
    ],
    [
      0,
      0
    ]
  ],
  "xLabels": [
    "Incomplete",
    "Complete"
  ],
  "xLabels1": [
    "Jan 2026"
  ],
  "xLabels2": []
}

Representative empty-cohort result from the real handler with a January 2026 summary axis. The request timestamp is 2026-01-10 00:00:00 UTC and expands to account-local day boundaries.

res has optional overall activity then type series plus unused zero rows. xLabels contains state names; xLabels1/xLabels2 contain the helper’s entity/period axes.

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":"This legacy report does not support your configured record scope. Use the scoped Contracts reports or table exports."}The dispatcher detects configured TeamAccess record scope before the handler.
{"error":"no permission to access api"}Account reporting feature bit 8192 is absent.
{"error":"missing parameter: daysFrom"}The named parameter is omitted or null. Present blank/malformed controls return an invalid-parameter error instead; list controls must be native arrays.
{"error":"missing parameter: daysTo"}The named parameter is omitted or null. Present blank/malformed controls return an invalid-parameter error instead; list controls must be native arrays.
{"error":"missing parameter: userType"}The named parameter is omitted or null. Present blank/malformed controls return an invalid-parameter error instead; list controls must be native arrays.
{"error":"missing parameter: displayType"}The named parameter is omitted or null. Present blank/malformed controls return an invalid-parameter error instead; list controls must be native arrays.
{"error":"missing parameter: legend"}The named parameter is omitted or null. Present blank/malformed controls return an invalid-parameter error instead; list controls must be native arrays.
{"error":"No data in marketing source"}No configured completion-state IDs remain. This inherited message does not mean a marketing source is missing.
{"error":"invalid parameter: legend"}A supplied numeric/list control is malformed, a list contains unsupported tokens, or frequency/userType/date selectors are outside 0–3. The message names the invalid control; validation precedes chart queries.

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

Behaviour and edge cases

  • State labels and allowed state IDs are loaded from appointment-statuses. Omitted status, or a list containing All, keeps all configured IDs; explicit selections are intersected with that list.
  • No remaining configured states returns the misleading legacy error No data in marketing source. It refers to Job states here, not marketing data.
  • Filters and groups Job cdate, selects is_complete from status, and selects type_id from numeric legend. Unlike the scheduled type report, no deleted=0 predicate is added.
  • The exact Opportunity legend token requests overall activity across all Job types within the selected completion states. Overall-only requests skip the type-specific query and do not execute an empty IN list.
  • For legend=["1"], the response has two rows, the second unused. Overall plus one type allocates three rows with a trailing unused row. Axis order is period/entity then state in the selected configuration order.
  • Value mode sums only meta.job_value using the guarded JSON extraction helper. It does not use linked Invoice or Quote values, so it need not agree with other Job value reports.
  • CRM1 and both CRM2 saved-report expanders retain All states through the server’s all-configured-states path. Omitted status, ["All"] and an empty status list all select the configured states; explicit IDs select their intersection.
  • There is no pagination, checkpoint or result-size limit. Keep the date range and entity selection bounded. Aggregated values are numeric chart cells, not database scalar strings or object rows.
  • The helper orders periods first, then entities by name; one entity collapses xLabels to period text with empty xLabels1. Temporary users with non-null meta.is_tmp are excluded from user-axis lookups, but inactive/deleted label entities are not generally excluded. Unmatched entity/date keys are silently dropped.
  • PHP date conversion uses the account timezone (missing/null defaults to Europe/Dublin, blank means UTC). SQL date/Unix conversion uses its database session timezone; these handlers do not force cross-layer alignment.
  • Weekly axes enumerate real Mondays and use ISO week-year keys consistently with SQL. Week 53 and ranges crossing a calendar-year boundary are included; display labels are Week NN YYYY using the ISO year.
  • Numeric controls and native selector lists are validated through Report_validateChartRequest before SQL. JSON-encoded list strings, nested/object-keyed arrays, unsafe ID values and undocumented tokens are rejected. The existing login, reporting-feature and TeamAccess entry policies remain unchanged.
  • No direct caller for this endpoint was found in the mobile app or its m-service intermediary.

Side effects

  • Reads tenant data only; no business-record, audit, notification or schema writes occur. The chart restores its temporary PHP timezone on normal return paths.

See it in Fieldmotion

CRM1

Open Reports dashboard, add or preview Job Type per Status, choose filters and inspect Network for Report_getJobTypeStatusUser. pageReportDashboard.js constructs the endpoint dynamically from the saved api value. Generic legends can control presentation without changing the backend cohort; compare the actual request with this page’s parameter contract. All states uses the server’s all-configured-states path.

CRM2

Open Reports dashboard, add or preview Job Type per Status, choose filters and inspect Network for Report_getJobTypeStatusUser. lib/displayReport.js / pageReportDashboardDetails.js constructs the endpoint dynamically from the saved api value. Generic legends can control presentation without changing the backend cohort; compare the actual request with this page’s parameter contract. All states uses the server’s all-configured-states path.

Related endpoints