Auto Assign Reporting Tag in Zoho Books

Difficulty: Advanced
Estimated reading time: 15 mins
Estimated implementation time: 1 hour and 15 mins

Auto Assign Reporting Tag Zoho Books

Automatically creates and assigns a Reporting Tag to an Invoice Line Item, if there is an associated Project. Can be adapted to work on other modules.


This function relies heavily on the Zoho Books API. To access this API, we need to create a Custom Connection to Zoho Books. Here are the steps you need to take to create this Custom Connection:

Create API Credentials: Gives you a Client ID and Client Secret to use in the next step.

  1. Go to the Zoho API Console
  2. Click Add Client and select Server-based Applications
  3. Fill in the following fields:
    • Client Name -> Zoho Books API
    • Homepage URL -> https://books.zoho.com
    • Authorized Redirect URIs -> https://deluge.zoho.com/delugeauth/callback
  4. Click Update
  5. Notice the Client ID and Client Secret here. You will need these in the next step, so keep this tab open.

Want to learn even more? Sign up for one of our Zoho courses!

Create Custom Connection

  1. Go to Zoho Books
  2. Click Settings, select the Automation tab, then choose Custom Functions.
  3. Select + New Custom Function and give it a random name and module. We will only use this function for a simple test.
  4. Choose Connections on the right hand side, then Go To Connections.
  5. Click Add Connection. Choose Custom Service.
  6. Fill in the following fields (This has to be very exact):
    • Service Name -> Zoho Books
    • Service LinkName -> zoho_books
    • Authentication Type -> oAuth2
    • Param Type -> Header
    • Grant Type -> Authorization Code
    • Client ID -> [YOUR_CLIENT_ID]
    • Client Secret -> [YOUR_CLIENT_SECRET]
    • Authorize URL -> https://accounts.zoho.com/oauth/v2/auth?
    • Access Token URL -> https://accounts.zoho.com/oauth/v2/token?
    • Refresh Token URL -> https://accounts.zoho.com/oauth/v2/token?
    • Connection Name -> Zoho Books
    • Connection LinkName -> zoho_books
    • Scope -> ZohoBooks.fullaccess.all (Note: Be sure to click the ‘+’ for the scope)
    • Use credentials of login user -> UNCHECKED
  7. Click Create and Connect. If asked to authenticate, enter your login details.

Test the Connection

1. Go to the custom function you previously created.
2. Input the following:

 				 					organizationId = organization.get("organization_id");  response = invokeUrl [   url : "https://books.zoho.com/api/v3/invoices?organization_id=" + organizationId     type : GET     connection : "zoho_books" ];  info response; 				 			

3. Run the script and make sure you receive a response that is not an error.


Full Assign Tag Script

 				 					// Setup Invoice variables INVOICE_ID = invoice.get("invoice_id"); ORG_ID = organization.get("organization_id"); searchFullInvoice = zoho.books.getRecordsByID("Invoices",ORG_ID,INVOICE_ID); fullInvoice = searchFullInvoice.get("invoice"); lineItems = fullInvoice.get("line_items");  // // Get all reporting tags in organization via Zoho Books API reportingTagsResponse = invokeurl [ 	url :"https://books.zoho.com/api/v3/settings/tags?organization_id=" + ORG_ID 	type :GET 	connection:"zoho_books" ]; reportingTags = reportingTagsResponse.get("reporting_tags");  // // Create map of Reporting Tag IDs, keyed by tag name for lookup reportingTagsMap = Map(); for each  reportingTag in reportingTags { 	tagName = reportingTag.get("tag_name"); 	tagId = reportingTag.get("tag_id"); 	reportingTagsMap.put(tagName,tagId); } taggedLineItemsMap = Map();  // // Loop over Line Items  for each  lineItem in lineItems { 	lineItemId = lineItem.get("line_item_id"); 	projectName = lineItem.get("project_name");    	// 	// Check if item has project 	if(!isNull(projectName)) 	{ 		// Check if tag currently exists, if not, create a new one 		if(!reportingTagsMap.containKey(projectName)) 		{ 			// Create new tag 			newTagMap = {"JSONString":{"tag_name":projectName,"tag_options":{{"tag_option_name":projectName,"is_active":true}}}}; 			createTag = invokeurl 			[ 				url :"https://books.zoho.com/api/v3/settings/tags?organization_id=" + ORG_ID 				type :POST 				parameters:newTagMap 				connection:"zoho_books" 			]; 			info createTag; 			responseCode = createTag.get('code');        			// 			// If Create Tag is sucessfull, add tag data to the reportingTagsmap 			if(responseCode == 0) 			{ 				reportingTag = createTag.get("reporting_tag"); 				tagName = reportingTag.get("tag_name"); 				tagId = reportingTag.get("tag_id"); 				reportingTagsMap.put(tagName,tagId); 			} 		} 		tagName = projectName; 		tagId = reportingTagsMap.get(tagName);      		// 		// Get full reporting tag 		reportingTagResponse = invokeurl 		[ 			url :"https://books.zoho.com/api/v3/settings/tags/" + tagId + "?organization_id=" + ORG_ID 			type :GET 			connection:"zoho_books" 		];      		// 		// Get Tag Option ID. This assumes there is only one tag option per tag.  		reportingTag = reportingTagResponse.get("reporting_tag"); 		tagOptions = reportingTag.get("tag_options"); 		defaultTagOption = tagOptions.get(0); 		defaultTagOptionId = defaultTagOption.get("tag_option_id");      		// 		// Construct line item update map 		lineItemUpdateMap = Map(); 		lineItemUpdateMap.put("line_item_id",lineItemId); 		lineItemUpdateMap.put("tags",{{"tag_id":tagId,"tag_option_id":defaultTagOptionId}}); 		json = {"JSONString":{"line_items":{lineItemUpdateMap}}}; 		info json;      		// 		// Update Invoice 		updateInvoice = invokeurl 		[ 			url :"https://books.zoho.com/api/v3/invoices/" + INVOICE_ID + "?organization_id=" + ORG_ID 			type :PUT 			parameters:json 			connection:"zoho_books" 		]; 		info updateInvoice; 	} } 				 			

Click here to copy these scripts. For more Zoho-wizardry, check out our GitHub page.

More Free Resources

Deluge Tips – Null Check

When scripting, ask yourself this question – will this value ever be null? If it’s a yes, that’s a place for a null check! Here are 3 tips and best practices to help you kickstart the habit....

Read More »