The main idea here is, at some defined trigger in the CRM, to automatically create an invoice for a specific Contact and send it to them via email.
The trigger needs to be set up via a workflow rule or blueprint transition, i.e. when a “Deal” is marked ‘Closed’. The defined argument in this function is the Contact_ID, but you can query that from whichever module you start the function. Below, I talk more about options for adding line items.
You will have to create the connection between CRM and the Finance Suite. In CRM, go to Setup >> Developer Space >> Connections to create and name the connection.
The first few lines define variables needed in the rest of the function, pulling information from the (CRM) Contact record and using the Zoho Books Organizations API to get the Organization ID. This field is frequently used with Deluge commands in the Zoho Finance Suite. Zoho provided the ability to create and manage multiple organizations in Books, and this specific ID is used in most Deluge commands in Books.
A quick search checks the Customers (but the API name is “contacts”) module for the contact’s email. If it is empty, we go ahead and create the Customer, and if not, we just pull the Contact Person information for the Invoice. This comprises lines 24-56.
Next, we create maps for the new invoice and add the payment options to that. Here, there are many ways to customize this function further. Some ideas are to create a sync between Books-CRM and the Items and Products module. Then, you can choose the products in CRM and via a query to the Items module (in Books), add those line items to the Invoice. You can simply leave it as it is and specify a single item if needed (as is done here). You can also customize the payment options. A useful resource is the Zoho Books API Doc, specifically the zoho.books.createRecord
command. Then, to better learn how to add custom fields, refer to our “Zoho Books Custom Fields” repository.
After the Invoice is created successfully, if(code==0)
, the last API call sends off the email with the created Invoice (also detailed in the Zoho Books API doc).
// Start by defining all the variables that you will need throughout the function, pulled from the CRM Contact record. Then call the Zoho Books Organizations API. You will have to do some sort of search based off name or something else if you have more than one organization. contactRecord = zoho.crm.getRecordById("Contacts",CONTACT_ID); info contactRecord; email = contactRecord.get("Email"); firstName = contactRecord.get("First_Name"); lastName = contactRecord.get("Last_Name"); otherInfo = contactRecord.get("other_custom_field"); //other info as needed getOrganizations = invokeurl [ url :"https://books.zoho.com/api/v3/organizations" type :GET connection:"zohobooks" ]; info getOrganizations; orgId = getOrganizations.get("organizations").get(0).get("organization_id"); info orgId; // Now that we have our defined variables, we search the Contacts module for contacts with a matching email address. It returns a list of contacts (just one) searchParam = {"email":email}; contactSearch = zoho.books.getRecords("Contacts",orgId,searchParam).get("contacts"); contactId = null; contactPersonId = null; // Check If Contact is Found. If (the list) is not empty, we query the primary contact's info to put on the invoice if(!contactSearch.isEmpty()) { // Get Contact Record contact = contactSearch.get(0); contactId = contact.get("contact_id"); contactDetails = zoho.books.getRecordsById("contacts",orgId,contactId).get("contact"); contactPersons = contactDetails.get("contact_persons").toList(); // Find Primary Contact for each contactPerson in contactPersons { if(contactPerson.get("is_primary_contact")) { contactPersonId = contactPerson.get("contact_person_id"); } } } else //(list is empty, create the Contact and Contact person in Books and get the info for the Invoice) { // Create Map for New Contact newContactMap = Map(); newContactMap.put("email",email); newContactMap.put("contact_name",firstName + " " + lastName); newContactMap.put("contact_persons", {{"first_name":firstName,"last_name":lastName,"email":email}} ); // Create New Contact createContact = zoho.books.createRecord("Contacts",orgId,newContactMap); contact = createContact.get("contact"); contactId = contact.get("contact_id"); // Get Contact Person Info contactPerson = contact.get("contact_persons").get(0); contactPersonId = contactPerson.get("contact_person_id"); } // Create New Invoice map and select a specific template if needed invoice = Map(); invoice.put("customer_id",contactId); invoice.put("date",today); invoice.put("template_id","your_templateId"); contactPersonsList = List(); contactPersonsList.add(contactPersonId); invoice.put("contact_persons",contactPersonsList); invoice.put("line_items",{{"item_id":"2062836000120068237","quantity":"1","invoice_custom_field":otherInfo}}); //create a map for custom fields and add them to the invoice customList = List(); customField1 = Map(); customField1.put("label","your_label"); customField1.put("value", ifnull(your_value, "")); customList.add(customField1); // // for second custom field // customField2 = Map(); // customField2.put("label","your_2nd_label"); // customField2.put("value",ifnull(your_2nd_value,"")); // customList.add(customField2); invoice.put("custom_fields", customList); // Set Payment Options - this code enables both Paypal and Stripe, but you can of course customize it paymentOptions = List(); paypalMap = Map(); paypalMap.put("gateway_name","paypal"); paypalMap.put("additional_field1","standard"); stripeMap = Map(); stripeMap.put("gateway_name","stripe"); paymentOptions.add(paypalMap); paymentOptions.add(stripeMap); gatewayMap = Map(); gatewayMap.put("payment_gateways",paymentOptions); invoice.put("payment_options",gatewayMap); // Create Invoice createInvoice = zoho.books.createRecord("invoices",orgId,invoice); info createInvoice; //If the invoice was created successfully, we send the email with the invoice and payment options via a Zoho Books API call code = createInvoice.get("code"); if(code == 0) { emailList = List(); emailList.add(email); invoiceInfo = createInvoice.get("invoice"); invoiceId = invoiceInfo.get("invoice_id"); info invoiceId; json = Map(); json.put("to_mail_ids",emailList); params = Map(); params.put("JSONString",json); emailInvoice = invokeurl [ url :"https://books.zoho.com/api/v3/invoices/" + invoiceId + "/email?organization_id=" + orgId type :POST parameters:params connection:"zohobooks" ]; info emailInvoice.get("message"); }
Click here to copy these scripts. For more Zoho-wizardry, check out our GitHub page.
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....
Learn to create a customized inventory report with Zoho Analytics. This tutorial contains a link to our GitHub page for SQL code that will help with your table creations....
How nice would it be if you could, at the press of a button, send clients an email w/a Zoho Books invoice? Replete with “Pay Now” buttons that link to PayPal/Stripe/other payment gateways?...
Whether you work primarily out of CRM or the Zoho Finance Suite, you can use Analytics to build commissions dashboards. This involves some fairly simple SQL code....
If you are an inventory manager, this blog post could change your life. If you are not, it will at least teach you how to build some wicked inventory tracking for your business....
Convert fields, related activities, attachments, notes and more from one record to another across modules via custom function....