Custom Function : Automatically send the Quote to the related contact

Custom Function : Automatically send the Quote to the related contact

Scenario: Automatically send the Quote to the related contact. 

We create Quotes for customers regularly and when we want to send the quote to the customer, we have to send it manually.

We can automate this, using Custom Functions. Based on a criteria, you can trigger a workflow rule and the custom function associated to the rule and automatically send the quote to customer through an email.

Please note that the quote will be sent as an inline email content and not as a PDF attachment.

Please follow these steps:

  1. Log in to Zoho CRM with administrative privileges.
  2. Click Setup > Automation > Workflow > Create Rule.
  3. In the New Rule page, choose Quotes module from the drop-down list and provide other rule details.
  4. Under Execute On, choose Create or Edit and then click Next.
  5. Specify the Rule Criteria. The rule will triggered only when a record meets the criteria mentioned here.
  6. In the Actions section, click on the Add button for Call Custom Functions.
  7. In the Configure Custom Function popup, click Write your own.
  8. Specify a name for the function.
  9. Build the Deluge Script based on the code given below.



void workflowspace1.Myfunction(string quoteId)
{
resp = zoho.crm.searchRecordsByPDC("Quotes","quoteid",input.quoteId);
respstr=resp.toString();
respmap=respstr.toMap();
productmap=respmap.get("product");
jlist=productmap.toJSONList();
ContactName=respmap.get("Contact Name");
AccountName=respmap.get(("Account Name"));
Description=ifnull(respmap.get("Description"),"");
AccountID=respmap.get("ACCOUNTID");
ContactID=respmap.get("CONTACTID");
accresp = zoho.crm.searchRecordsByPDC(("Accounts"),("accountid"),AccountID);
accrespstr=accresp.toString();
accrespmap=accrespstr.toMap();
conresp = zoho.crm.searchRecordsByPDC("Contacts","contactid",ContactID);
conrespstr=conresp.toString();
conrespmap=conrespstr.toMap();
Mobile=ifnull(conrespmap.get("Mobile"),"");
Email=ifnull(conrespmap.get("Email"),"");
City=ifnull(accrespmap.get("City"),"");
Street=ifnull(accrespmap.get("Street"),"");
str="<br><br><br><table border='0' cellspacing='0' cellpadding='0' width='100%' style='background:#fff;padding:2px;'><tbody><tr><td><table border='0' cellspacing='0'cellpadding='0' width='100%' style='border-left:1px solid #dadada;border-right:4px solid#dadada;border-top:1px solid #dadada;border-bottom:4px solid #dadada;padding:10px;background-color:white;'><tbody><tr><td valign='top'><div style='font-family:Arial, Helvetica, sans-serif; font-size: 13px;'><span style='font-family: Verdana, arial, Helvetica,sans-serif; font-size: 12px;'>Hello there!&nbsp;</span><div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'>Customer Name: ") + ContactName) + "&nbsp;</div><div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size:12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size:12px;'>Company Name: ") + AccountName) + "&nbsp;</div><div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'>Mobile Number: ") + Mobile) + "&nbsp;</div><divstyle='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=((str + " <div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'>Email Address:") + Email) + "&nbsp;</div><div style='font-family: Verdana, arial, Helvetica, sans-serif;font-size: 12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial, Helvetica, sans-serif;font-size: 12px;'>City:&nbsp;") + City) + "</div><div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'>Address:&nbsp;") + Street) + "</div><div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=((str + "<div style='font-family: Verdana, arial,Helvetica, sans-serif; font-size: 12px;'>Requirements :&nbsp;") + Description) + "</div><div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=str + " <div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'>Kindly allocate the partner for the above case and also update us on the further progress of the above lead.&nbsp;</div>";
str=str + "<div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size:12px;'>Regards, CNX Team</div><div style='font-family: Verdana, arial, Helvetica, sans-serif; font-size: 12px;'><br></div>";
str=str + "<table border='0' cellspacing='0'cellpadding='0' width='100%' style='font-family: Arial, Helvetica,sans-serif;font-size:11px;color:#000;'><thead><tr><td style='font-weight:bold;background-color:#eaeaea;border-top:2px solid gray;'>S.No.</td><td style='font-weight:bold;background-color:#eaeaea;border-top:2px solid gray;'>Product Details</td><td style='font-weight:bold;background-color:#eaeaea;border-top:2px solid gray;'>Qty</td><td align='right' style='font-weight:bold;background-color:#eaeaea;border-top:2px solid gray;'>List Price</td>  <td align='right' style='font-weight:bold;background-color:#eaeaea;border-top:2px solid gray;'>Total</td>  </tr> </thead>";
for each index j in jlist
{
mapvar=jlist.get(j);
finalMap=mapvar.toMap();
pdt=ifnull(finalMap.get("Product Name"),"");
qty=ifnull(finalMap.get("Quantity"),"");
listPrice=ifnull(finalMap.get("List Price"),"");
UnitPrice=ifnull(finalMap.get("Unit Price"),"");
TotalDis=ifnull(finalMap.get(("Total After Discount")),"");
qtyInStock=ifnull(finalMap.get("Quantity in Stock"),"");
Tax=ifnull(finalMap.get("Tax"),"");
netTotal=ifnull(finalMap.get("Net Total"),"");
discount=ifnull(finalMap.get(("Discount")),"");
Total=ifnull(finalMap.get("Total"),"");
str=str + "<tbody><tr><td style='border-bottom:2px dotted #dadada' valign='top'><b>" + (j  +  1) + "<br></b></td>";
str=str + "<td style='border-bottom:2px dotted #dadada'><b>" + pdt + "</b><br></td>";
str=str + "<td style='border-bottom:2px dotted #dadada' valign='top'>" + qty + "</td>";
str=str + "<td style='border-bottom:2px dotted #dadada' align='right' valign='top'>" + listPrice + "</td>";
str=str + "<td style='border-bottom:2px dotted #dadada' align='right' valign='top'>" + Total + "</td>";
str=str + "</tr></tbody>";
}
subtotal=ifnull(respmap.get("Sub Total"),"");
totaltax=ifnull(respmap.get("Tax"),"");
adjustment=ifnull(respmap.get("Adjustment"),"");
Grandtotal=ifnull(respmap.get("Grand Total"),"");
str=str + "<tbody><tr><td colspan='4' align='right'>Sub Total</td>";
str=str + "<td align='right'><b>" + subtotal + "</b></td></tr>";
str=str + "<tr><td colspan='4' align='right'>Tax</td>";
str=str + " <td align='right'>" + totaltax + "</td></tr>";
str=str + "<tr><td colspan='4' align='right'>Adjustment</td>";
str=str + "<td align='right'> " + adjustment + "</td></tr>";
str=str + "<tr><td colspan='4' style='border-bottom:2px solid #ccc' align='right'><b>Grand Total</b></td>";
str=str + "<td style='border-bottom:2px solid #ccc;border-top:2px solid #dadada;' align='right'><b>INR " + Grandtotal + "</b></td></tr></tbody></table><br><br></td></tr></tbody></table></td></tr></tbody></table>";
sendmail
[
from:zoho.adminuserid
to:Email
subject:"Quote Details"
message:str
content type:HTML
]
}

Note: This custom function is for the Quote module and you can modify it to send the automated email from the Sales Order and Invoices also. Also, we have used on the default Quote template model. If you want to change the quote layout, then you need to customize the custom function as per your requirement.

Please refer to the following link to know more about this feature:
    • Sticky Posts

    • Function #46: Auto-Calculate Sales Margin on a Quote

      Welcome back everyone! Last week's function was about displaying the discount amount in words. This week, it's going to be about automatically calculating the sales margin for a particular quote, sales order or an invoice. Business scenario Where there is sales, there's also evaluation and competition between sales reps. A healthy rivalry helps to better motivate your employees to do smart work and close deals faster and more efficiently. But how does a sales rep get evaluated? 90% of the time, it's
    • Zoho CRM Functions 53: Automatically name your Deals during lead conversion.

      Welcome back everyone! Last week's function was about automatically updating the recent Event date in the Accounts module. This week, it's going to be about automatically giving a custom Deal name whenever a lead is converted. Business scenario Deals are the most important records in CRM. After successful prospecting, the sales cycle is followed by deal creation, follow-up, and its subsequent closure. Being a critical function of your sales cycle, it's good to follow certain best practices. One such
    • User Tips: Auto-Create Opportunity/Deal upon Quote Save (PART 1)

      Problem: We use quotes which convert to sales orders but Users / Sales Reps do not create opportunities / deals and go straight to creating a quote. This leads to poor reporting. Implementing this solution improves reporting and makes it easier for users.
    • Custom Function : Automatically send the Quote to the related contact

      Scenario: Automatically send the Quote to the related contact.  We create Quotes for customers regularly and when we want to send the quote to the customer, we have to send it manually. We can automate this, using Custom Functions. Based on a criteria, you can trigger a workflow rule and the custom function associated to the rule and automatically send the quote to customer through an email. Please note that the quote will be sent as an inline email content and not as a PDF attachment. Please follow
    • Function #50: Schedule Calls to records

      Welcome back everyone! Last week's function was about changing ownership of multiple records concurrently. This week, it's going to be about scheduling calls for records in various modules. Business scenario Calls are an integral part of most sales routines.. Sales, Management, Support, all the branches of the business structure would work in cohesion only through calls. You could say they are akin to engine oil, which is required by the engine to make all of it's components function perfectly. CRM
      • Recent Topics

      • Integration with...

        Dear Zoho Commerce team, Please could you consider the integration within Zoho Commerce / Inventory and Qapla'? (https://www.qapla.it/en/) This app is better than Aftership in many ways: - Aftership integration require PRO plan and price start from more
      • Generate leads from instagram

        hello i have question. If connect instagram using zoho social, it is possible to get lead from instagram? example if someone send me direct message or comment on my post and then they generate to lead
      • Adding Markdown text using Zoho Desk API into the Knowledge Base

        Hi Zoho Community members, We currently maintain the documentation of out company in its website. This documentation is written in markdown text format and we would like to add it in Zoho Knowledge Base. Do you know if there is REST API functionality
      • Create case via email

        Good Afternoon, I have just registered and am taking a look around the system. Is it possible to create a case via email.  I.e. an employee/client/supplier emails a certain address and that auto generates the case which then prompts a member of staff
      • Need a Universal Search Option in Zohobooks

        Hello Zoho, Need a Universal Search Option in Zohobooks to search across all transactions in our books of accounts. Please do the needful Thanks
      • Locked Notebook

        Hi, I hadn't used my Notebook in some time and was refamiliarizing myself with it. I clicked a lock icon and now I can't unlock. When I hit the information or unlock icons I'm taken to a page with the notebook icon and a keyboard. When I type, nothing
      • Unable to produce monthly P&L reports for previous years

        My company just migrated to Books this year. We have 5+ years financial data and need to generate a monthly P&L for 2019 and a monthly P&L YTD for 2020. The latter is easy, but I'm VERY surprised to learn that default reports in Zoho Books cannot create
      • Hide fields only for creation

        Hello, I'd like to hide some fields only during the creation of a contact in Zoho CRM. In fact I have some fields that are automatically calculated thanks to an automation, so when my users create a contact I don't want them to fill those fields. I know
      • Issues with Zoho Sheet in Mac

        I have downloaded the Zoho App from App Store but It is failing to Save As, Open & Download Operations. App Store
      • Weekly Sales Summary

        Is it possible to generate a weekly report in Zoho Books to show -$$ amount of estimates generated -# of estimates generated by Salesperson -$$ amount of Sales Orders created -$$ amount of Invoices generated
      • Can I write a check in Zoho Books with no associated bill?

        This currently does not seem possible, and I have a client that desperately needs this function if I am able to convert them with Quickbooks. Thank you in advance for your reply. 
      • OpenAPI Specs are just plain wrong

        The provided yml files for generating the OpenAPI specs are absolutely riddled with errors and inconsistencies. From missing fields on the objects, to just incorrectly named resource objects. I'm having to go through and manually changing the spec to
      • Custom Footer – Zoho Writer Document

        Hello everyone, I’m having an issue adding a custom footer in a Zoho Writer document. I would like to insert my company information (including a logo + address) in the footer. The problem is that when I add these elements, the main content of my pages
      • Report grouping

        I have added a grouping in a report but it is not working how i had expected. I wanted to group a summary on a field named Size but when i add the grouping the report is still showing me each record and making a summary at the bottom of the report. What
      • Social Media Simplified with Zoho Social: Preview your Instagram grid before posting

        For a platform like Instagram that relies on visual appeal, it's important that you plan your image and video content in a way that holds your audience's attention. Planning your grid ahead of time gives you the benefit of understanding how your posts
      • Spreadsheet View click & focus issue in Arabic (RTL) localization

        Hello Zoho Support Team, I am facing an issue in Zoho Creator Spreadsheet View when using Arabic localization (RTL). Scenario: My app supports English (LTR) and Arabic (RTL). I created a Spreadsheet View for a form. In English, everything works correctly.
      • VAT rates - exempt and out of scope

        Good Evening, UK based company here. I am a bit confused in respect of setting up VAT rates for exempt goods and services; at present I am simply leaving the VAT rate blank in the transactions in order to prevent any VAT appearing in the VAT return. When
      • How to loop through Multiple Upload and Display Actual File Name

        I have been reading the help on the File Upload Control and reviewed the Deluge help on files and I can not figure out how to loop through the uploaded files and do anything but get the automatically created file names. The code below will run but each
      • abou arattai

        I want to use the Arattai app for business purposes, so please convert my account to a business account.I have my own invoice app, and I want to link it with the Arattai app for direct messaging.
      • Configurable Zoho Cliq Notifications for Zoho People Alerts

        Hello Zoho People Product Team, Greetings and hope you are doing well. We would like to request an enhancement to Zoho People notifications, enabling a native delivery via Zoho Cliq with admin-level control, similar to the notification settings available
      • Overlapping Reports in Dashboards

        It's rare, but occasionally it would be a good feature if I were able to overlap reports, either fully or partially in the Dashboards. Also, then having the ability to move objects to the front or rear, or make them transparent/translucent would be good
      • Looking back at Zoho Calendar in 2025

        Hello Zoho Calendar Community, As we step into a brand-new year, we’d like to take a moment to thank you for being an active and valued part of the Zoho Calendar community. Your trust, feedback, and continued engagement motivate us to keep evolving and
      • There was an error while connecting to GSTN

        I am trying to file GSTR1. Everything flows smoothly until I reach the final step of filing the return. After I enter the PAN and OTP for filing it raises the error "There was an error while connecting to GSTN"
      • Zoho Books Extension: What Happens If Custom Fields Already Exist?

        When developing Zoho Books extensions, what happens if the target Zoho Books organization already has a custom field with the same API name as one defined in the extension? I’m asking because we originally created an on-Books version of this functionality,
      • Internal Server Error (500) When Attempting to View Banking Transactions

        I am experiencing an Internal Server Error (500) when attempting to view transactions across all of my banking accounts. Despite multiple attempts to resolve this, I have received little more than runaround from support, and the issue remains unresolved.
      • How do I add a blank line to the Organisation Address Format?

        I'd like to have my VAT number, for example, shown prominently by having a clear gap between it and the address block above, but any blank lines in the address format get ignored in PDF outputs.
      • Automatic Invoice Number generation for createRecord

        Hello, while testing some custom Buttons in my Zoho Books application, I noticed that I get an error that previously did not occur. After some further digging I found that the automatic transaction numbering of invoices no longer work in my organization.
      • Adding number of days to an estimate.

        I need both QTY of item and "number of days hire" in my estimates at the line item level. Any clues as to how this is done would be greatly appreciated. It needs to calculate. Thanks J
      • Books Api: listing expenses created after certain dates

        Is there any parameter I can add to the List Expenses endpoint that will let me look up expenses by when they were created?
      • Why can't we change the Account type from an Expense to an Asset?

        Like the question. Why in QuickBooks for example if I mistakenly created an account as an expenses and I already captured information in those accounts, I can just change the account type from expense to asset
      • Is it possible to do validation for the Actions added to Reports?

        We have an all-around On Validate function that checks all the possibilities before the Created/Edited form submissions. We want to have a button in the report view, so we can change records without entering. We are able to add this button, and it does
      • Ability to Edit Ticket Subject when Splitting a Ticket

        Often someone will make an additional or new request within an existing ticket that requires we split the ticket. The annoying part is that the new ticket maintains the subject of the original ticket after the split so when the new ticket email notification
      • [Free Webinar] Environments in Zoho Creator - Creator Tech Connect

        Hello Everyone, We’re delighted to kick off the 2026 edition of the Zoho Creator Tech Connect Series and are excited to continue this learning journey with you. The Creator Tech Connect series is a free monthly webinar featuring deep-dive technical sessions
      • Zoho Voice API SMS

        I made a post request in Zapier to try to send an SMS. Authentication appears to be configured correctly. I followed the documentation and I'm getting a 400 Error "Internal Server Error". Not helpful at all. Anyways, I could not find any information on
      • How do I change (error) display messages

        Hi! I would like to edit display messages like "invalid entries" and "enter a value for Nome" and so on into Italian language messages. How can I do that? Already tried on Validate on form submit. Where I am failing? Thanks in advance.
      • Record Overseas Transactions Along with CC charges

        Hi All, We receive payments via stripe in multiple currencies and stripe takes around 2.5% fees. The amount is settled in INR into our local bank. What should be the currency of the income account used for Stripe payments? Here is a sample flow that we
      • Easier onboarding for new users with stage descriptions

        Greetings, I hope all of you are doing well. We're happy to announce a recent enhancement we've made to Bigin. You can now add descriptions to the stages in your pipeline. Previously, when creating a pipeline, you could only add stages. With this update,
      • Pieds de page personnalisé - Document Zoho Writer

        Bonjour à tous, Je rencontre un souci avec l’ajout d’un pied de page personnalisé dans un document Zoho Writer. Je souhaite insérer les informations de mon entreprise (notamment un logo + adresse) dans le pied de page. Le problème, c’est que lorsque j’ajoute
      • Permissions on Views

        Having the option of any agent creating custom views is firing back and got a situation where there are a hundred different views across the team and tickets are not being dealt in the most efficient of ways. Tickets seems to be missed by some agents,
      • Credit card transactions are backwards after importing statements

        I am new to Zoho Books so I'm importing my firm's bank and credit card statements in. My credit card statements have a single column with negative numbers so that is the option I chose. But when I went to categorize the credit card transactions, I can
      • Next Page