Libraries

Functions are the cornerstone of writing clean and reusable code. Code that appears multiple times in the same calculation logic should be placed in functions. These functions can appear in any element of the logic. Same thing can be said about libraries, with the difference that libraries allow to use a function from several logics. A rule of thumb is to put code that appears multiple times in multiple calculation logics into library logics.

Use Case

When to use function and when libraries:

Functions

When you have code that appears multiple times in the same calculation logic.

Libraries

When you have code that appears multiple times in multiple calculation logics.

Functions

In Groovy a function is defined with the def word or a return type. Functions can receive any number of arguments, and the types of these arguments do not have to be explicitly defined. Multiple modifiers can be added, such as public, private and protected. If no modifier is provided, the function is public by default.

Let’s look at an example of a simple function that is used for rounding numbers.

Groovy code in logic element "Utils", which defines the rounding function
BigDecimal round(BigDecimal number, int decimalPlaces) { if (number == null) { return null } return number.setScale(decimalPlaces, RoundingMode.HALF_UP) }
Groovy code in logic element "Price", which calculates the price and rounds it to 2 decimal places
def price = priceCalculation() return Utils.round(price, 2) //❶

❶ When calling a function defined in other element, you must specify the name of the element.

The order of the element (with the function definition) in the logic is important, because the function will be visible only to later elements e.g., function defined in the 2nd element will be visible to 3rd, 4th, …​ element but it will not be visible to the 1st element.

The following practice is recommended:

  • The names of the function parameter should be self-explaining.

  • The types of the parameters should be specified.

  • The return types of the library functions should be specified.

  • The functions should be documented using GroovyDoc (similar to Javadoc).

Libraries

A Groovy library is a collection of uniquely named reusable callable Groovy functions linked to our Pricefx application. In Pricefx libraries are basically logics with a library nature type. As with other logics, libraries have elements in which we can write code. They contain definitions of functions, which are used across multiple logics in the same partition. GroovyDoc is a must in this case.

Groovy code in library logic "PriceLib" in element "RoundingUtils", which defines the rounding function
/** * This function rounds given number to given number of decimal places * and returns the rounded value. * It rounds using the standard rounding rules used in math. * * @param number Number to round. * @param decimalPlaces To how many decimal places should the number be rounded to. * @return The rounded value. */ BigDecimal round(BigDecimal number, int decimalPlaces) { if (number == null) { return null } return number.setScale(decimalPlaces, RoundingMode.HALF_UP) }

Library elements should follow the naming conventions, specified in the Best Practices section of the Knowledge Base.

  • The library logic name should have a suffix "Lib" (e.g., SharedLib).

  • The library element names should have a suffix "Utils" (e.g., DatamartUtils).

A library must be deployed to the partition before it can be utilized by other calculation logics. You can verify the presence of the library logic in the Pricefx web application at Administration  Logics  Calculation Logic  Groovy library.

To call the library function, type “libs.” → followed by name of the logic “SharedLib.” → followed by the name of the element in the logic “RoundingUtils” → followed by the name of the function “round”.

Call to the library function, from an element of Pricelist calculation logic

The binding variable libs is available within all logic types.

Summary

As we can see, functions and libraries give us the ability to standardize and reuse specific logical functions that can be applied to our Calculation logics. This promotes efficiency and functional reusability and should be ingrained at the inception of calculation logic design.

Found an issue in documentation? Write to us.