# Formula Configuration

How to configure a formula you want will be introduced here. First you need to know the business logics and these logics need to be written in mathematical expressions using expression blocks. Then you can use blocks in the left toolbar to draw this formula in workspace so that system can generate DSL language accordingly for product engine to recognize and apply the same to run formula in runtime.
Before starting with a real formula, you need to get acquaintance with the blocks in the toolbar first.

## Basic Blocks
Click **Basic Blocks** in the left toolbar to see all basic blocks.

![basic blocks](./image/formula_configuration/basic_blocks.png)







|    Block Image    |    Function description                                                                                                                                                                                                                                                                                                                                                                 |
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|         ![Block](./image/formula_configuration/Block.png)          |    Basic carrier Block. Used to carry other blocks such as free text block or condition block.                                                                                                                                                                                                                                                                                       |
|       ![Carrier](./image/formula_configuration/Carrier.png)            |    Free text block can be used to define the free text value.  ![Carrier_premium](./image/formula_configuration/Carrier_premium.png)  This will be wrapped into a basic carrier or other carrier blocks to use in the formula.<br> If you want to define a string (not a variable name), you need to input single inverted comma to the text.   ![String](./image/formula_configuration/String.png)                                                                                                                                   |
|      ![Variable_define_block_1](./image/formula_configuration/Variable_define_block_1.png)          |    Variable define block. Used to define a variable.<br> If change **def** to **null**, it means assign some value to a variable. ![Variable_define_block_2](./image/formula_configuration/Variable_define_block_2.png)                                                                                                                                                                                                                                                          |
|     ![Rate_Amount](./image/formula_configuration/Rate_Amount.png)       |             Used to define Rate or Amount. Most used in formula of fees and taxes.<br>   The two options can be switched by clicking the green dropdown.  ![Rate_Amount2](./image/formula_configuration/Rate_Amount2.png)                                                                                                                                                                                                                                                             |
|      ![return_true](./image/formula_configuration/return_true.png)           |              Used to return a true or false value.<br> It can also change the block to be any formula as  form of **A B**.  |
|        ![brackets](./image/formula_configuration/brackets.png)           |    Operational formula block, including add, subtract, multiply and divide. Support to add or remove brackets freely. ![brackets2](./image/formula_configuration/brackets2.png)     It should be wrapped into a basic carrier or other carrier blocks as below. ![def_amount](./image/formula_configuration/def_amount.png)                                                                                                                                                                              |
|      ![else_if](./image/formula_configuration/else_if.png)             |    Compare block. Used to compare 2 variables, resulting in true or false. Usually be used in conditional statement.   Support comparison operators below:<br>  · Equal to.<br>  · Not equal to.<br>   · Less than.<br>   · Less than or equal to.<br>   · Greater than.<br>   · Greater than or equal to. <br>              ![choices](./image/formula_configuration/choices.png)                             |
|       ![brackets_and](./image/formula_configuration/brackets_and.png)            |    Condition block. Can be nested.    Usually be used in conditional statement. ![null_brackets](./image/formula_configuration/null_brackets.png)                                                                                                                                                                                                                                                                                                   |
|       ![if_do_else](./image/formula_configuration/if_do_else.png)            |    Conditional statement block.   The condition after **If** can be changed by removing it and dragging another block to attach after **If**.<br>  ![if_do_else2](./image/formula_configuration/if_do_else2.png)  <br>  If users need to add or remove condition, such as removing else or adding an **else if**, they can click the icon on the top left corner. Then users can drag an item from the left to the right to add a condition; or drag the item from the right to the left to remove it.<br>   ![else_if2](./image/formula_configuration/else_if2.png)    |
|       ![array](./image/formula_configuration/array.png)            |    Array define block. A block below means [1, 2].    ![array2](./image/formula_configuration/array2.png)                                                                                                                                                                                                                                                                                                                                  |
|      ![ceiling](./image/formula_configuration/ceiling.png)             |    Used to define the precision mode of a number.   Usually used in complex business block.<br>     ![ceiling_choices](./image/formula_configuration/ceiling_choices.png)                                                                                                                                                                                                                                                                    |
|      ![set_name](./image/formula_configuration/set_name.png)             |    Used to define a specific DSL block name. Usually   used in complex business block.                                                                                                                                                                                                                                                                           |
|       ![set_filter](./image/formula_configuration/set_filter.png)            |                                                                                                                                                                                                                                                                                                                                                                                     |
|       ![closure](./image/formula_configuration/closure.png)            |    Used to define a variable whose value is returned from a closure. Users can consider it as an immediate execution method.<br>   Usually used to define a global variable.                                                                                                                                                                                                           |
|        ![script](./image/formula_configuration/script.png)           |                                                                                                                                                                                                                                                                                                                                                                                     |

## Factor Blocks
You can find all factors defined in product structure under **Factors** menu in formula configuration. These factors are grouped according to applies to level defined in the factor definition. Once you click any of the nodes under **Factors** in formula configuration, it will list out all factors on right side.
The factors here are usually used as parameters to pass dynamic value into the formula.

![policy](./image/formula_configuration/policy.png)

## Functions

Function is a block of code designed to perform a particular task. It is executed when **something** invokes it (calls it). Here **something** means if a user enters the required data for function, and then the expected result gets calculation basis on the code or algorithm written in the function.

![functionName](./image/formula_configuration/functionName.png)

Please see the table below where some of the functions are explained in detail. 

### Basic Functions

|    Block Image                                                                                   |    Function description                                                                                                                                                    |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|                       ![add_days](./image/formula_configuration/add_days.png)                                                                              |    Date processing function, adding specific days to a date, returns the new date. <br>Parameter 1: original date,  e.g. 10/22/2019. <br>Parameter 2: days to add or subtract. <br>Function name `add_months`, <br>functionDesc adding X months on given date parameters of function are : {“name” : “date”, “desc” : “the date in the date format”, :type” : “date”} {“name” : “curdate”, “desc” : “how many months you want to add on given date”, “type” : “INT”}.     |
|                            ![add_months](./image/formula_configuration/add_months.png)                                                                      |    Date processing function, adding specific months to date, returns count of months.<br> Parameter 1: original date, e.g 10/22/2019. <br>Parameter 2: months to add or subtract. <br> Function name `add_months`, <br>functionDesc adding X months on given date parameters of function are : {“name” : “date”, “desc” : “the date in the date format”, :type” : “date”} {“name” : “curdate”, “desc” : “how much months you want to add on given date”, “type” : “INT”}.    |
|                            ![add_years](./image/formula_configuration/add_years.png)                                                                      |      Date processing function, adding specific months to date, returns count of years. <br>Parameter 1: original date, e.g 10/22/2019. <br> Parameter 2: years to add or subtract. <br> Function name `add_years`, <br>functionDesc adding x years on given date parameters of function are : {"name":"date","desc":"the date in date format","type":"DATE"}{"name":"curdate","desc":"how many years you want to add on given date","type":"INT"}.  |
|                                     ![age](./image/formula_configuration/age.png)                                                             |          Date processing function, adding current date and date of birth, returns the age in years. <br>Parameter 1: current date, e.g 10/22/2019. <br> Parameter 2: date of birth, e.g 10/23/1990. <br> Function name `calc_age`, <br>functionDesc calculating the age with given date of birth with current date parameters of function are : {"name":"dob", "desc":"the age in date format"}  |
|                           ![currentDate](./image/formula_configuration/currentDate.png)                                                                       |    Date processing function, returns current date. <br> Function name `currentDate`, <br>functionDesc get the current system date.  |
|              ![get_Days](./image/formula_configuration/get_Days.png)                                                                                    |    Date processing function, returns days between two dates. <br> Parameter 1: endorsement effective date, e.g 10/22/2019. <br> Parameter 2: policy effective date, e.g 10/23/1990. <br> Function name `getDaysBetweenTwoDates`, <br>functionDesc get delta days between given two days parameters of function are : {"name":"date1","desc":"the one date","type":"DATE"}{"name":"date2","desc":"the another date","type":"DATE"}.    |
|                                      ![POI](./image/formula_configuration/POI.png)                                                            |      Date processing function, returns days between policy effective date and expiry date. <br>Parameter 1: policy effective date, e.g 10/22/2019. <br> Parameter 2: policy expiry date, e.g 10/21/2020. <br> Function name `getDaysFromPOI`, <br>functionDesc getting days between POI parameters of function are : {"name":"effDate","desc":"policy effective date in date format","type":"DATE"}{"name":"expDate","desc":"policy expiry date in date format","type":"DATE"}.                                       |
|                    ![hour](./image/formula_configuration/hour.png)                                                                              |      Function name `hour`, <br>functionDesc getting hour of day from given date parameters of function are : {"name":"date","desc":"the given date in date format","type":"DATE"}.                                                                                                |
|              ![month](./image/formula_configuration/month.png)                                                                                    |     Date processing function, returns month from the date parameter. <br> Parameter :date, e.g 10/22/2019. <br> Function name `month`, <br>functionDesc getting month from given date parameters of function are : {"name":"date","desc":"the given date in date format","type":"DATE"}.                                                                                                                                |
|              ![daily_rates](./image/formula_configuration/daily_rates.png)                                                                                    |   Function name `proDailyRate`, <br>functionDesc calculating POI rate based on current year parameters of function are : {"name":"effDate","desc":"policy effective date in date"}.                                                                              |
|                ![number](./image/formula_configuration/number.png)                                                                                  |   Function name `thousandsNumber`, <br>functionDesc formatting the given number as thousands format (eg: 1,000,000) parameters of function are : {"name":"number","desc":"the given number need to thousands format","type":"NUMBER"}.   |
|                           ![total](./image/formula_configuration/total.png)                                                                       |   Function name `totalDaysToXYears`, <br>functionDesc getting delta days between given date and X years later of given date parameters of function are : {"name":"date","desc":"the given date in date"}.                                                                      |
|      ![timeofdate](./image/formula_configuration/timeofdate.png) |    Function name `truncateTimeOfDate`, <br>functionDesc truncating the time of current date parameters of function are : {"name":"date","desc":"the given date in date format","type":"DATE"}.                                |
|                                ![year2](./image/formula_configuration/year2.png)                                                                  |    Function name `year`, <br>functionDesc getting year from given date parameters of function are : {"name":"date","desc":"the given date in date format","type":"DATE"}.                                                           |

### Math Functions

|    Block Image                                                                                   |    Function description                                                                                                                                                    |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|   ![ceiling2](./image/formula_configuration/ceiling2.png)  | Ceiling the given decimal value. <br> Parameter: Value<DECIMAL>. |
| ![floor](./image/formula_configuration/floor.png) | Floor the given decimal value. <br> Parameter: Value<DECIMAL>. |
| ![halfUp](./image/formula_configuration/halfUp.png) | Parameter 1: The value <BIGDECIMAL>  to be rounded up. <br> Parameter 2: Precision<INT>. If a integer number is wanted, just set parameter 2 to be 0.  |

### Business Functions

|    Block Image                                                                                   |    Function description                                                                                                                                                    |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ![value](./image/formula_configuration/value.png) | Get deductible value on indicated coverage. <br> Parameter 1: Coverage code. <br> Parameter 2: Deductible type.  |
| ![limit_value](./image/formula_configuration/limit_value.png) | Get limit value on indicated coverage. <br> Parameter 1: Coverage code. <br> Parameter 2: Limit type.  |
| ![deductible_value](./image/formula_configuration/deductible_value.png) | Get deductible value on indicated sub coverage(interest). <br> Parameter 1: Coverage code. <br> Parameter 2: Sub coverage code. <br> Parameter 3: Deductible type.  |
| ![limit_value](./image/formula_configuration/limit_value.png) | Get limit value on indicated sub coverage(interest). <br> Parameter 1: Coverage code. <br> Parameter 2: Sub coverage code. <br> Parameter 3: Limit type. |

Parameter value of limit/deductible type:<br> 
•	`PER_ACCIDENT` – If limit/deductible type is set as AOA.<br>
•	`PER_POLICY` – If limit/deductible type is set as AOP.<br>
•	`MAX_PERSON` – Not Supported yet.<br>
•	`PER_POLICY` – If limit/deductible type is set as LIFETIME.

## Rate Tables

After uploading rate table in **Tables** page, we can find the rate table uploaded under **Rate Tables** in formula configuration toolbar. All tables in the uploaded rate table file will be listed here, using sheet name as table name.

![short_basic_rate](./image/formula_configuration/short_basic_rate.png)
![basic_rate_result](./image/formula_configuration/basic_rate_result.png)
![result](./image/formula_configuration/result.png)

In Image expression block above, the block is used to fetch the specific value from the rate table. Here system will fetch the result from the rate table basis on the parameters given in rate table params block. You can see all columns in the rate table on left side.

###  Detail explanation of rate table block 
In this block, there’re 3 parameters - function name, condition Clause and parameters.

####  Function Name 
There are 3 types of function:<br>
a.	**Locate** – Used to find a certain row.
<br> Note : System will return error, if no row can be found by the given condition.<br>
b.	**Exists** – Check if the row can be found by the given condition, returns true or false.<br>
c.	**LocateIfExists** – If system can find a certain row by given condition, returns this row, otherwise returns null.

####  Condition Clause  
It’s the search condition like where clause in SQL. Let’s see the following example:
**?** between `AGE_From` and `AGE_To` and `Plan_Code`. 
The question mark **?** will map with the value of parameters (in this case they are **age** and **planCode**) in sequence. So the sentence above means we need to find a row that the value of age is between rate table columns `AGE_From` and `AGE_To` and the value of plan code should be equal to column `Plan_Code`.
Currently we can input the condition clause manually.

#### Parameters (Array format)
List all parameters that need to be used to locate a certain row in rate table. The order need to match the order of question marked **?** in condition clause.

### A Simple Example 
Let’s understand these better with an example. Suppose a rate table is prepared as below according to business requirement:

![result2](./image/formula_configuration/result2.png)

It can be seen that by age and plan code, we can locate a certain row and get the premium. For example, if parameter age is 20 and plan code is **Plan2**, then the premium should be 700,000.
So, we need to drag a free text block to be the parameter after **locate**, and key in the condition clause as below:
**?** between `AGE_From` and `AGE_To` and `Plan_Code`.

Then parameters **age** and **planCode** should be dragged from factors block. Now the formula will look like below.

![main_config](./image/formula_configuration/main_config.png)

If parameter age is 20 and plan code is **Plan2**, then system will locate row 8 according to given condition, and that’s the value of variable “`Main_CoverageResult`”. We can use “`Main_CoverageResult.Premium`” to get the corresponding premium 700,000.
Now we can finish this rating formula as below:

![age_plancode](./image/formula_configuration/age_plancode.png)

## Business Blocks

There are some commonly used but complex logics, like premium adjustment of different policy period (POI Adjustment block). System provides these logics as business blocks to use, and they can be dragged to the workspace; some options and blocks can be changed accordingly.

### POI Adjustment 
System provided 2 samples of POI adjustment block.
1)	Adjusted by basic prorate – daily or monthly.

![set_names](./image/formula_configuration/set_names.png)

2)	Adjusted by user defined rate table.

![set_names2](./image/formula_configuration/set_names2.png)

### Underwriter Function
When defining a referral (underwriting) rule, the formula MUST return an underwriting result object, using function **refer(…)**. The underwriting function block is used to give an example of formula of this kind. You just need to add logics to change value of variable **uwResult** in different conditions.

![uw_result](./image/formula_configuration/uw_result.png)

Parameters of function refer():<br>
•	Parameter 1: Underwriting level, if not defined just input 0.<br>
•	Parameter 2: Underwriting result, true means pass while false means block. <br>
•	Parameter 3: Underwriting message.

## Global Variable

You can define the variables which can be used across the algorithms. These variables are called as **Global Variables** as shown in Image 1 below. In New **Algorithm** you need to define Algorithm Code as **COMMON** so that the algorithm steps defined under it can be used as Global Variable. Please refer below Image 2 and 3.

Image 1:

![fill_out](./image/formula_configuration/fill_out.png)

Image 2:

![fill_out2](./image/formula_configuration/fill_out2.png)

Image 3:

![formula_info](./image/formula_configuration/formula_info.png)

## Retrieve Deleted Blocks

If you want to retrieve some deleted blocks, you can find them by clicking **Recycle Bin** as shown in Image 1 below. Once clicking **recycle bin**, you will find all deleted blocks on right hand side panel as shown in Image 2 below.

Image 1:

![formula_info2](./image/formula_configuration/formula_info2.png)

Image 2:

![formula_info3](./image/formula_configuration/formula_info3.png)