A quick article on how to get the pricebook entry using Zoho Deluge for a specific product in your ZohoBooks or ZohoInventory instance.
Why?
This took me the best part of an hour to determine by going through forum posts from 7 years to 2 years ago. The following will work in May 2024 following the API domain change.
The use-case is that the customer wants the item/product rate taken from the item record, if a pricebook is specified and the item exists within it, then it takes the rate from the pricelist. Note that when I refer to pricebook, this is also referred to as the pricelist... and vice-versa.
And in this use-case, my client has added an incredible number of price books/ price lists and then has in excess of 20k items. Previously, the function that would need to get the price book rate post saving a record in Zoho Deluge would fail because it was making too many function statements.
How?
I have this code triggered in a workflow when the sales order is created to do some further calculations based on a surcharge rate held in a custom module. The custom module could only be created in Zoho Books at time of print but Zoho Inventory is where our workflow and code is sitting right now.
The code snippet to get the item record from the price book
Note that I'm using a connection called "zbooks" and it has every permission under the sun (the naughty ZohoBooks.fullaccess.all) but according to documentation (to be taken with a grain of salt), the scope should be ZohoInventory.settings.READ. I have another connection called "zinventory" which is used here to retrieve the item/product record.
// // initialize m_Blank = Map(); // // evaluate v_BooksOrgID = organization.get("organization_id"); // // loop through line items for each m_LineItem in salesorder.get("line_items") { r_BooksItem = zoho.inventory.getRecordsByID("items", v_BooksOrgID, m_LineItem.get("item_id"), "zinventory"); m_BooksItem = ifnull(r_BooksItem.get("item"), m_Blank); v_BooksItemRate = ifnull(m_BooksItem.get("rate"),0.00); v_ThisQuantity = ifnull(m_LineItem.get("quantity"),1); info "Line Item Rate: " + v_BooksItemRate; info "Line Item Quantity: " + v_ThisQuantity; // if(m_LineItem.get("pricebook_id") != null && m_LineItem.get("pricebook_id") != "") { m_Params = Map(); m_Params.put("organization_id", v_BooksOrgID); m_Params.put("pricebook_id", m_LineItem.get("pricebook_id")); m_Params.put("item_ids", m_LineItem.get("item_id")); m_Params.put("sales_or_purchase_type", "sales"); v_PriceBookEndpoint = "https://www.zohoapis.com/books/v3/items/pricebookrate"; r_ThisPriceBook = invokeurl [ url : v_PriceBookEndpoint type :GET parameters: m_Params connection:"zbooks" ]; // // tests show this only returns the 1 relevant item from a pricebook of many more items l_PriceBookItems = ifnull(r_ThisPriceBook.get("items"),{}); for each m_PriceBookItem in l_PriceBookItems { if(m_PriceBookItem.get("default_price_brackets").size() > 0) { m_ThisPriceBookDefault = m_PriceBookItem.get("default_price_brackets").get(0); v_BooksItemRate = ifnull(m_ThisPriceBookDefault.get("pricebook_rate"),v_BooksItemRate); info "Pricebook Item Default Rate: " + v_BooksItemRate; } if(m_PriceBookItem.get("pricing_scheme")=="volume") { for each m_PriceBracket in m_PriceBookItem.get("price_brackets") { if(v_ThisQuantity >= m_PriceBracket.get("start_quantity")) { if(m_PriceBracket.get("end_quantity") != "" && v_ThisQuantity <= m_PriceBracket.get("end_quantity")) { v_BooksItemRate = ifnull(m_PriceBracket.get("pricebook_rate"),v_BooksItemRate); info "Pricebook Item Volume Rate: " + v_BooksItemRate; } else if(m_PriceBracket.get("end_quantity") == "") { v_BooksItemRate = ifnull(m_PriceBracket.get("pricebook_rate"),v_BooksItemRate); info "Pricebook Item Volume Rate: " + v_BooksItemRate; } } } } } } info "Final Item Rate: " + v_BooksItemRate; }
- //
- // initialize
- m_Blank = Map();
- //
- // evaluate
- v_BooksOrgID = organization.get("organization_id");
- //
- // loop through line items
- for each m_LineItem in salesorder.get("line_items")
- {
- r_BooksItem = zoho.inventory.getRecordsByID("items", v_BooksOrgID, m_LineItem.get("item_id"), "zinventory");
- m_BooksItem = ifnull(r_BooksItem.get("item"), m_Blank);
- v_BooksItemRate = ifnull(m_BooksItem.get("rate"),0.00);
- v_ThisQuantity = ifnull(m_LineItem.get("quantity"),1);
- info "Line Item Rate: " + v_BooksItemRate;
- info "Line Item Quantity: " + v_ThisQuantity;
- //
- if(m_LineItem.get("pricebook_id") != null && m_LineItem.get("pricebook_id") != "")
- {
- m_Params = Map();
- m_Params.put("organization_id", v_BooksOrgID);
- m_Params.put("pricebook_id", m_LineItem.get("pricebook_id"));
- m_Params.put("item_ids", m_LineItem.get("item_id"));
- m_Params.put("sales_or_purchase_type", "sales");
- v_PriceBookEndpoint = "https://www.zohoapis.com/books/v3/items/pricebookrate";
- r_ThisPriceBook = invokeUrl
- [
- url : v_PriceBookEndpoint
- type :GET
- parameters: m_Params
- connection:"zbooks"
- ];
- //
- // tests show this only returns the 1 relevant item from a pricebook of many more items
- l_PriceBookItems = ifnull(r_ThisPriceBook.get("items"),{});
- for each m_PriceBookItem in l_PriceBookItems
- {
- if(m_PriceBookItem.get("default_price_brackets").size() > 0)
- {
- m_ThisPriceBookDefault = m_PriceBookItem.get("default_price_brackets").get(0);
- v_BooksItemRate = ifnull(m_ThisPriceBookDefault.get("pricebook_rate"),v_BooksItemRate);
- info "Pricebook Item Default Rate: " + v_BooksItemRate;
- }
- if(m_PriceBookItem.get("pricing_scheme")=="volume")
- {
- for each m_PriceBracket in m_PriceBookItem.get("price_brackets")
- {
- if(v_ThisQuantity >= m_PriceBracket.get("start_quantity"))
- {
- if(m_PriceBracket.get("end_quantity") != "" && v_ThisQuantity <= m_PriceBracket.get("end_quantity"))
- {
- v_BooksItemRate = ifnull(m_PriceBracket.get("pricebook_rate"),v_BooksItemRate);
- info "Pricebook Item Volume Rate: " + v_BooksItemRate;
- }
- else if(m_PriceBracket.get("end_quantity") == "")
- {
- v_BooksItemRate = ifnull(m_PriceBracket.get("pricebook_rate"),v_BooksItemRate);
- info "Pricebook Item Volume Rate: " + v_BooksItemRate;
- }
- }
- }
- }
- }
- }
- info "Final Item Rate: " + v_BooksItemRate;
- }
Code to get all pricebooks
Adding this here on the per chance you want to use this. But the official documentation will give you this as well:
v_BooksOrgID = organization.get("organization_id"); r_AllPriceBooks = invokeurl [ url :"https://www.zohoapis.com/inventory/v1/pricebooks?organization_id="+v_BooksOrgID type :GET connection:"zinventory" ];
- v_BooksOrgID = organization.get("organization_id");
- r_AllPriceBooks = invokeUrl
- [
- url :"https://www.zohoapis.com/inventory/v1/pricebooks?organization_id="+v_BooksOrgID
- type :GET
- connection:"zinventory"
- ];
Code to get a specific pricebook
Adding this here on the per chance you want to use this. But the official documentation will give you this as well (somewhere). Annoyingly, pricebooks are only mentioned in the line item rather than at the header level:
v_BooksOrgID = organization.get("organization_id"); r_ThisPriceBook = invokeurl [ url :"https://www.zohoapis.com/inventory/v1/pricebooks/"+m_LineItem.get("pricebook_id")+"?organization_id="+v_BooksOrgID type :GET connection:"zinventory" ];
- v_BooksOrgID = organization.get("organization_id");
- r_ThisPriceBook = invokeUrl
- [
- url :"https://www.zohoapis.com/inventory/v1/pricebooks/"+m_LineItem.get("pricebook_id")+"?organization_id="+v_BooksOrgID
- type :GET
- connection:"zinventory"
- ];
Error(s) Encountered
{ "code": 37, "message": "The HTTP method GET is not allowed for the requested resource" }
You can still use GET. For this, I had to change the endpoint to the Books v3 API and push through the parameters as per my code above.For security reasons you have been blocked for some time as you have exceeded the maximum number of requests per minute
Getting the item specifically from the pricebook using the code above fixed this as previously it was running into too many statement execution limits.
Source(s):
- Zoho Community - Zoho Inventory - Zoho Inventory API - Price List Access
- Zoho Community - Zoho Books - Zoho Books Pricelist API- Get Price of an item in Pricelist