Creating Calculations

Queries

.find

A find query will search the given field and return the first item that satisfied the condition set in the function.

model.sampleDataList.find{it.exampleField == 2}

This will return the entire item, meaning we can access any field on that item. For example,

model.sampleDataList.find{it.exampleField == 2}.title

Will search the Sample Data List for the first item that has an Example Field value of 2. It will then return the Title field for that item.

.findAll

As it’s name implies, a findAll query is very similar to a find query. However, rather than returning only the first item that satisfies the given condition, a findAll query will return all items that satisfy the condition, in a collection.

model.sampleDataList.findAll{it.exampleField == 2}

This will return a collection of items, meaning, once again, we can access any field on each of those items. For example,

model.sampleDataList.findAll{it.exampleField == 2}.otherField

Will search the Sample Data List for all items that have an Example Field value of 2. It will then return the Other Field for each of those items as a collection.

Additional functions can be called on queries. From our example above,

model.sampleDataList.findAll{it.exampleField == 2}.otherField.average{it}

Will return the average of the collection returned by our findAll query.

Operators

Arithmetic Operators

Operator

Purpose

Examples

Addition

2 + 2 = 4

Subtraction

2 - 2 = 0, 4 - 2 = 2

Multiplication

2 * 2 = 4, 4 * 2 = 8, 10 * 0 = 0

/

Division

10 / 5 = 2

%

Modulo (remainder)

4 % 3 = 1, 10 % 2 = 0

Relational Operators

Relational operators are used to compare two objects. In groovy the following operators are available. The result of an expression using a relational operator is either TRUE or FALSE.

Operator

Purpose

Examples

==

Equals

1 + 2 == 3, TRUE, 1 + 2 == 4, FALSE

!=

Different (not equal)

1 + 3 != 4, FALSE, 3 != 2.5, TRUE, “model” == “MODEL”, TRUE

>

Greater than

0 > 8, FALSE, 0 > -2, TRUE, 0 > 0, FALSE

>=

Greater than or equal

0 >= 8, FALSE, 0 >= -2, TRUE, 0 >= 0, TRUE

<

Less than

0 < 8, TRUE, 0 < -2, FALSE, 0 < 0, FALSE

<=

Less than or equal

0 <= 8, TRUE, 0 <= -2, FALSE, 0 <=0, TRUE

Logical Operators

Logical operators allow us to combine boolean expressions:

Operator

Purpose

Examples

&&

and

true && true, TRUE, true && false, FALSE, (1 == 1) && (1 > 2), FALSE

||

or

true || true, TRUE, true || false, FALSE

!

not

!true, FALSE, !false, TRUE

If/Else Statements

If/Else statements are used to perform different actions based on conditional statements.

Basic if/else logic

As an example, let’s say we want to write an expression that when provided with an hour of the day (24 hour clock), returns to us whether the time is AM or PM.

One logical, plain language solution would be to say, if the hour provided is less than 12, return AM, if not, return PM. Let’s implement this in groovy.

if (hour < 12) {
   “AM”
} else {
   “PM”
}

Else If

if (h < 0 || h > 24) {
 "Error"
} else if (h < 12) {
 "AM"
} else {
 "PM"
}

Dates

Modelshop provides a powerful set of date handling libraries that are based on Java Date Formatting. Date formats can be managed in a number of places in the application:

  • Connector import formats

  • Datalist field formats

  • View formats

  • Chart and Cube formats

  • Using Date functions

In each of these places, the same formatting convention is used. Formatting can be used both for guiding the system to import dates as well as formatting dates for output.

For connector fields, the format setting is used to guide parsing on reading data and to coerce an output on writing data. For datalist formats, the primary objective is for displaying dates or when converting to text, but the specified format will also act as a hint when setting a date value from text (either during import or in calculations and rules). Views, charts and cubes use date formatting for display purposes only.

When working with dates in the Modelshop language, the Date library, as well as date and datetime fields themselves, leverage formatting for both parsing and display. The full set of Date library functions can be found here.

The most critical functions regarding formatting are:

  • Creating dates from text:

    myDate = Date.parse(textValue, format)
    
  • Setting dates

    myDate.set(textValue, format)
    
  • Converting dates to text

    myDate.format(format)
    

The format uses the following conventions. Online resources can easily be found to help with nuances regarding this powerful date formatting capability, including the official Java documentation.

Date and Time Patterns

Date and time formats are specified by date and time pattern strings. Within date and time pattern strings, unquoted letters from ‘A’ to ‘Z’ and from ‘a’ to ‘z’ are interpreted as pattern letters representing the components of a date or time string. Text can be quoted using single quotes (’) to avoid interpretation. “’’” represents a single quote. All other characters are not interpreted; they’re simply copied into the output string during formatting or matched against the input string during parsing.

The following pattern letters are defined (all other characters from ‘A’ to ‘Z’ and from ‘a’ to ‘z’ are reserved):

Letter

Date or Time Component

Presentation

Examples

G

Era designator

Text

AD

y

Year

Year

1996; 96

Y

Week year

Year

2009; 09

M

Month in year (context sensitive)

Month

July; Jul; 07

L

Month in year (standalone form)

Month

July; Jul; 07

w

Week in year

Number

27

W

Week in month

Number

2

D

Day in year

Number

189

d

Day in month

Number

10

F

Day of week in month

Number

2

E

Day name in week

Text

Tuesday; Tue

u

Day number of week (1 = Monday…)

Number

1

a

Am/pm marker

Text

PM

H

Hour in day (0-23)

Number

0

k

Hour in day (1-24)

Number

24

K

Hour in am/pm (0-11)

Number

0

h

Hour in am/pm (1-12)

Number

12

m

Minute in hour

Number

30

s

Second in minute

Number

55

S

Millisecond

Number

978

z

Time zone

General time zone

Pacific Standard Time; PST; GMT-08:00

Z

Time zone

RFC 822 time zone

-0800

X

Time zone

ISO 8601 time zone

-08; -0800; -08:00

Pattern letters are usually repeated, as their number determines the exact presentation:

  • Text: For formatting, if the number of pattern letters is 4 or more, the full form is used; otherwise a short or abbreviated form is used if available. For parsing, both forms are accepted, independent of the number of pattern letters.

  • Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it’s needed to separate two adjacent fields.

  • Year: If the formatter’s Calendar is the Gregorian calendar, the following rules are applied. - For formatting, if the number of pattern letters is 2, the year is truncated to 2 digits; otherwise it is interpreted as a number. - For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern “MM/dd/yyyy”, “01/11/12” parses to Jan 11, 12 A.D. - For parsing with the abbreviated year pattern (“y” or “yy”), SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of “MM/dd/yy” and a SimpleDateFormat instance created on Jan 1, 1997, the string “01/11/12” would be interpreted as Jan 11, 2012 while the string “05/04/64” would be interpreted as May 4, 1964. During parsing, only strings consisting of exactly two digits, as defined by Character.isDigit(char), will be parsed into the default century. Any other numeric string, such as a one digit string, a three or more digit string, or a two digit string that isn’t all digits (for example, “-1”), is interpreted literally. So “01/02/3” or “01/02/003” are parsed, using the same pattern, as Jan 2, 3 AD. Likewise, “01/02/-3” is parsed as Jan 2, 4 BC.

Otherwise, calendar system specific forms are applied. For both formatting and parsing, if the number of pattern letters is 4 or more, a calendar specific long form is used. Otherwise, a calendar specific short or abbreviated form is used.

If week year ‘Y’ is specified and the calendar doesn’t support any week years, the calendar year (‘y’) is used instead. The support of week years can be tested with a call to getCalendar().isWeekDateSupported().

  • Month: If the number of pattern letters is 3 or more, the month is interpreted as text; otherwise, it is interpreted as a number. - Letter M produces context-sensitive month names, such as the embedded form of names. Letter M is context-sensitive in the sense that when it is used in the standalone pattern, for example, “MMMM”, it gives the standalone form of a month name and when it is used in the pattern containing other field(s), for example, “d MMMM”, it gives the format form of a month name. For example, January in the Catalan language is “de gener” in the format form while it is “gener” in the standalone form. In this case, “MMMM” will produce “gener” and the month part of the “d MMMM” will produce “de gener”. If a DateFormatSymbols has been set explicitly with constructor SimpleDateFormat(String,DateFormatSymbols) or method setDateFormatSymbols(DateFormatSymbols), the month names given by the DateFormatSymbols are used. - Letter L produces the standalone form of month names.