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