Skip to main content

Creating Print Template in MS Word

Use cases or methods for creating conditions (placeholders) in Word document templates for the Fintin document generator via the MS Word plugin.

Technical Note

The condition syntax is very sensitive to changes and does not accept all conditions (e.g., from JavaScript). You must strictly follow the presented formats, as even minor modifications can cause improper generator operation and consequently errors when generating prints.

Basic Functionalities

Iterating Through Lists

When you want to display data from a list of objects, use a section starting with {#listName} and ending with {/listName}. Within this section, you can refer to the fields of each object in the list.

Basic Example:

{#supplier.addresses}
{city}
{/supplier.addresses}

Description: This code goes through all supplier addresses and displays the city name for each of them. If the supplier has 3 addresses, 3 city names will appear in the document, each on a new line.

Advanced Example with Nested Lists:

{#account.representatives}
{#addresses [loopOver: "content"]}
{#type.key=="HQ"}
{city}
{/}
{/addresses}
{/account.representatives}

Description: This code goes through all account representatives, then through their addresses and displays the city only for those addresses marked as headquarters (HQ). Practically - if a company has several representatives in different cities, it will show only cities where headquarters are located.

Conditional Data Display

To conditionally display content, use the format {#condition}content{/}. The fragment will be displayed only when the condition is met.

Example:

{#type.key=="S"}
{city}
{/}

Description: This code checks if the address type is "S" (e.g., business address) and only then displays the city name. If the address is not of type "S", the city will not appear in the document at all.

Ternary Conditions (Alternative Display)

To display one of two values depending on a condition, use the syntax: {condition ? valueIfTrue : valueIfFalse}

Examples:

{application.isPartnerInsurance==true ? "Yes" : "No"}

Description: Checks if partner insurance was selected in the application. If yes, it will display "Yes", if not - it will display "No". Useful for clearly marking customer choice in the document.

{application.assets.length > 1 ? "ITEMS" : "ITEM"}

Description: Checks how many items are in the application. If more than one, it will display "ITEMS" (plural), if one or zero - it will display "ITEM" (singular). Ensures correct grammar in the document.

Advanced Operations

Data Extraction with Filters

For complex filtering and retrieving specific data, use the expression:

Extracting headquarters address:

{#case.application.parties [expression: "value.filter(el => (el.roles || []).find(r => r.key == 'APPLICANT')).flatMap(p => p.addresses || []).filter(address => (address.types || []).find(type => type.key == 'HQ'))"]}{prefix} {street} {buildingNumber}{premises ? '/' + premises : ''}, {postcode} {city}, {country.value}{/}

Description: This code finds the applicant in the case, then among all their addresses selects only the headquarters address (HQ) and displays it in full format with street, building number, postal code, city and country. If there are premises, it adds them after a slash. Useful for automatically inserting company address into contracts.

Complex Conditions with Multiple Filters

Filtering with multiple conditions:

{#case.application.parties [expression: "value.filter(el =>(el.roles || []).find(r => r.key == 'ASSIGNEE'))"]}
{#personInCompany [expression: "value.filter(el =>(el.roles || []).find(r => r.key == 'RE'))"]}
{fullName}
{/personInCompany}
{/case.application.parties}

Description: This code finds the assignee (person/company to whom rights were transferred) in the case, then among people in this company selects the legal representative (RE) and displays their full name. Useful in documents where you need to indicate a specific person authorized to act.

Condition with legal form verification:

{#case.application.parties [expression: "value.filter(el =>(el.roles || []).find(r => r.key == 'ASSIGNEE') && el.legalForm?.key == '001')"]}
{fullName}
{/case.application.parties}

Description: This code finds the assignee, but only if they have a specific legal form (code '001' - e.g., LLC) and displays their full name. Used when different legal forms require different treatment in documents.

Data Operations

Number Formatting

Basic number formatting:

{calculation.ownContribution.net | numberFormat}

Description: This code gets the own contribution amount (net) from the calculation and formats it according to Polish standards - adds spaces as thousand separators (e.g., 123 456.78 PLN). Useful for displaying monetary amounts in readable form.

Advanced formatting with thousand separators:

{case.application.offer.mileage [module: "Script", function: "evaluate", expression: "Number.isInteger(value) ? value.toLocaleString('pl-PL').replace(/\\u00A0/g, ' ') : (Math.floor(value).toLocaleString('pl-PL').replace(/\\u00A0/g, ' ') + '.' + Math.round((value - Math.floor(value)) * 100).toString().padStart(2, '0'))" ]}

Description: This code formats vehicle mileage from the offer. If mileage is a whole number (e.g., 50000), it displays it with thousand separators (50 000). If it has a decimal part, it displays it with 2 decimal places precision (e.g., 50 000.25). Ensures uniform mileage formatting in documents.

Mathematical Operations

Summing values from a list:

{case.application.parties [module: "Script", function: "evaluate", expression: "(value || []).map(el => el.invoiceNetValue || 0).reduce((a, b) => a + b, 0)" ]}

Description: This code goes through all case participants, gets the net value of their invoices and sums them. If someone doesn't have an invoice, it treats it as 0. The result is the total value of all net invoices. Useful for calculating total costs in a case.

Variable Management

Setting Local Variables

You can create local variables to store data that will be used in various places in the template:

Setting a variable:

{case [module: "Script", function: "set", variable: "partiesUsers", expression: "value.parties"]}

Description: This code creates a "partiesUsers" variable and saves all case participants in it. Useful when you want to repeatedly refer to the same list of participants in different places in the document, without having to retrieve data each time.

Using the variable:

{#partiesUsers [expression: "value?.filter(el => el?.role == 'APPLICANT')"]}{firstName}{/partiesUsers}

Description: This code uses the previously saved "partiesUsers" variable, filters only applicants and displays their first names. Thanks to using the variable, the code is more readable and efficient.

Practical example with counting guarantors:

{case [module: "Script", function: "set", variable: "guarantorNumber", expression: "(value.application.parties || []).filter(el => (el.roles || []).some(r => r.key == 'GUARANTOR')).length"]}

{#guarantorNumber=="ONLINE"}No guarantor{/guarantorNumber}
{#guarantorNumber==1}There is one guarantor{/guarantorNumber}
{#guarantorNumber==2}There are two guarantors{/guarantorNumber}

Description: This code first counts how many guarantors are in the case and saves the number to a variable. Then it checks this number and displays the appropriate message: "No guarantor", "There is one guarantor" or "There are two guarantors". Useful for automatically generating case status descriptions.

Operations on Arrays and Objects

Saving strings to an array:

{attachments [module: "Script", function: "set", variable: "attachmentsData", expression: "value.map(num => Object.fromEntries([['key', num]]))"]}

{#attachmentsData}{key}{/attachmentsData}

Description: This code transforms the list of attachments into a special data structure where each attachment has a "key" field. Then it goes through this structure and displays values. Useful for creating attachment lists in a specific format.

Saving objects to a variable:

{accounts [module: "Script", function: "set", variable: "account", expression: "value?.[0]"]}

Description: This code gets the first element from the account list and saves it to the "account" variable. Useful when multiple accounts are assigned to a case, but in the document you need to refer only to the first (main) account.

Special Functionalities

Barcode Generation

The system supports barcode generation based on model data:

From model: barcodeNumber
Encoding: code-2of5 interleaved

Description: This functionality allows automatic barcode insertion into the document based on the number saved in the case. The barcode is generated in the "code-2of5 interleaved" standard, which is often used in logistics and warehousing. Useful for shipping documents, labels or invoices.

Best Practices

  1. Maintain exact syntax - the generator is very sensitive to syntax errors
  2. Test conditions - always check condition operation on sample data
  3. Use variables - for complex operations save results to local variables
  4. Document templates - describe complicated conditions with comments in the document
  5. Check data types - make sure you're comparing appropriate value types
  6. Hide conditions in document - select text with condition and use Ctrl+D (Windows) or Cmd+D (Mac) shortcut, then choose "Hide" option. This way conditions won't be visible in the final document, but will work during generation
  7. Write conditions in one line - avoid using Enter key inside conditions. The entire condition should be written in one line without breaks, so the system can interpret it correctly
Tip

Before implementing complex conditions in the template, test them on smaller data fragments to ensure they work properly.