TABLE OF CONTENTS


Using functions


You can use functions in various places in Senta: 


In placeholders -- useful for formatting placeholders in special ways, e.g. by formatting text.

In date offsets -- handy for choosing dates in more complex ways, e.g. the earliest of two dates.

In filters -- ensure that tasks/fields only show for clients who fulfil certain criteria e.g. who don't have a certain service turned on


To test any function in Senta, you can use the expression tester.


Any of the described functions must be enclosed within curly braces { } when used within a placeholder.



AND


This function allows you to add extra conditions to an IF function, if you want more than one criteria to be fulfilled.


IF( AND(client.fees > 1000, client.grade = "A"), "Yay", "Boo")


BETWEEN


Returns true or false if value >= lowerbound and value <= upperbound


BETWEEN (value, lowerbound, upperbound)


BETWEEN (client.turnover, 50000, 100000) would return "TRUE" if the client turnover is between 50,000 and 100,000


CHOOSE


Allows you to pick from a selection of options using a number to denote the option you want


CHOOSE (1, "Field 1", "Field 2", "Field 3") would return Field 1


Can be combined with RANDBETWEEN function to randomly choose between two options


CHOOSE( RANDBETWEEN( 1, 2 ), "Option A", "Option B" )


Randomly select a user:

CHOOSE( RANDBETWEEN( 1, 4 ), "u12345", "u0876234", "u567891", "u0987121" )



CONCAT


Combines multiple field references or specified text into a single string


CONCAT ("+44","7707123456") would return +447707123456 


CONTAINS


Allows you to insert set text if a specific term is used within a field.


IF (CONTAINS(client.software, "Xero"), "We will access Xero to retrieve your accounting records.","Please upload your records to the client portal as soon as possible.")


DATEFORMAT


This function can be used to format dates to display in a specific way.


E.g. Payment is due {DATEFORMAT(job.paymentdate, "DD/MM/YYYY")}


This function replaces the existing date formatting option for placeholders, as DATEFORMAT can be combined with other functions.


E.g.  {IF(job.paymentdate, "{DATEFORMAT(job.paymentdate,"DD/MM/YYYY")}", "n/a")}


would display the Job payment date in the format DD/MM/YYYY if there is a date present, otherwise "n/a" would be displayed.


The date formatting needs to be in quotes when used with the DATEFORMAT function.


DATEDIF


You can use this function to calculate days remaining until a certain date, or a number of days between 2 dates:  


{DATEDIF(client.date1,client.date2)}

{DATEDIF(today(),client.date1)}

{DATEDIF(client.date1,job.date)}


The DATEDIF function can also be used to calculate the number of days between a date field and today's date:


DATEDIF(client.date,TODAY())


The above function can be used to calculate the number of days between the 2 dates and populate a number field automatically. As an example, you might record an important date within the client details form. Naturally, a date field would be used to record this date. 


Alternatively you may wish to calculate


Let's assume that this field, has the field reference of importantdate:



In this case, and in order to record the number of days between the date inputted and today's date, you will need to:


1. Create a new number field to record this information, since the days difference will need to be displayed in a number format.



2. When you are setting up the number field, ensure that you select Yes as an the option of whether this field is readonly



You can use this within an IF function, to check for whether either of the date sources exists or not:


{IF(AND(client.date1,client.date2),DATEDIF(client.date1,client.date2))}


You can choose whether specific text will appear in an email if it is sent within 7 days of a tax deadline:


{IF(DATEDIF(today(),job.duedate)<7, "Remember to submit your tax return soon!.")}


You can calculate a client's age using DATEDIF:


DATEDIF(client.contact1.dateofbirth, TODAY, "y")


DATEOFFSET


This function allows you to dynamically set a date offset in placeholders or use one in another expression, such as a filter.


To use this function in a placeholder;


DATEOFFSET( job.filingdate, "-2d" )

eg.  Please ensure this is submitted by {DATEOFFSET( job.filingdate, "-2d" )}


This can be combined with the existing DATEFORMAT() function to format dates.

eg. Make sure you return the letter by {DATEFORMAT( DATEOFFSET( job.filingdate, "-2d"), "DDD MMM YYYY" )}


You can use this function within other expressions also.

eg, IF( DATEOFFSET( job.date, "-2d" ) > DATEOFFSET( job.filingdate, "+3d" ))



DAY


Gets the day as a number 


DAY(job.date) will return '25' if the job date is the 25th. 


Can be used with = as a filter expression 


E.g. DAY(job.date)=25 will only meet criteria if job date is 25th of the month.



DEFAULT


The “DEFAULT” function is used so that calculations have a default value of zero if there’s no value in either field If you don't use DEFAULT, the calculation will fail. Essentially, a default field can be used for the expression to still “work” even if those values are missing.


For example, You might record the salary of an individual client in a money field within the client details form, plus any additional income in a separate field:



If you wish to bring the sum of those 2 figures together in order to populate an email you can use the following function:

{DEFAULT( client.salary, 0 ) + DEFAULT( client.moreincome, 0 )}


The function in the example above would populate an email with the following figure:



>



Taking the above as an example, you can perform additional basic arithmetic operations by following the same principle:


Subtraction:


{DEFAULT( client.salary, 0 ) - DEFAULT( client.moreincome, 0 )}  


Multiplication:


{DEFAULT( client.salary, 0 ) * DEFAULT( client.moreincome, 0 )}  


Division:


{DEFAULT( client.salary, 0 ) / DEFAULT( client.moreincome, 0 )} =



Please note that in the example above, {client.salary} and {client.moreincome} refers to the field references associated with the Salary and Additional income fields.


EARLIEST


Picks the earliest of two dates.  The two dates can be field references or date offsets.


EARLIEST (date1, date2)


EARLIEST (job.previous_task_completion, duedate-30d)


EMBEDDED PLACEHOLDERS


You can use placeholders in the format {client.title} within other placeholders.


IF (client.language = "French", "Je vous écris au sujet de votre entreprise {client.title}", "I am writing to you regarding your company {client.title}")


FIXED


Shows a number with comma-separated thousands and a fixed number of decimal places


FIXED (number, places)


FIXED (1000, 2) would show 1,000.00


It is important in any number fields in Senta to not include a comma e.g. £1234.56 rather than £1,234.56.


IF


Lets you put in different text, dates, numbers, etc. based on a condition.


IF (condition, value1, value2)


IF (client.taxnumber <> "", "We have your tax number on file.", "We do not have your tax number on file yet.")

IF (client.priority = 1, +3d, +2w)


The IF function supports the following operators: 


= equals

<> does not equal

!= (this is the same as the <> above)

< is less than

> is greater than

<= is less than or equal to

>= is greater than or equal to


Using IF functions with yes/no fields and tasks


You can also use an IF function to populate an email based on a yes/no field or task. This means that you can have a different value inserted into an email depending on whether yes or no has been selected. 


For example, if you have a yes/no field in your practice where you record whether your clients are based in the UK or not, you can use an IF function to send a custom email to your clients, based on whether they live in the UK or not.


The screenshot below, illustrates a YES/NO radio field with the option to choose whether the clients are based in the UK or not:



>


The standard format of an IF function based on a yes/no field answer is the following:


IF (client.fieldreference, "option1", "option2")


To break this down further:


client.fieldreference = the field reference used in the yes/no field (for example client.clientbase)

option1 = text that will be inserted based on a yes answer

option2 = text that will be inserted based on a no answer


For example if you are recording whether your clients are based in the UK or not, you could use the following IF function to populate an e-mail. In this case we use client.clientbase as our field reference:


IF (client.clientbase, "UK resident", "non-UK resident")


All of our _______________ clients are required to...


If the answer is yes, the e-mail will populate as:


All of our UK resident clients are required to...


If no is the answer, the e-mail will populate as:


All of our non-UK resident clients are required to...


Using IF functions in date offsets


The IF function can also be used within date offsets, so that the start or due date offset for a task can vary based on client data. For example:


IF(client.clienttype = "Individual", job.paymentdate-7d, job.paymentdate-3d)


Using the function above, if the client type is "individual" then the date offset will be "job.paymentdate-7d", and if the client type is not "individual" the date offset will be "job.paymentdate-3d".



IF/ELSE


You can now use the function {if}...{else}...{endif} which allows you to have two different options for text in your emails, for example:


{IF (client.clienttype = "Individual")} 

Your self assessment tax return is due...


{ELSE} 


Your corporation tax return is due...


{ENDIF}


LATEST


Picks the latest of two dates.  The two dates can be field references or date offsets.


LATEST (date1, date2)


LATEST (job.previous_task_completion, duedate-30d)


LEFT


Reduces text to a set number of characters: 


LEFT (s, n)


s = the original string of text


n = the number of places to reduce it to



So for example, if we were composing an email or letter, and we wanted to just pull the first name of a contact, we could create a placeholder like this:


If the contact's name were 'Dianne'


{LEFT (client.contact1.firstname, 1)}


would output: 'D'


LEN


Allows you to determine the number of characters within a value


LEN(client.name) would return 5 if the client name was "Senta"


This can also be used to confirm if a field such as UTR is the correct amount of characters


LEN(client.utr)=10 would return True if it is 10 digits, and false if not. 


LOWER


Changes text to lower case.


LOWER (text)


LOWER ("ACCOUNTS") would show "accounts"


MAX


Returns the maximum of 2 or more values


MAX (client.q1turnover, client.q2turnover, client.q3turnover, client.q4turnover) would return the highest turnover value across 4 quarters


MIN


Returns the minimum of 2 or more values


MIN (n1, n2, ...)


MIN (client.q1turnover, client.q2turnover, client.q3turnover, client.q4turnover) would return the lowest turnover value across 4 quarters


MOD

Returns the modulus (remainder) when dividing two numbers.  


MOD(dividend, divisor)


e.g. MOD(7, 3) would return 1; MOD(9,3) would return 0.


This can be used combined with the MONTH function in the expression filter to customise jobs based on set months. 


e.g. MOD( MONTH( job.date ), 3 )=1 would return correctly if the month of the job date is January/April/July/October 


To break that down a little more -


MONTH( job.date ) would return 1 in January, 4 in April, 7 in July, 10 in October

MOD(4,3) would return 1 

MOD( MONTH( job.date ),3)=1 will only be correct through an expression filter if the job month number is 1,4,7 or 10


Examples for each quarter period 


MOD( MONTH( job.date ), 3 )=1    -  January, April, July, October


MOD( MONTH( job.date ), 3 )=2    -  February, May, August, November


MOD( MONTH( job.date ), 3 )=0    -  March, June, September, December


MONTH

Used with date placeholders to find the month.


e.g. MONTH(job.date) would return the month number of the job date, such as 3 for March.


NOT


Used in filters if some criteria have not been fulfilled.


In the example below, you could add this function to the expression filter, so that a task will only run if a specific service is not turned on.


NOT(services.sXXXXXXXX)


You can find the service name by looking in the url for the service template.



You could also use this filter so that a job only kicks off if someone is not a former client.


NOT(client.clientstate = "Former client")


The operator "<>" can be used as an alternative to NOT(). This operator means does not equal. For example:


IF (client.taxnumber <> "", "We have your tax number on file.", "We do not have your tax number on file yet.")



OR


This function allows you to add extra conditions to an IF function, if you want one of several criteria to be fulfilled.


IF ( OR(client.software = "Xero", client.software = "QBO"))


RAND, RANDBETWEEN, CHOOSE


Useful for generating random numbers, for example these can be used to randomly assign clients to an account manager.


RAND() gives you a random number greater than or equal to 0 and less than but not equal to 1.


RANDBETWEEN() gives you a random integer between your two values, inclusive, i.e. greater than or equal to the first number, and less than or equal to the second number


Randomly choose between 2 options:

CHOOSE( RANDBETWEEN( 1, 2 ), "Option A", "Option B" )


Randomly select a user:

CHOOSE( RANDBETWEEN( 1, 4 ), "u12345", "u0876234", "u567891", "u0987121" )


REMOVESPACES


You can remove spaces from the field in a placeholder with the function:  REMOVESPACES()


ROUND


Rounds a number with decimal places to the nearest whole number


ROUND(1.467) would return 1


ROUND(1.931) would return 2


SUBSTITUTE


You can use this function to remove spaces of other characters or to replace some characters


E.g. SUBSTITUTE (client.vatnumber, " ", "")


SUM


Returns the sum of 2 or more values, but also allows for missing values


SUM (n1, n2, ...)

SUM (client.q1turnover, client.q2turnover, client.q3turnover, client.q4turnover) would return the sum of the 4 fields, even in the q4 turnover had nor been entered yet


TODAY


Finds todays date as a placeholder, but can be combined with DATEFORMAT 


DATEFORMAT(TODAY, "DD MM YYYY") would show that days date in the format 01 01 2021 

 

DATEFORMAT(TODAY, "DD MMM YY") would show that days date in the format 01 Jan 21


TRIM


Removes excess spaces from text.


TRIM (text)


TRIM("Hello    ") would not show the spaces after Hello.


UKPAYESUFFIX


Can be used within UK based PAYE payroll jobs. 


When making payments to HMRC, the reference number will consist of an account reference number in the format 123AB12345678, and an additional four digits at the end to identify the period, two for the tax year end (eg tax year ending April 22 this would be 22) and two for the month of the tax year (so April is 01, May 02 etc)

The placeholder {ukpayesuffix(job.date,job.period)} would calculate these based on the job date.


{ukpayesuffix(job.date,job.period)} would show 0522 if the job was for payroll in August 2021


{client.payereference}{ukpayesuffix(job.date,job.period)} would show 123AB123456780522 for a payroll August 2021


UPPER


Changes text to upper case.


UPPER (text)


UPPER ("payroll") would show "PAYROLL"



YEAR


Will pull the year in 2 digit number form


YEAR(job.date) will show "21" if the job is in 2021. 


Can be used with = as an expression filter


E.g. YEAR(job.date)=21 will only meet criteria if job date is in the year 2021


Additional function options:


Test for secondary contacts in placeholders


You can now test for whether a secondary contact exists before pulling their information into a placeholder, using the IF function:


{IF (client.contact2, "Contact 2 exists", "Contact 2 does not exist")}


Also:


Dear {client.contact1.firstname} {IF(client.contact2)} and {client.contact2.firstname} {ENDIF} {IF(client.contact3)} and {client.contact3.firstname}{ENDIF}


Calculated fields


Form fields can now be calculated using an expression via the readonly option on a field:



To learn more about Calculated fields, please see our guide: Calculated fields



Service scope in placeholders


A new scope for clients to use in placeholders to do things if services are selected. 


For example:


{IF (services.s12345678, "You are on our Tax Return service", "You are currently not on our Tax Return service")}


You can find the service name by looking in the url for the service template.



Lists of services


To pull a list of services offered to a client into an email, use the following formatting:


{each(service)}

- {service.title}

{service.sales | optional}

{service.terms | optional}

{if(service.fees.setup)} £{service.fees.setup} setup {endif}

{if(service.fees.monthly)} £{service.fees.monthly} each month {endif}

{if(service.fees.annual)} £{service.fees.annual} per year {endif}

{endeach}


{service.sales} refers to the "sales description" field on any service

{service.terms} refers to the "sales terms" field on any service

{services.fees.setup} refers to the "setup fee" field on any service

{services.fees.monthly} refers to the "monthly fee" field on any service

{services.fees.annual} refers to the "annual fee" field on any service


These fields are not available with the template version of Senta, but can be turned on for you if needed. Please contact us at support@senta.co


| optional} means that Senta will only try to pull through data from a field if it contains any information


The "each" function means that Senta will look for the title, sales and terms for each service, and pull that information into an email. For example, if I select VAT and payroll for a client, the following information will display:


- Payroll service

Example sales description

Examples sales terms

£100 setup

£500 each month


- VAT service

Example sales description

Example sales terms

£100 setup

£2000 per year



Using Expressions in filters


Another useful way to use Expressions is to create filters for tasks and fields in the Client List. There may be a specific way you want to filter tasks that can’t be achieved using the usual filters and dependencies. In the example job, the email task is designed to confirm in the client’s chosen language that they have signed up to the newsletter. 


Please note expressions filters don't need the outer { } the way expressions do elsewhere.

 

We’ve set up a text entry form with a tooltip to guide what choices can be entered (helpful for setting up the filters), and given the form result a field reference, ‘marklang.’ The field reference will be used to further personalise the email.

 

 

I’ve set up a job to capture this information then generate an email based on their choice. There are three language choices so I have set up three email tasks:

 

 

In each task, we want to place an expression to tell the task whether to kick off or not. The basic expression we will use is

job.marklang = "[answer]"

 

To set an expression filter, expand the task and go to the Filter tab. Click Add filter, scroll down to the bottom and expand Advanced to access the Expression filter:

 

 

For the English email, you want to add the expression as follows:

job.marklang = "English"

 

 

The final step is to put the placeholder into the email itself. In the Email tab of the task, I have entered my text. I can add a placeholder to populate the correct language into the email, in this case 


{job.marklang}

 

 

I then repeated this process for the other 2 email tasks and now we are ready to test. I ran the job ad-hoc for a client and filled in the form, entering “English”:


 

You can see that only the English email task has been created:


 

Click Send the email and you can see that the correct language has been filled in:



IF/OR functions in expression filters


Another example you can use is an IF/OR function, to tell a task to generate if one of multiple parameters is met (as opposed to using filters, which require all parameters to be met).


With the email task below, I want it to be filtered into a job for clients who are either Prospects or Former clients. To do this, I will use an OR function - remembering that you do not need the brackets { } around expression filters.



OR(client.clientstate = "Former client", client.clientstate = "Prospect")


When I run this job for a client that is a Prospect:



You can see that the email task is filtered into the job:



This can be used to create some very useful, flexible ways of filtering tasks without having to duplicate them to take into account client differences.