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.

Configuration

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 »