# Scripts - How to create & add
Similarly to how we change the look and feel of applications using .js and .css scripts, in order to add business logic to applications, we use groovy (opens new window) scripts which will take actions and make changes depending on how we define them using action packs (opens new window) and various different methods to communicate with RecordM.
# Part 1 - Obtaining and updating fields in RecordM
To address these requests, two Groovy scripts were developed, and we'll utilize the code to illustrate and elucidate the process of integrating your own business logic into your server.
To begin, let's examine the code that addresses the date 'problem,' which, as previously mentioned, automatically populates the 'End Date' field of a contract based on the 'Start Date' and 'Duration' fields once they have been filled in. The code is as follows:
// 1. obtrain "start date" and "duration" fields of contract
// 2. add duration to start date to obtain the final date
if (msg.product == "recordm" && msg.action =~ "add|update" && msg.type == "Contracts") {
// get start date of contract and add the duration
// in order to automatically obtain the end date
def endDate = Calendar.getInstance()
endDate.setTime(new Date(msg.value("Start Date", Long.class)))
endDate.add(Calendar.Month, msg.value("Duration", Integer.class))
endDate.toZonedDateTime()
def updates = ["End Date": "${endDate.getTimeinMillis()}"]
recordm.update(message.type, msg.id, updates)
}
As observed in the first line of the code,
if (msg.product == "recordm" && msg.action =~ "add|update" && msg.type == "Contracts")
we specify that we anticipate a message from RecordM and thar the message is either 'add' or 'update'. This ensures that the end date field is populated not only upon the creation of a new contract but also when the start date or duration of an existing contract is updated. Lastly, the msg.type == "Contracts"
condition instructs the system to filter messages exclusively from the creation or updating of a Contract, disregarding any other cases."
Next up, we have this block of code:
def endDate = Calendar.getInstance()
endDate.setTime(new Date(msg.value("Start Date", Long.class)))
endDate.add(Calendar.Month, msg.value("Duration", Integer.class))
endDate.toZonedDateTime()
This section of the code retrieves the Start Date
from the RecordM instance using msg.value("Data Início", Long.class)
, converting it into an instance of the Calendar class. This enables us to add the specified number of months (duration of the contract) to the date. As a result, endDate
will hold the contract's end date.
TIP
Dates in RecordM are stored as epoch time, and the type defined Long.class
used here is necessary in order to manipulate date and time variables.
The following block of code shows how we can now update the RecordM instance:
def updates = ["End Date": "${endDate.getTimeinMillis()}"]
Initially, we construct a map where the key corresponds to the name of the field we intend to modify or update in the RecordM instance, and the value indicates the desired update for that field. Here, we're updating the "End Date," which denotes the contract's end date, with the value represented in milliseconds, signifying the epoch time of the contract's end date.
WARNING
The update map sent to RecordM must have its values represented as strings.
Once we have the updates map ready with all the information we intend to add to the RecordM system, we can then define a variable named result, which will store the result of updating the value, as follows:
recordm.update(message.type, msg.id, updates)
Here we use the RecordM update (opens new window) function, along with the "update" map we defined previously, in order to "push" the updated information into the RecordM instance, which will automatically fill the End Dat
field.
# Part 2 - Querying RecordM and sending emails
The second example script we'll examine serves a similar purpose. However, this script is designed to send email notifications to specific users of the solution when a particular event occurs in the RecordM instance. In this scenario, we aim to automatically dispatch an email to the responsible person for a "contract" if it is nearing expiration. These emails should be sent on the first day of every month and should include details about the expiring contracts, along with additional pertinent information for each one.
To begin, we examine the msg.product, msg.action, and msg.type fields, just as in the previous script, to identify the message related to the update we are targeting. This notification will be implemented using a cron job to trigger the checking script, as follows:
if (msg.product == "cron" && msg.type == "contract-management"){
if (msg.action == "evaluate-expiring") {
notfyExpiringContracts()
}
}
In this case, we do not want to change a field in recordM, but we want to notify the users that a field has changed. To do this, we are going to have to build the html of an email, starting with an introduction and then adding in the info of the relevant scripts.
def notfyExpiringContracts() {
def query = "state:active (end_date.date:<now+3m OR contract_limit_renew:<now+3M)"
def contractsPerManager = getContractManagers(query)
contractsPerManager.each { manager, contracts ->
// For each iteration, the manager is the same for all the provided contracts and there is at least one contract
def managerName = contratos[0].value("Manager Name")
def managerEmail = contratos[0].value("Manager Email")
def mailSubject = ""
def mailBody = """
<html>
<body>
<p>Hi ${managerName},</p>
<br>
<br>
<p>The following active contracts will be expiring in the next 3 months:</p>
<br>
${buildHtmlTable(contracts)}
<br>
<br>
</body>
</html>
"""
email.send(mailSubject, mailBody, [to: [managerEmail] ])
}
}
Starting with the first two lines, we are searching for all the contracts ending in the next 3 months or that need to be renewed in the next 3 months, and then filtering by each person responsible for the contracts. This way we are only sending the expiring contracts to the correct people.
def query = "state:active (end_date.date:<now+3m OR contract_limit_renew:<now+3M)"
def contracts_per_manager = getContractManagers(query)
The remaining code utilizes the retrieved contract data to construct a table containing the pertinent information. The final result would resemble the following:
Description | Anual value | Ending Date | Renew Limit Date |
---|---|---|---|
Contract A | 3€ | 2023-10-25 | |
Contract B | 2€ | 2023-11-10 |
The actual code that sends the email is found on the final line:
email.send(mailSubject, mailBody, [to: [managerEmail] ])
What this does is use the EmailActionPack (opens new window) to send the actual email, using the provided data formatted into a table. It sends an email for each manager with at least one expiring contract, on the first day of every month as defined using the cron job.