Invoice Template Formula Reference Guide

Magnit VMS — MSP Configuration

1. Introduction

The Invoice Template builder lets you define how data appears in each section of a generated invoice — Header, Columns, and Footer. By default, each field displays a single data value. Enabling the Formula toggle unlocks a formula expression editor where you can combine fields, apply functions, and build calculated values.

Where Formulas Are Available

Formula fields can be used in:

  • Header fields
  • Column fields (table rows)
  • Footer fields

How to Enable a Formula Field

  1. Open or add a field in the Header, Column, or Footer section.
  2. Toggle the Formula switch at the top of the dialog to ON.
  3. The editor switches to formula mode, showing a toolbar with Category, Function, and Data Field dropdowns.

Using the Formula Builder Toolbar

  • Category — filters the available data fields by type (for example, Billing Item, Daily, Expense).
  • Data Field — inserts a field reference into the formula at the cursor position.
  • Function — inserts a function template (for example, CONCAT(field1, field2)) at the cursor position.

Formula Editor Color Coding

  • Function names appear in brown
  • Field references {{FIELD_NAME}} appear in blue
  • Parentheses and brackets appear in gray

2. Field Reference Syntax

To reference a data field inside a formula, wrap its name in double curly braces:

{{FIELD_NAME}}

Examples:

{{AMOUNT}}
{{CURRENCY_CODE}}
{{FIRST_NAME}}
{{INVOICE_NUMBER}}

Tip: Always use the Data Field dropdown in the toolbar to insert field names — this ensures correct spelling and case. Field names are case-sensitive.

Fields can be used directly as values, passed into functions, or combined with operators:

{{AMOUNT}} + {{TAX}}
CONCAT({{FIRST_NAME}}, " ", {{LAST_NAME}})
CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, 0)

3. Operators

3.1 Arithmetic Operators

Use arithmetic operators to perform calculations between field values and numeric literals.

Operator Description Example
+Addition{{REGULAR_HOURS}} + {{OVERTIME_HOURS}}
-Subtraction{{GROSS_AMOUNT}} - {{DISCOUNT}}
*Multiplication{{HOURS}} * {{RATE}}
/Division{{TOTAL_AMOUNT}} / 2

Operators can be combined and grouped with parentheses:

({{REGULAR_HOURS}} + {{OVERTIME_HOURS}}) * {{HOURLY_RATE}}

Tip: If a field may be null, wrap it in NULLTOZERO() before arithmetic to avoid errors — see Section 4.2.

3.2 Comparison Operators

Comparison operators evaluate a condition and return true or false. They are primarily used inside CASE conditions.

Operator Description Example
==Equal to{{CURRENCY_CODE}} == "INR"
!=Not equal to{{STATUS}} != "Cancelled"
<Less than{{HOURS}} < 40
<=Less than or equal to{{HOURS}} <= 40
>Greater than{{AMOUNT}} > 1000
>=Greater than or equal to{{AMOUNT}} >= 500

String values must be in double quotes: "INR", "Active". Numbers are written without quotes: 40, 1000.

3.3 Logical Operators

Logical operators combine multiple conditions into a single expression.

Operator Description Example
&&AND — both conditions must be true{{ACTIVE}} == "Y" && {{ELIGIBLE}} == "Y"
||OR — at least one condition must be true{{TYPE}} == "FT" || {{TYPE}} == "PT"

Example combining AND with CASE:

CASE({{COUNTRY}} == "US" && {{HOURS}} > 40, {{OVERTIME_RATE}}, {{STANDARD_RATE}})

→ Returns OVERTIME_RATE only when country is "US" AND hours exceed 40; otherwise STANDARD_RATE.

4. Functions

4.1 String Functions

CONCAT

Joins two or more values together. Null values are automatically skipped.

Syntax: CONCAT(value1, value2, ...)

CONCAT({{FIRST_NAME}}, " ", {{LAST_NAME}})
CONCAT({{BILL_CLIENT_INVOICE_NUMBER}}, {{BILL_DOWN_FEE_NUMBER}})
CONCAT("INV-", {{INVOICE_NUMBER}}, "-", {{YEAR}})

FIRST

Returns the first N characters of a value.

Syntax: FIRST(n, value)

FIRST(3, {{INVOICE_NUMBER}})

→ If INVOICE_NUMBER is "INV-2024-001", result is "INV".

LAST

Returns the last N characters of a value.

Syntax: LAST(n, value)

LAST(4, {{ACCOUNT_CODE}})

→ If ACCOUNT_CODE is "GL-4500", result is "4500".

SUBSTR

Extracts a portion of a string. The start index is 1-based (the first character is position 1).

Syntax: SUBSTR(value, startIndex, length)

SUBSTR({{INVOICE_REF}}, 3, 5)

→ Starting at character 3, extracts 5 characters.

SPLIT

Splits a value by a delimiter and returns the part at the given index. The index is 1-based.

Syntax: SPLIT(value, delimiter, index)

SPLIT({{FULL_ADDRESS}}, ",", 1)
SPLIT({{PROJECT_CODE}}, "-", 2)

→ Returns the text before the first comma. → Returns the second segment of a hyphen-delimited code.

REPLACE

Replaces all occurrences of a target substring with a replacement.

Syntax: REPLACE(value, target, replacement)

REPLACE({{DESCRIPTION}}, "N/A", "Not Available")
REPLACE({{NOTES}}, " ", "_")

LENGTH

Returns the number of characters in a value. Returns 0 if the value is null.

Syntax: LENGTH(value)

LENGTH({{NOTES}})
LENGTH({{DESCRIPTION}})

4.2 Null Handling Functions

NULLTOZERO

Returns 0 if the field value is null. Use this before performing arithmetic on optional numeric fields.

Syntax: NULLTOZERO(value)

NULLTOZERO({{OVERTIME_HOURS}})
NULLTOZERO({{AMOUNT}}) + NULLTOZERO({{TAX}})

NULLTOEMPTY

Returns an empty string if the field value is null.

Syntax: NULLTOEMPTY(value)

NULLTOEMPTY({{MIDDLE_NAME}})
CONCAT({{FIRST_NAME}}, " ", NULLTOEMPTY({{MIDDLE_NAME}}), " ", {{LAST_NAME}})

4.3 Conditional Function: CASE

Evaluates a series of conditions in order and returns the value associated with the first true condition. An optional final argument is returned when no condition matches (the "else" value).

Syntax:

CASE(condition1, result1, condition2, result2, ..., elseValue)

Using == (equal to):

CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, 0)
CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, {{CURRENCY_CODE}} == "USD", {{USA_TAX_AMOUNT}}, 0)

→ First formula: returns TAX_AMOUNT for INR; else 0. Second formula: TAX_AMOUNT for INR, USA_TAX_AMOUNT for USD, else 0.

Using != (not equal to):

CASE({{STATUS}} != "Cancelled", {{AMOUNT}}, 0)

→ Returns AMOUNT for every status except "Cancelled"; returns 0 for cancelled records.

Using < / <= (less than):

CASE({{HOURS}} <= 40, "Regular", "Overtime")
CASE({{AMOUNT}} < 500, "Low", {{AMOUNT}} < 1000, "Medium", "High")

→ First: "Regular" for 40 h or fewer; else "Overtime". Second: classifies amount into Low/Medium/High.

Using > / >= (greater than):

CASE({{AMOUNT}} >= 10000, {{AMOUNT}} * 0.05, {{AMOUNT}} >= 5000, {{AMOUNT}} * 0.03, 0)

→ 5% discount for amounts ≥ 10,000; 3% for amounts ≥ 5,000; no discount otherwise.

Using && (AND) inside a CASE condition:

CASE({{COUNTRY}} == "US" && {{HOURS}} > 40, {{OVERTIME_RATE}}, {{STANDARD_RATE}})

→ Overtime rate only when country is "US" AND hours exceed 40.

Using || (OR) inside a CASE condition:

CASE({{STATUS}} == "Pending" || {{STATUS}} == "Under Review", "In Progress", {{STATUS}})

→ Displays "In Progress" for Pending or Under Review; otherwise the status as-is.

4.4 Membership Functions

CONTAINS

Returns true if a string contains a given substring.

Syntax: CONTAINS(source, value)

CONTAINS({{DESCRIPTION}}, "Premium")
CASE(CONTAINS({{NOTES}}, "urgent"), "Priority", "Standard")

IN

Returns true if a value matches any of the listed options.

Syntax: IN(value, option1, option2, ...)

IN({{COUNTRY}}, "USA", "Canada", "Mexico")
CASE(IN({{CURRENCY_CODE}}, "INR", "USD", "EUR"), {{AMOUNT}}, 0)

NOTIN

Returns true if a value does NOT match any of the listed options. Inverse of IN.

Syntax: NOTIN(value, option1, option2, ...)

NOTIN({{STATUS}}, "Cancelled", "Rejected")
CASE(NOTIN({{COUNTRY}}, "US", "CA"), {{FOREIGN_TAX}}, 0)

4.5 Numeric Functions

ROUND

Rounds a numeric value to a specified number of decimal places (half-up rounding).

Syntax: ROUND(value, scale)

ROUND({{TOTAL_AMOUNT}}, 2)
ROUND({{HOURS}} * {{RATE}}, 2)
ROUND(NULLTOZERO({{TAX_AMOUNT}}) / 2, 2)

4.6 Date Functions

ADDDAYS

Adds a number of days to a date field.

Syntax: ADDDAYS(dateField, days)

ADDDAYS({{START_DATE}}, 7)
ADDDAYS({{INVOICE_DATE}}, 30)

SUBSTRACTDAYS

Subtracts a number of days from a date field.

Syntax: SUBSTRACTDAYS(dateField, days)

SUBSTRACTDAYS({{END_DATE}}, 30)
SUBSTRACTDAYS({{DUE_DATE}}, 7)

Note: The function is spelled SUBSTRACTDAYS (one 'T', not "SUBTRACT"). Use the Function dropdown to insert it correctly.

5. Nesting Functions

Functions can be nested — the result of an inner function is passed as an argument to the outer function. When reading a nested formula, work from the inside out: the innermost expression is evaluated first.

Null-safe arithmetic

Wrap optional numeric fields in NULLTOZERO before calculating to avoid errors:

NULLTOZERO({{AMOUNT}}) + NULLTOZERO({{TAX}})

Round a calculated result

ROUND(NULLTOZERO({{TAX_AMOUNT}}) / 2, 2)

Step by step:

  1. NULLTOZERO({{TAX_AMOUNT}}) → converts null to 0
  2. ... / 2 → divides by 2
  3. ROUND(..., 2) → rounds to 2 decimal places

Conditional + null-safe + arithmetic (full pattern)

ROUND(NULLTOZERO(CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, 0)) / 2, 2)

Step by step:

  1. CASE(...) → picks TAX_AMOUNT if currency is INR, else 0
  2. NULLTOZERO(...) → turns null result into 0
  3. ... / 2 → halves the value
  4. ROUND(..., 2) → rounds to 2 decimal places

String nesting — build a formatted code

CONCAT(FIRST(3, {{INVOICE_NUMBER}}), "-", SUBSTR({{ACCOUNT_CODE}}, 1, 4))

→ First 3 chars of invoice number + hyphen + first 4 chars of account code.

CASE with a function as the result

CASE({{STATUS}} == "Active", CONCAT({{FIRST_NAME}}, " ", {{LAST_NAME}}), "Inactive User")

→ Returns full name for active records; "Inactive User" otherwise.

Membership check driving a CASE

CASE(IN({{COUNTRY}}, "US", "CA", "MX"), "North America", "Other")

→ "North America" for US, Canada, or Mexico; "Other" for all other countries.

Tip: There is no hard limit on nesting depth, but keep formulas readable. If a formula grows very long, review whether a simpler combination of conditions achieves the same result.

6. Real-World Examples

The following examples are based on real invoice template use cases.

Example 1 — Single-Currency Tax (Half Amount)

Goal: Show half the INR tax amount; show 0 for all other currencies.

NULLTOZERO(CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, 0)) / 2
  • CASE(...) returns TAX_AMOUNT when currency is INR, else 0
  • NULLTOZERO(...) handles the case where TAX_AMOUNT itself is null
  • / 2 divides the result by 2

Example 2 — Multi-Currency Tax (Half Amount)

Goal: Show half the tax for INR or USD currencies; 0 for all others.

NULLTOZERO(CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, {{CURRENCY_CODE}} == "USD", {{USA_TAX_AMOUNT}}, 0)) / 2
  • Two condition/value pairs inside CASE: one for INR, one for USD
  • Final 0 is the else value for all other currencies
  • Wrapped in NULLTOZERO to guard against null fields

Example 3 — Multi-Currency Tax (Full Amount, No Null Guard)

Goal: Return the appropriate tax field per currency without dividing.

CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, {{CURRENCY_CODE}} == "USD", {{USA_TAX_AMOUNT}}, 0)

Use this form when null values are not a concern and the full amount is needed.

Example 4 — Single-Currency Tax (Full Amount, with Null Guard)

Goal: Return the INR tax amount or 0, null-safe.

CASE({{CURRENCY_CODE}} == "INR", {{TAX_AMOUNT}}, 0)

Example 5 — Concatenated Invoice Header Field

Goal: Combine two billing fields into a single header value.

CONCAT({{BILL_CLIENT_INVOICE_NUMBER}}, {{BILL_DOWN_FEE_NUMBER}})

→ Produces a merged invoice reference in the header column.

Example 6 — Tiered Billing Rate

Goal: Apply a higher rate for workers exceeding 40 hours, only in the US.

CASE({{COUNTRY}} == "US" && {{HOURS}} > 40, {{OVERTIME_RATE}}, {{STANDARD_RATE}})

Example 7 — Safe Full Name

Goal: Build a full name, treating null middle name as empty.

CONCAT({{FIRST_NAME}}, " ", NULLTOEMPTY({{MIDDLE_NAME}}), " ", {{LAST_NAME}})

7. Tips & Limitations

Topic Guidance
Field namesCase-sensitive. Always insert using the Data Field dropdown to avoid typos.
String literalsMust use double quotes: "INR", not 'INR'.
Null fieldsWrap optional numeric fields in NULLTOZERO() before arithmetic. Wrap optional text fields in NULLTOEMPTY() before string operations.
SUBSTRACTDAYS spellingThe function is named SUBSTRACTDAYS (one 'T'). Use the Function dropdown to insert it.
Division by zeroAvoid dividing by a field that could be 0. Guard with CASE: CASE({{DIVISOR}} != 0, {{VALUE}} / {{DIVISOR}}, 0)
Formula validationThe editor validates your formula on save. A red error means invalid syntax — check that all {{ }} references are complete.
Operator precedenceStandard math rules apply: * and / before + and -. Use parentheses to control evaluation order.
Header/Footer vs ColumnsHeader and Footer formula editors do not include the Custom Field Object toolbar button. Column formulas have access to the full toolbar.