A quick article on a code snippet to mark a package as shipped and delivered in Zoho Inventory.
Why?
As usual, any task like this that takes me longer than an hour, I'd like to document for future use. The use-case is the client has their own delivery drivers and want them to mark a sales order & package as shipped and delivered.
How?
Here's a code snippet that works for me. It is triggered when a user ticks a decision box in Zoho Creator (on iPad displays as an on/off switch). My connection here called "jl_inventory" has the minimum required scopes:
- ZohoInventory.salesorders.READ
- ZohoInventory.packages.READ
- ZohoInventory.shipmentorders.CREATE
- ZohoInventory.shipmentorders.READ
// // init (put your own ZohoBooks/ZohoInventory Org ID v_BooksOrgID = 123456789; // // check the form was ticked and there is a package ID specified if(input.Mark_as_Complete && input.Zoho_Package_ID != "") { v_PackageID = input.Zoho_Package_ID; r_PackageSlip = zoho.inventory.getRecordsByID("packages",v_BooksOrgID.toString(),v_PackageID,"ab_inventory"); if(r_PackageSlip.get("package") != null) { if(r_PackageSlip.get("package").get("salesorder_id") != null) { v_SalesOrderID = r_PackageSlip.get("package").get("salesorder_id"); } if(r_PackageSlip.get("package").get("shipment_order") != null) { v_ShipmentID = r_PackageSlip.get("package").get("shipment_order").get("shipment_id"); // // if blank then create one if(v_ShipmentID == "") { m_Params = Map(); m_Params.put("date",zoho.currentdate.toString("yyyy-MM-dd")); m_Params.put("delivery_method","My_Own_Drivers"); m_Params.put("delivered_date",zoho.currentdate.toString("yyyy-MM-dd HH:mm")); m_Params.put("tracking_number","N/A"); l_UrlParams = List(); l_UrlParams.add("salesorder_id=" + v_SalesOrderID); l_UrlParams.add("package_ids=" + v_PackageID); l_UrlParams.add("is_delivered=true"); l_UrlParams.add("organization_id=" + v_BooksOrgID); v_Url = "https://inventory.zoho.com/api/v1/shipmentorders?" + l_UrlParams.toString("&"); r_CreateShipment = invokeurl [ url :v_Url type :POST parameters:m_Params.toString() connection:"jl_inventory" ]; info "Created Shipment: "; info r_CreateShipment; if(r_CreateShipment.get("shipment_order") != null) { if(r_CreateShipment.get("shipment_order").get("shipment_id") != null) { v_ShipmentID = r_CreateShipment.get("shipment_order").get("shipment_id"); } } } // // maybe one is either used or created if(v_ShipmentID != "") { v_Url = "https://inventory.zoho.com/api/v1/shipmentorders/" + v_ShipmentID + "/status/delivered?organization_id=" + v_BooksOrgID; r_Delivered = invokeurl [ url :v_Url type :POST connection:"jl_inventory" ]; info "Marked as Delivered:"; info r_Delivered; } } } }
- //
- // init (put your own ZohoBooks/ZohoInventory Org ID
- v_BooksOrgID = 123456789;
- //
- // check the form was ticked and there is a package ID specified
- if(input.Mark_as_Complete && input.Zoho_Package_ID != "")
- {
- v_PackageID = input.Zoho_Package_ID;
- r_PackageSlip = zoho.inventory.getRecordsByID("packages",v_BooksOrgID.toString(),v_PackageID,"ab_inventory");
- if(r_PackageSlip.get("package") != null)
- {
- if(r_PackageSlip.get("package").get("salesorder_id") != null)
- {
- v_SalesOrderID = r_PackageSlip.get("package").get("salesorder_id");
- }
- if(r_PackageSlip.get("package").get("shipment_order") != null)
- {
- v_ShipmentID = r_PackageSlip.get("package").get("shipment_order").get("shipment_id");
- //
- // if blank then create one
- if(v_ShipmentID == "")
- {
- m_Params = Map();
- m_Params.put("date",zoho.currentdate.toString("yyyy-MM-dd"));
- m_Params.put("delivery_method","My_Own_Drivers");
- m_Params.put("delivered_date",zoho.currentdate.toString("yyyy-MM-dd HH:mm"));
- m_Params.put("tracking_number","N/A");
- l_UrlParams = List();
- l_UrlParams.add("salesorder_id=" + v_SalesOrderID);
- l_UrlParams.add("package_ids=" + v_PackageID);
- l_UrlParams.add("is_delivered=true");
- l_UrlParams.add("organization_id=" + v_BooksOrgID);
- v_Url = "https://inventory.zoho.com/api/v1/shipmentorders?" + l_UrlParams.toString("&");
- r_CreateShipment = invokeUrl
- [
- url :v_Url
- type :POST
- parameters:m_Params.toString()
- connection:"jl_inventory"
- ];
- info "Created Shipment: ";
- info r_CreateShipment;
- if(r_CreateShipment.get("shipment_order") != null)
- {
- if(r_CreateShipment.get("shipment_order").get("shipment_id") != null)
- {
- v_ShipmentID = r_CreateShipment.get("shipment_order").get("shipment_id");
- }
- }
- }
- //
- // maybe one is either used or created
- if(v_ShipmentID != "")
- {
- v_Url = "https://inventory.zoho.com/api/v1/shipmentorders/" + v_ShipmentID + "/status/delivered?organization_id=" + v_BooksOrgID;
- r_Delivered = invokeUrl
- [
- url :v_Url
- type :POST
- connection:"jl_inventory"
- ];
- info "Marked as Delivered:";
- info r_Delivered;
- }
- }
- }
- }
Error(s) Encountered
- {"code": 4,"message": "Invalid value passed for salesorder_id"}: Not sure about what ended up fixing this one. I think I converted the sales order to an invoice and created a package slip for it. The invoice was then sent (payment=unpaid). Not sure which fixed this.
- {"code": 4,"message": "Invalid value passed for JSONString"}: Quick fix by settings the parameters in the invokeUrl to a string m_Params.toString()