Sample Extension

Let’s see how to build an extension for Zoho Books from scratch. In this help document, we’ll explain the steps involved in building the Salesperson extension as a sample extension to learn this better. First, let’s understand why Salesperson extension is required.

In Zoho Books, it is currently not possible to track salespersons within an organization. Using the Salesperson extension, admins of an organization can keep track of the salespersons and their activities, and assign commissions to them each time a customer associated with them pays for an invoice.

Now that you’ve understood the need for the Salesperson extension let’s start building the extension. The steps involved in building this extension are:

  1. Creating an extension
  2. Custom module for salespersons
  3. Connection for extension
  4. Custom function to calculate the salesperson’s commission
  5. Workflow rule for custom function
  6. Salesperson Name custom field in the Expenses module
  7. Global field to store salesperson’s data
  8. Settings widget for the extension
  9. Syncing new salesperson with the Salesperson module
  10. Syncing existing salespersons during extension installation

Creating an Extension

The first step is to create an extension. To do this:

Click 'New Extension' Enter the extension details and click 'Create'

With this, you have created the Salesperson extension. The next step is to add the necessary components for the extension. To do this:

Click 'Edit Extension'

Custom Module for Salespersons

You need a module to keep track of all the Salespersons in your organization. You can use the Custom Modules feature to create a module for Salesperson. Here’s how:

You’ll have to create the additional fields for the Salesperson module. Here’s how you can do this:

Refer to the image below to view the additional fields that you’ll have to create and their details.

Details of other fields required for the custom module

Note

  • For the Salesperson Account field, select Accounts as the Module that has to be looked up.
  • For the Salesperson Commission Type field, enter Percentage and Amount as the dropdown options.

Connection for the Extension

You have to create a connection so that the extension has the permissions required to fetch the data necessary from Zoho Books. To create a connection:

Custom Function to Calculate the Salesperson’s Commission

You have to create a custom function that automatically calculates the salesperson’s commission when the salesperson creates an invoice. Also, the custom function will automatically create an expense for the saleseprson’s commission once the invoice’s status is Paid. This will help you keep track of the commissions you owe to each salesperson in your organization.

To create the custom function:

Workflow Rule for the Custom Function

For the custom function to automatically calculate the salesperson’s commission once they create an invoice, you have to create a workflow rule that gets triggered automatically once an invoice is created or edited. You can associate the custom function with the workflow rule.

To create the custom function:

Add the required filters

Salesperson Name Custom Field in the Expenses Module

In Zoho Books, the Salesperson field is available in the sales modules such as Quotes, Sales Orders, and Invoices. You have to create the Salesperson field in the Expenses module to keep track of the Salesperson for whom the expense is created. To do this, you can use the Custom Fields feature in Zoho Books. Here’s how:

Global Field to Store the Salesperson’s Data

You have to create a global field to store the salesperson’s data. Here’s how you can do this:

Settings Widget for the Salesperson Extension

You need to create a settings widget for the Salesperson extension. The widget will contain the UI components required for the initial configuration of the Salesperson extension. You can create the settings widget using any framework of your choice. In this extension, we’ve used the Vue, React, and Vanilla JS.

After you create the widget, you need to pack it and upload it into the global field.

Sync New Salesperson With the Salesperson Module

Whenever you create a new salesperson, you’ll have to add them to the Salespersons module. This can be a time-consuming process. Instead, you can create a custom button in the Salesperson module. On clicking the custom button, the newly added salesperson will be automatically synced with the Salesperson module. Here’s how you can do this:

Sync Existing Salespersons During Extension Installation

Before an organization installs the Salesperson extension, they might already have created salespersons. Using the On Installation component, you can sync these salespersons to the Salesperson module, when the organization installs your extensions. Here’s how:

organizationID = organization.get("organization_id");
domainUrl = organization.get("api_root_endpoint");
customModuleApiName = "cm__u76nt_salesperson";
cmNameApiName = "cf__u76nt_salesperson_name";
cmEmailApiName = "cf__u76nt_salesperson_e_mail";
cmAccountApiName = "cf__u76nt_salesperson_account";
cmTypeApiName = "cf__u76nt_salesperson_commission_type";
cmRateApiName = "cf__u76nt_salesperson_commission_rate";
cmStatusApiName = "cf__u76nt_salesperson_status";
globalFieldApiName = "vl__u76nt_data_store";
dataStore = global_fields.get(globalFieldApiName).get("value");
user_given_commission = dataStore.get("commission");
user_given_expense_id = dataStore.get("expense_account").get("id");
user_given_commission_type = dataStore.get("type");
connection_link_name = "salesperson_commission_books";
// GET total page count of Custom Module .
total_page = invokeurl
[
	url :domainUrl + "/" + customModuleApiName + "?page=1&per_page=200&response_option=2&organization_id=" + organizationID
	type :GET
	connection:"salesperson_commission_books"
];
total_page = total_page.get("page_context").get("total_pages");
// total page count make as loop 
loop = rightpad(",",total_page).toList("");
// Get Salesperson Details
salesperson_response = invokeurl
[
	url :domainUrl + "/salespersons?organization_id=" + organizationID
	type :GET
	connection:"salesperson_commission_books"
];
data = salesperson_response.get("data");
for each  record in data
{
	is_present = 0;
	salesperson_name = record.get("salesperson_name");
	salesperson_email = record.get("salesperson_email");
	salesperson_status = record.get("is_active");
	if(salesperson_status == false)
	{
		salesperson_status = "Inactive";
	}
	else
	{
		salesperson_status = "Active";
	}
	body = {"JSONString":{cmNameApiName:salesperson_name,cmTypeApiName:user_given_commission_type,cmRateApiName:user_given_commission,cmEmailApiName:salesperson_email,cmAccountApiName:user_given_expense_id,cmStatusApiName:salesperson_status}};
	page = 0;
	for each  index in loop
	{
		page = page + 1;
		// Get Custom Module Details 
		customModule_response = invokeurl
		[
			url :(domainUrl + '/') + customModuleApiName + '?page=' + page + '&usestate=false&organization_id=' + organizationID
			type :GET
			connection:"salesperson_commission_books"
		];
		customModule_records = customModule_response.get("module_records");
		for each  records in customModule_records
		{
			if(records.get(cmEmailApiName) == salesperson_email)
			{
				is_present = is_present + 1;
				customModule_id = records.get('module_record_id');
				salesperson_commission_type = records.get(cmTypeApiName);
				salesperson_commission_rate = records.get(cmRateApiName);
				salesperson_expense_id = records.get(cmAccountApiName);
				body = {"JSONString":{cmNameApiName:salesperson_name,cmTypeApiName:user_given_commission_type,cmRateApiName:user_given_commission,cmEmailApiName:salesperson_email,cmAccountApiName:user_given_expense_id,cmStatusApiName:salesperson_status}};
				updatecustomModuleFields = invokeurl
				[
					url :domainUrl + "/" + customModuleApiName + "/" + customModule_id + "?organization_id=" + organizationID
					type :PUT
					parameters:body
					connection:"salesperson_commission_books"
				];
			}
		}
		if(is_present == 0)
		{
			createcustomModuleFields = invokeurl
			[
				url :domainUrl + "/" + customModuleApiName + "?organization_id=" + organizationID
				type :POST
				parameters:body
				connection:"salesperson_commission_books"
			];
			info createcustomModuleFields;
		}
	}
}

With this, you have build all the components necessary for the Salesperson extension. You can test your extension in the Zoho Books Sandbox environment and publish your extension in Zoho Marketplace.


Was this document helpful?
Yes
No
Thank you for your feedback!
Want a feature?
Suggest
Switch to smart accounting software. Switch to Zoho Books.   Start my free 14-day trial Explore Demo Account

Books

Online accounting software
for small businesses.