BriteCore's rating engine provides several functions you can use in your calculations.

## Available functions

#### bc.optional

This function marks data fields, rate tables, and items as optional. If a rate table is marked as optional, then BriteLines will determine which fields the rate table uses as sources and mark them as optional. To use `bc.optional()`

, wrap the data field, rate table, or item reference names in the function.

#####
`bc.optional`

with Rate Tables

Example:

bc.min(primaryDriverRateTable, bc.optional(secondaryDriverRateTable))

By wrapping `secondaryDriverRateTable`

as `bc.optional`

, all of the data fields that `secondaryDriverRateTable`

points to will be optional during quoting. If `secondaryDriverRateTable`

has no default value set or you want to override the default value, then you can pass a default value to the `bc.optional`

function.

Note:The default value must be a number.

bc.min(primaryDriverRateTable, bc.optional(secondaryDriverRateTable, default=1))

#####
`bc.optional`

with Items

Example:

mandatoryItem.premium.term.value + bc.optional(optionalItem.premium.term.value, default=0)

In this example, we add a mandatory item's premium to an optional item's premium.

- If the mandatory item's premium is 50 and the optional item exists on the policy and has a premium of 50, then this calculation will return 100.
- If the mandatory item's premium is 50 and the optional item hasn't been enabled for the policy, then this calculation will return 50.
- If the mandatory item's premium is 50 and the optional item exists on the policy but can't be resolved yet, then this calculation will return 50.

##### Optional fields in quoting

During quoting, a field will only be considered optional if:

- All calculations that refer directly to the field are wrapped in
`bc.optional()`

. - All rate tables that refer to the field are wrapped in
`bc.optional()`

. - All used optional fields are wrapped in
`[bc.optional](rating.md#bcoptional)`

.

This means a field can be optional or required depending on the items selected for a risk. Example:

- If a quote has Item 1 enabled, then all Item 1 calculations mark the
`additionalDriver`

field as optional. It is optional on the quote. - If Item 2 is enabled on the quote and it has calculations that refer to
`additionalDriver`

, which aren't wrapped in`bc.optional()`

, then**Additional Driver**becomes a required field (because it's not filled out, then Item 2 couldn't rate).

#### bc.age

bc.age(date_or_number, {base_date})

Returns the age of something in years from a given date or number. To use a different base date when calculating age, provide a `base_date`

.

Note:If a`base_date`

isn't provided, BriteCore uses the quote rating date (`bc.transactionEffectiveDate`

) as the base date.

Example:

bc.age(dateOfBirth, {base_date})

This allows us to collect the date of origin and find its age dynamically, so we can collect **Birthday**/**Year Built**/**Year Purchased**. Then, `bc.age()`

will use the quote rating date (`bc.transactionEffectiveDate`

) or a specified `base_date`

to find the age based on these dates. Example: If the following are true:

- You collect
`dateOfBirth`

as a date input. - The user chooses "01/31/1992".
- The rating date year is 2017.

Then `bc.age(dateOfBirth)`

will return 25. This function isn't simply the difference in years; it also accounts for aging in the current year. So if the rating date is "12/13/2017" and the user types "12/15/2000", then the value isn't 17, but 16 because the 15th hasn't yet passed. Users can also pass in numbers, in which case `bc.age()`

assumes the number is a year. For instance, a calculation of `bc.age(2010)`

will return 8 if the current year is 2018.

Note:This is useful for calculating the age of vehicles.

bc.age(vehicleModelYear)

Optionally, a `base_date`

parameter can be provided to use a different base date when calculating age. Example:

bc.age(dateOfBirth, bc.policyTermEffectiveDate)

When the `base_date`

isn't provided, BriteCore uses the quote rating date, `bc.transactionEffectiveDate`

, as the base date. The `bc.age()`

utility will always return the difference between the rating date or specified `base_date`

and the value passed into the function, which means `bc.age()`

could return a negative number for future dates and years. To prevent `bc.age()`

from returning negative numbers, change your calculation to the following: `bc.max(bc.age(vehicleModelYear), 0)`

#### bc.condition

Returns different results based on whether the condition is true or false.

bc.condition(hasAntiLockBrakes, 0.95, 1.0)

If the user has selected `Yes`

for the `hasAntiLockBrakes`

boolean field, this calculation would return 0.95. If the user hasn't selected `Yes`

, then it would return 1.0.

#### bc.if_item

Returns different results based on whether the risk has a specific item selected.

bc.if_item('comprehensive', 0.95, 1.0)

This calculation would return 0.95 if the comprehensive coverage is present on the quote. If the coverage isn't present, then the calculation would return 1.0.

#### bc.round

Rounds values based on `round_to`

and `round_method`

.

bc.round(some_number, round_to=bc.NEAREST_HUNDRED, round_method=bc.ROUND_UP)

`bc.round`

also works with an alternative syntax:

bc.round(some_number, 2)

This is a simplified version that would round `some_number`

to the second decimal place.

#####
`round_to`

options

Note:`round_to`

options default to`TWO_DECIMALS`

(the nearest penny).

`bc.ZERO_DECIMALS`

Example: bc.round(88.7915, round_to=bc.ZERO_DECIMALS) = 89

`bc.ONE_DECIMAL`

Example: bc.round(88.7915, round_to=bc.ONE_DECIMALS) = 88.8

`bc.TWO_DECIMALS`

Example: bc.round(88.7915, round_to=bc.TWO_DECIMALS) = 88.79

`bc.THREE_DECIMALS`

Example: bc.round(88.7915, round_to=bc.THREE_DECIMALS) = 88.792

`bc.FOUR_DECIMALS`

Example: bc.round(88.7915, round_to=bc.FOUR_DECIMALS) = 88.7915

`bc.FIVE_DECIMALS`

Example: bc.round(88.791578, round_to=bc.FIVE_DECIMALS) = 88.79158

`bc.NEAREST_ONE`

Example: bc.round(88.7915, round_to=bc.NEAREST_ONE) = 89

`bc.NEAREST_TEN`

Example: bc.round(88.7915, round_to=bc.NEAREST_TEN) = 90

`bc.NEAREST_HUNDRED`

Example: bc.round(88.7915, round_to=bc.NEAREST_HUNDRED) = 100

`bc.NEAREST_THOUSAND`

Example: bc.round(1250.4762, round_to=bc.NEAREST_THOUSAND) = 1000

#####
`round_method`

options

`bc.ROUND_UP`

`bc.ROUND_DOWN`

`bc.ROUND_CEILING`

`bc.ROUND_FLOOR`

`bc.ROUND_HALF_UP`

Note:`round_method`

options default to`bc.ROUND_HALF_UP`

(natural rounding).

#### bc.max

Returns the maximum value from all values passed to it. If `primaryDriverRateTable`

resolves to 800.0 and `secondaryDriverRateTable`

resolves to 400.0, then the following function would return 800.0.

bc.max(primaryDriverRateTable, secondaryDriverRateTable)

#### bc.min

Returns the minimum value from all values passed to it. If `primaryDriverRateTable`

resolves to 800.0 and `secondaryDriverRateTable`

resolves to 400.0, then the following function would return 400.0.

bc.min(primaryDriverRateTable, secondaryDriverRateTable)

### limits

Uses `<itemName>.limits.<limitName>`

to access an item's limits.

bodilyInjury.limits.bodilyInjuryLimit