Skip to main content

Reverse Movement — Pickup Parts from Repair Shop (leg 1 of 2)

Collects parts a repair shop no longer needs, ready to bring back to HQ. Genuinely two mobile sessions — this doc is leg 1 (pickup); leg 2 (drop-off at HQ) is 03-drop-off-parts-to-hq.md.

Endpoint

Same shared endpoint as 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: "reverse")

Same Parts_search_details event as the Direct flow (01) — movement_type selects which branch runs. This is the entry point for both legs of the Reverse trip: it also handles "this trip is already picked up, waiting for HQ drop-off" so mobile knows which screen to show. 03-drop-off-parts-to-hq.md doesn't have its own search step; it's reached from here.

Payload

{
{
"payload":{
"event_type": "Parts_search_details",
"user_email": "tonystarktest@outlook.com.au",
"details": {
"rego": "TN18AU1995",
"movement_type": "reverse"
}
}
}
}

Criteria (server-side)

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

reverse_movement = latest Parts_Movement where Claim_Form == claim AND Movement_Type == "reverse"

if reverse_movement exists AND Movement_Status == "Parts Picked Up":
→ stage = "dropoff" (already collected — go straight to leg 2)
parts_list = Deliver_Parts on that movement where Pickup == true
hq_location = reverse_movement.Crash_Claim_HQ
parts_movement_id = reverse_movement.ID

else:
parts = Parts_Order for this claim where Status == "Pending Repair Shop Pick-Up"
→ empty: error "No parts flagged for return at a repair shop"
→ stage = "pickup"
parts_list = those Parts_Order records

Response

{
"result": {
"data": {
"form_name": "pickup",
"movement_type": "reverse",
"parts_list": [
{
"parts_order_id": 10875000029042214,
"description": "Testing order parts"
}
],
"rego": "TN18AU1995"
},
"status": "success"
},
"code": 3000
}
FieldPresent whenNotes
stagealways"pickup" → use this doc's Step 2/3. "dropoff" → skip to 03-drop-off-parts-to-hq.md
hq_locationstage == "dropoff"Auto-populate for leg 2, same read-only rule as repairer elsewhere
parts_movement_idstage == "dropoff"The open trip to complete

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

Same two-call staging flow as every other doc — see 01-drop-off-parts-to-repair-shop.md §Step 2 for the full field list, response shapes, and why it's just a temporary holding spot. Only difference here: Movement_Stage: "reverse_pickup". The photo is copied out of this staging record into Deliver_Parts.Pickup_Image in Step 3 below — it is never the final home for the image.

Call 2a — parts_movement_upload_token

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

Returns record_id (= the image_id for Step 3), token, and the app/report/field link names.

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>
Content-Type: multipart/form-data

file: <binary>

Step 3 — parts_pick_up_reverse

Payload

{
"payload": {
"event_type": "parts_pick_up_reverse",
"user_email": "user@email.com",
"details": {
"rego": "TN42AU6373",
"delivery_location": "",
"movement_type": "reverse",
"parts": [
{ "parts_order_id": "10875000024189993", "confirm": true, "image_id": "10875000030314834" }
]
}
}
}
FieldRequiredNotes
regoClaim is resolved server-side — no claim_id is sent
movement_type"reverse"
delivery_locationSent as an empty string. The real production Reverse forms capture nothing for this (feature disabled server-side today); if HQ location ever needs capturing at pickup time, raise it as an open question before building
parts[]image_id is record_id from Step 2's Call 2a

Business logic

  1. Create one Parts_Movement: Movement_Type = "reverse", Movement_Status = "Parts Picked Up", Picked_Up_By = resolved user, Pick_Up_Date_Time = now, Location_Type = HQ.
  2. For each confirmed part: create Deliver_Parts (Pickup = 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. Delivery_Image stays empty — it's set later in leg 2, when this same Deliver_Parts record is updated rather than a new one created. Update Parts_Order.Status: Pending Repair Shop Pick-Up → Picked Up from Repair Shop.
  3. Link the movement onto Claims_Management_Form.Parts_Movement.
  4. Post the Cliq "Parts Picked Up From Repair Shop" announcement server-side.
  5. 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": 10875000030318113
},
{
"parts_order_id": 10875000024191015,
"delivery_id": 10875000030318117
}
],
"movement_type": "reverse",
"parts_movement_id": 10875000030318111
},
"status": "success"
},
"code": 3000
}

Carry parts_movement_id forward — leg 2 requires it. This response also echoes movement_type, which the other two handlers do not.

Error cases

Conditionresult.text
No parts have confirm: true"Select at least one part to collect."
A part is no longer Pending Repair Shop Pick-Up"<Part No.> is no longer flagged for return."
A confirmed part has no matching image_id"<Part No.> is missing its pickup photo."

Next

Driver returns to HQ later, searches the rego again (Parts_search_details returns stage: "dropoff"), and completes via 03-drop-off-parts-to-hq.md.