Skip to main content

Direct Movement — Drop Off Parts to Repair Shop

Endpoint (all steps below, except the image upload)

One endpoint, event_type selects the operation. Same URL for every doc in this spec.

  • Dev: https://www.zohoapis.com.au/creator/custom/clientportal/Mobile_Kratos_Incoming_handler_DEV?publickey=xxxxxxxxxxxxxxxxxxxx
  • Method: POST

Step 1 — Parts_search_details (movement_type: "direct")

Payload

{
"payload": {
"event_type": "Parts_search_details",
"user_email": "vignesh.au.2024@gmail.com",
"details": {
"rego": "TN25AU3490",
"movement_type": "direct"
}
}
}
FieldTypeRequiredNotes
regostringMatched case-insensitively against Claim_Form.Customer_Registration

Criteria (server-side)

claim_rec = Claim_Form where Customer_Registration contains rego
→ not found: error "Rego not found"

claims_management_rec = Claims_Management_Form linked to claim_rec
→ not found: error "Record not found"

parts_list = Parts_Order for this claim where Status == "Arrived"
→ empty: error "No parts ready for delivery to a repair shop"

repairer = claims_management_rec.Repairer

Response

{
"result": {
"data": {
"repairer": 10875000022297868,
"form_name": "pickup",
"movement_type": "direct",
"rego": "TN25AU3490",
"parts_list": [
{
"parts_order_id": 10875000030088709,
"description": "Testing",
"order_status": "Arrived"
}
]
},
"status": "success"
},
"code": 3000
}

repairer is auto-populated and read-only in the mobile UI — no location picker.


Step 2 — Upload Image (per part) — two calls

Two calls per photo. The staging form Parts_Uploaded_Images exists only to give mobile somewhere to put the raw file before the real Deliver_Parts record exists (that record isn't created until Step 3 submits). It is not the final home for the photo: Step 3 copies the image out of this staging record into the real target, the Deliver_Parts subform's Pickup_Image / Delivery_Image fields. Treat Parts_Uploaded_Images rows as disposable once copied.

Mobile never calls Zoho's native Add-Records API. Call 2a is the usual custom event on the shared handler — Creator creates the staging record and mints a short-lived OAuth token in the same call. Call 2b is the only raw-Zoho call in the whole flow.

Parts_Uploaded_Images fields

FieldTypeNotes
Parts_Orderpicklist → Parts_Order.IDWhich part this photo is for
Claim_Formpicklist → Claim_Form.IDResolved server-side from rego
Movement_Stagepicklist"direct_dropoff" for this doc
Parts_ImageimageThe photo (note: Parts_Image, not Image)
Uploaded_Bypicklist → User.IDResolved from user_email
Uploaded_TimedatetimeServer-set

Call 2a — parts_movement_upload_token

Same shared handler endpoint as every other event. Note the fields sit directly on payload, not nested under details.

{
"payload": {
"event_type": "parts_movement_upload_token",
"Parts_Order": "10875000024191015",
"Movement_Stage": "direct_dropoff",
"rego": "TN25AU3490",
"user_email": "user@email.com"
}
}

Response

{
"result": {
"data": {
"app_owner": "clientportal",
"app_name": "test-claims-management-portal",
"form_name": "Parts_Uploaded_Images",
"report_name": "Parts_Movement_Uploaded_Images_Temp_Report",
"field_name": "Parts_Image",
"record_id": 10875000030314834,
"token": "xxxxxxx",
"environment": true
},
"status": "success"
},
"code": 3000
}
  • record_id is the image_id to carry into Step 3 — nothing from Call 2b needs capturing.
  • environment is only present in stage/development; omitted in production, same as the Fuel Receipt flow.
  • The token is opaque and short-lived — mint one per upload, never store it on the device.

Call 2b — attach the file

POST https://www.zohoapis.com.au/creator/v2.1/data/{app_owner}/{app_name}/report/{report_name}/{record_id}/{field_name}/upload
Authorization: Zoho-oauthtoken <token from 2a>
environment: development # stage/dev only
Content-Type: multipart/form-data

file: <binary>

Uses the report link name (Parts_Movement_Uploaded_Images_Temp_Report), not the form link name.

Response

{
"code": 3000,
"data": { "filename": "download.jpeg", "message": "File Uploaded Successfully" }
}

This response does not repeat the record ID — use record_id from Call 2a.

Repeat both calls once per confirmed part — one photo each, not one for the whole trip.


Step 3 — parts_drop_off

Payload

{
"payload": {
"event_type": "parts_drop_off",
"user_email": "user@email.com",
"details": {
"rego": "TN42AU6373",
"delivery_location": { "id": "10875000020622521", "name": "Bankstown Muffler Fit" },
"movement_type": "direct",
"parts": [
{ "parts_order_id": "10875000024189993", "confirm": true, "image_id": "10875000030314834" }
]
}
}
}
FieldRequiredNotes
regoFrom Step 1. The claim is resolved server-side — no claim_id is sent
movement_type"direct"
delivery_location{ id, name } — the repairer picked from the repairer-list dropdown, not just passed straight back from Step 1 (Step 1's repairer doesn't always resolve, e.g. fleet/loan-car/private jobs with no linked claim)
parts[]confirm: false rows are dropped. image_id is record_id from Step 2's Call 2a

Business logic

Single transaction — both legs of the physical trip (HQ pickup, repair-shop drop-off) are recorded together, since the driver only opens the app once, already at the repair shop:

  1. Create one Parts_Movement: Movement_Type = "direct", Movement_Status = "Parts Dropped off", Picked_Up_By / Dropped_Of_By = the same user, Pick_Up_Date_Time / Dropped_Off_Date_Time = the same timestamp, Repair_Shop = delivery_location.id (and/or .name, whichever the target field expects).
  2. For each confirmed part: create Deliver_Parts (Pickup = true, Delivery = true, QtyOrdered from the part, Parts_Movement = the new movement). Look up the staged row in Parts_Uploaded_Images by image_id, then copy its Parts_Image into this Deliver_Parts record's Pickup_Image field and its Delivery_Image field — both, since this combined flow only ever captures one photo per part (there's no separate HQ-pickup photo to put in Pickup_Image otherwise). Update Parts_Order.Status: Arrived → Delivered to Repair Shop directly.
  3. Post the Cliq "Parts Delivered" announcement (Parts Movement + New Repair Jobs channels) — server-side, mobile does not call anything further.
  4. Once copied, the staging row in Parts_Uploaded_Images is no longer needed — safe to delete or leave for audit, at the Creator side's discretion.

Response

{
"result": {
"data": {
"delivery_parts": [
{
"parts_order_id": 10875000024189993,
"delivery_id": 10875000030318098
},
{
"parts_order_id": 10875000024191015,
"delivery_id": 10875000030318102
}
],
"parts_movement_id": 10875000030318096
},
"status": "success"
},
"code": 3000
}

delivery_parts[] (not deliver_parts) with delivery_id (not deliver_parts_id); IDs are numbers, not strings.

Error cases

Conditionresult.text
rego resolves to no claim"Claim not found."
No parts have confirm: true"Select at least one part to deliver."
A confirmed part has no matching image_id"<Part No.> is missing its delivery photo."
A part is no longer Arrived (raced by the Dashboard)"<Part No.> is no longer available for delivery."