Document Formula

Written By Jessica Moore (Super Administrator)

Updated at January 21st, 2026

Below are the general rules for building formulas in the SchemeServe Document area (Template Editor / endorsement wording / display logic). This is the “same thing” as the rating-file rules, but tailored to how documents actually evaluate fields, formatting, and HTML/CSS.

General rules for SchemeServe document formulas

1) Know the three “contexts” you can write formulas in

Document logic usually appears in one of these places:

  • Inline token formulas wrapped in ## ... ##

Used to print values or run calculations directly in the document body.

  • Display/hide logic inside HTML/CSS, typically:

style="display:##IF(...,'','none')##"

Used to show/hide paragraphs, table rows, divs, etc.

  • Non-## DisplayIf blocks (used when text formatting must be preserved):

<DisplayIf Formula="..."> ... </DisplayIf>

Especially useful for multi-paragraph textbox content that collapses into one line when pulled via ##...##.

✅ Rule: Use the right mechanism for the outcome you want (print vs hide/show vs preserve formatting).

 

2) Inline formulas must be wrapped in ##

If you want the system to evaluate the expression and print the output, you must wrap it:

 
##IF([Record.Type]='Renewal','Renewal','New Business')##

✅ Rule: No ## = it will usually render as literal text (or not evaluate).

 

3) Use square brackets for field references

All fields are referenced using [ ... ].

Common examples:

[Record.Type], [Record.Status], [Record.CreatedDate]
[Policy.InceptionDate], [Policy.OriginalInceptionDate]
[Client.ClientId], [Agent.AccountRef][QuestionID_Value], [QuestionID_Cover], [QuestionID_DateValue]

✅ Rule: If the field name isn’t inside [...], the document engine won’t recognise it as a dynamic field.

 

4) Use the correct suffix (_Value, _Cover, _DateValue, _ResultBefore)

Same idea as rating files, but with some doc-specific gotchas:

Suffix/Modifier

_Cover Numeric/Money - e.g. the amount entered in a Calculation question
_Value Text - e.g. the answer Yes/No
_Fee Numeric/Money - e.g. the Fee you've set some rows above in your rating file
_Result Numeric/Money - e.g. the result of your total Premium 'TotalPremium_Result'
i.e the obtained result of a % applied to £XX Sum Insured
_DateValue Date
_CoverBefore Pull through the previous record´s answer on a calculation question
_Rate Numeric/Money - e.g. the Rate you've set some rows above in your rating file
 
 

✅ Rule: If something prints blank or errors, check you’re using the correct suffix and level (record vs policy).

 

5) Text needs quotes; numbers don’t

Text comparisons: "Yes", "Renewal", "On Cover"

Numeric comparisons: 0, 1000, 30.5

✅ Rule: Quote strings, don’t quote numbers.

 

6) Dates: formatting and comparisons use different techniques

A) Comparing against a fixed date
Use hash-wrapped dates:

 
##IF([Policy.InceptionDate] >= #2021-07-12#,'New wording','Old wording')##

B) Printing a date in a specific format
Use .ToString(...):

 
##[Policy.InceptionDate].ToString("dd MMMM yyyy")##

C) Adding/subtracting time
Use .AddYears(), .AddDays(), etc.:

 
##[CompletionDate_DateValue].AddYears(10).ToString("dd MMMM yyyy")##

✅ Rule: Compare using #yyyy-MM-dd# and display using .ToString(...).

 

7) Converting numbers into readable formats (currency, decimals, percentages)

You’ll commonly format numeric outputs using .ToString(...):

Currency (no decimals):

 
##[PLIndemnity_Cover].ToString("C0")##

Currency (2 decimals):

 
##[BasicPremium_Result].ToString("C2")##

Number with 1 decimal:

 
##(([TotalCommission_IndexLevel0_Result]/[TotalPremiumNet_Result])*100).ToString("N1")## %

✅ Rule: Do calculations first, then format the final output.

 

8) Show/hide content using display:##IF(...)##

This is the standard pattern:

 
<tr style="display:##IF([Record.Type]='Renewal','','none')##">

How it works:

IF true → return '' (blank) → normal display

IF false → return 'none' → hidden

✅ Rule: In display logic, return '' to show and 'none' to hide.

 

9) Multi-field “one line address” pattern: build strings safely

When concatenating fields, protect optional lines by checking if they contain real text:

 
##[AddressLine1]## ##IF([AddressLine2].Replace(' ','').Length>0, ', ' + [AddressLine2], '')## ...

✅ Rule: Use .Replace(' ','').Length > 0 to avoid printing stray commas.

 

10) Tables and MP: know when you need row indexing or GroupBy

To pull a specific row:

 
##[Table_Name_Row#0_Value]##

For MultiPage (MP) documents, use [GroupBy ...] ... [/GroupBy] and MP fields like:

##[MP_RowNumber]## (inside groupby)

##[MP_SystemID_Cover]## (combined totals outside groupby, with limitations)

✅ Rule: If your output repeats per premises/row, you almost always need GroupBy.

 

11) Keep document formulas readable and maintainable

Best practice in templates:

Keep formula blocks short and repeatable

Prefer hidden fields in rating when the doc logic becomes complex (docs are for presentation)

Use consistent patterns for display toggles ('' vs 'none')

✅ Rule: If you’re building “logic”, consider moving it to rating and just printing the result in the doc.

 


Quick “before you save” checklist ✅ (Documents)