A quick article on how to use remove() on a map variable as well as a snippet of code to copy tags from a contact to a deal record.
Why?
Anything that stumps me for 30 minutes is worth writing a quick article on. In this case, I had a function querying tags on a contact record which needed to be copied to a deal record. I wanted to copy over the tag but apparently, the ID of the tag is not allowed to be copied over.
The official documentation says to use remove() to remove a key from a map. In this case, the ID key and value pair. It would then tell me the list was null when I thought I was adding the map with the ID removed back into a list. The map itself was null.
How?
We are using an API action called "Add_Tags". I'm going to get the tags of the contact record using an invokeurl because shortcode only gives me name and ID; but I want the color code field as well which I only seem to get with an InvokeURL. I'm then going to create a list map of tags and add these to the deal record.
The key take-away to remember here is that remove() is a void function, similar to the sort() function; in that if you try to assign this to a new variable name, it will fail.
In other words:
copyraw
m_NewTag = m_Tag.remove("id"); // yields null m_Tag.remove("id"); // returns m_Tag map without the ID key-value pair
- m_NewTag = m_Tag.remove("id");
- // yields null
- m_Tag.remove("id");
- // returns m_Tag map without the ID key-value pair
The use-case
This is a snippet that gets the tags of a contact and copies it over to the deal record:
copyraw
l_Tags = List(); // r_DealDetails = zoho.crm.getRecordById("Deals",p_DealID); if(!isNull(r_DealDetails.get("Contact_Name"))) { r_ContactDetails = invokeurl [ url :"https://www.zohoapis.com/crm/v7/Contacts/" + r_DealDetails.get("Contact_Name").get("id") type :GET connection:"zcrm" ]; // l_ContactDetails = ifnull(r_ContactDetails.get("data"), List()); for each m_ContactDetails in l_ContactDetails { if(!isNull(m_ContactDetails.get("Tag"))) { for each m_Tag in m_ContactDetails.get("Tag") { m_Tag.remove("id"); l_Tags.add(m_Tag); } } info l_Tags; // if(l_Tags.size()>0) { m_Params = {"tags": l_Tags}; r_AddTags = invokeurl [ url :"https://www.zohoapis.com/crm/v7/Deals/" + p_DealID + "/actions/add_tags" type :POST parameters:m_Params.toString() connection:"azcrm" ]; info r_AddTags; } } }
- l_Tags = List();
- //
- r_DealDetails = zoho.crm.getRecordById("Deals",p_DealID);
- if(!isNull(r_DealDetails.get("Contact_Name")))
- {
- r_ContactDetails = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v7/Contacts/" + r_DealDetails.get("Contact_Name").get("id")
- type :GET
- connection:"zcrm"
- ];
- //
- l_ContactDetails = ifnull(r_ContactDetails.get("data"), List());
- for each m_ContactDetails in l_ContactDetails
- {
- if(!isNull(m_ContactDetails.get("Tag")))
- {
- for each m_Tag in m_ContactDetails.get("Tag")
- {
- m_Tag.remove("id");
- l_Tags.add(m_Tag);
- }
- }
- info l_Tags;
- //
- if(l_Tags.size()>0)
- {
- m_Params = {"tags": l_Tags};
- r_AddTags = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v7/Deals/" + p_DealID + "/actions/add_tags"
- type :POST
- parameters:m_Params.toString()
- connection:"azcrm"
- ];
- info r_AddTags;
- }
- }
- }
copyraw
/* {"code":"INVALID_DATA","details":{"api_name":"id","json_path":"$.tags[0].id"},"message":"invalid tag id","status":"error"} -> Error was due to trying to assign map with removed key to a new map. -> Solution was to remove the assignment and simply keep m_Tag.remove("id"); {"code":"MAPPING_MISMATCH","details":{"mapped_field":{"api_name":"name","json_path":"$.tags[0].name"},"api_name":"color_code","json_path":"$.tags[0].color_code"},"message":"Given tag present with different colour already.","status":"error"} -> Error was due to someone already giving tags with the same name -> Solution is to remove the color_code key as well... m_Tag.remove("color_code"); */
- /*
- {"code":"INVALID_DATA","details":{"api_name":"id","json_path":"$.tags[0].id"},"message":"invalid tag id","status":"error"}
- -> Error was due to trying to assign map with removed key to a new map.
- -> Solution was to remove the assignment and simply keep m_Tag.remove("id");
- {"code":"MAPPING_MISMATCH","details":{"mapped_field":{"api_name":"name","json_path":"$.tags[0].name"},"api_name":"color_code","json_path":"$.tags[0].color_code"},"message":"Given tag present with different colour already.","status":"error"}
- -> Error was due to someone already giving tags with the same name
- -> Solution is to remove the color_code key as well... m_Tag.remove("color_code");
- */
Considering that neither the color code nor ID were necessary in the end, I can use shortcode for getting the tag. Note that on a fresh CRM instance where no tags have been used previously, I would use the code above to maintain tag colors. Here's the shortened version where the system chooses the color for the tag:
copyraw
l_Tags = List(); // r_DealDetails = zoho.crm.getRecordById("Deals",p_DealID); if(!isNull(r_DealDetails.get("Contact_Name"))) { m_ContactDetails = zoho.crm.getRecordById("Contacts", r_DealDetails.get("Contact_Name").get("id")); if(!isNull(m_ContactDetails.get("Tag"))) { for each m_Tag in m_ContactDetails.get("Tag") { m_Tag.remove("id"); l_Tags.add(m_Tag); } } info l_Tags; // if(l_Tags.size()>0) { m_Params = {"tags": l_Tags}; r_AddTags = invokeurl [ url :"https://www.zohoapis.com/crm/v7/Deals/" + p_DealID + "/actions/add_tags" type :POST parameters:m_Params.toString() connection:"zcrm" ]; info r_AddTags; } }
- l_Tags = List();
- //
- r_DealDetails = zoho.crm.getRecordById("Deals",p_DealID);
- if(!isNull(r_DealDetails.get("Contact_Name")))
- {
- m_ContactDetails = zoho.crm.getRecordById("Contacts", r_DealDetails.get("Contact_Name").get("id"));
- if(!isNull(m_ContactDetails.get("Tag")))
- {
- for each m_Tag in m_ContactDetails.get("Tag")
- {
- m_Tag.remove("id");
- l_Tags.add(m_Tag);
- }
- }
- info l_Tags;
- //
- if(l_Tags.size()>0)
- {
- m_Params = {"tags": l_Tags};
- r_AddTags = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v7/Deals/" + p_DealID + "/actions/add_tags"
- type :POST
- parameters:m_Params.toString()
- connection:"zcrm"
- ];
- info r_AddTags;
- }
- }
Fix to historical records
This snippet uses COQL to find me all the deals where the tag is empty but the contact record wasn't. There is an additional/repeat action to add tags; the first attempts to copy over the color on a new tag; the second is if this fails to copy over the color (because there is an existing tag with the same name), then it only copies over the name:
copyraw
v_TotalCount = 0; v_TotalProcessed = 0; v_PerPage = 100; v_CoqlQuery = "select id, Contact_Name.Tag 'Tag' from Deals where Tag is null and Contact_Name.Tag is not null order by id asc limit " + v_PerPage; m_Params = {"select_query":v_CoqlQuery}; r_Coql = invokeurl [ url :"https://www.zohoapis.com/crm/v7/coql" type :POST parameters:m_Params.toString() connection:"zcrm" ]; if(!isNull(r_Coql.get("data"))) { for each m_Data in r_Coql.get("data") { if(!isNull(m_Data.get("id"))) { v_TotalCount = v_TotalCount + 1; // l_Tags = List(); for each m_Tag in m_Data.get("Tag") { m_Tag.remove("id"); l_Tags.add(m_Tag); } if(l_Tags.size() > 0) { m_Params = {"tags":l_Tags}; r_AddTags = invokeurl [ url :"https://www.zohoapis.com/crm/v6/Deals/" + m_Data.get("id") + "/actions/add_tags" type :POST parameters:m_Params.toString() connection:"zcrm" ]; if(!isNull(r_AddTags.get("code")) && r_AddTags.get("code").equals("MAPPING_MISMATCH")) { info "Tags Error: MAPPING_MISMATCH: Color"; info m_Tag.get("name") + " " + m_Tag.get("color_code"); // l_Tags = List(); for each m_Tag in m_Data.get("Tag") { m_Tag.remove("id"); m_Tag.remove("color_code"); l_Tags.add(m_Tag); } m_Params = {"tags":l_Tags}; r_AddTags = invokeurl [ url :"https://www.zohoapis.com/crm/v7/Deals/" + m_Data.get("id") + "/actions/add_tags" type :POST parameters:m_Params.toString() connection:"zcrm" ]; } if(!isNull(r_AddTags.get("code")) && r_AddTags.get("code").equals("SUCCESS")) { info "Tag Error resolved. Tags updated."; v_TotalProcessed = v_TotalProcessed + 1; } } } info "-------------------------"; } } return "Updated " + v_TotalProcessed + " of " + v_TotalCount;
- v_TotalCount = 0;
- v_TotalProcessed = 0;
- v_PerPage = 100;
- v_CoqlQuery = "select id, Contact_Name.Tag 'Tag' from Deals where Tag is null and Contact_Name.Tag is not null order by id asc limit " + v_PerPage;
- m_Params = {"select_query":v_CoqlQuery};
- r_Coql = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v7/coql"
- type :POST
- parameters:m_Params.toString()
- connection:"zcrm"
- ];
- if(!isNull(r_Coql.get("data")))
- {
- for each m_Data in r_Coql.get("data")
- {
- if(!isNull(m_Data.get("id")))
- {
- v_TotalCount = v_TotalCount + 1;
- //
- l_Tags = List();
- for each m_Tag in m_Data.get("Tag")
- {
- m_Tag.remove("id");
- l_Tags.add(m_Tag);
- }
- if(l_Tags.size() > 0)
- {
- m_Params = {"tags":l_Tags};
- r_AddTags = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v6/Deals/" + m_Data.get("id") + "/actions/add_tags"
- type :POST
- parameters:m_Params.toString()
- connection:"zcrm"
- ];
- if(!isNull(r_AddTags.get("code")) && r_AddTags.get("code").equals("MAPPING_MISMATCH"))
- {
- info "Tags Error: MAPPING_MISMATCH: Color";
- info m_Tag.get("name") + " " + m_Tag.get("color_code");
- //
- l_Tags = List();
- for each m_Tag in m_Data.get("Tag")
- {
- m_Tag.remove("id");
- m_Tag.remove("color_code");
- l_Tags.add(m_Tag);
- }
- m_Params = {"tags":l_Tags};
- r_AddTags = invokeUrl
- [
- url :"https://www.zohoapis.com/crm/v7/Deals/" + m_Data.get("id") + "/actions/add_tags"
- type :POST
- parameters:m_Params.toString()
- connection:"zcrm"
- ];
- }
- if(!isNull(r_AddTags.get("code")) && r_AddTags.get("code").equals("SUCCESS"))
- {
- info "Tag Error resolved. Tags updated.";
- v_TotalProcessed = v_TotalProcessed + 1;
- }
- }
- }
- info "-------------------------";
- }
- }
- return "Updated " + v_TotalProcessed + " of " + v_TotalCount;
Category: Zoho :: Article: 898
Add comment