Print Form Service User Guide
Template Tab
To upload a form to the service, you need to be on the Template upload page

This page contains the following fields:
- Template Name – file name
- Data Collection method – type of collector and variable processing (JS Loader should be the default)
- Template File – path to the file to be uploaded
- SUBMIT button – uploads the specified file to the service database
After clicking submit, you will be redirected to the variable structure definition page for the form you just uploaded

The page contains the following fields:
- Template Name – file name
- Download Template – download the current uploaded template
- Replace File – upload and replace the current uploaded template
- Data Collection method – type of collector and variable processing (JS Loader should be the default)
- Text – editor for the variable and block structure of the form
In this editor, you can and should define/redefine variables and blocks
Example of Definition and Redefinition Structure
{
"generator": "libreoffice",
"variables": {
"totalDebtFormatted": "((contractBalance.all | arr_pick('inBalance.local') | arr_sum) + (contractBalance.all | arr_pick('outBalance.local') | arr_sum)) | float_format(2)"
},
"properties": {
"rows": [
[
"contractCalculatedSchedule.tranches._.number",
"contractCalculatedSchedule.tranches._.repaymentDate | date_format('DD.MM.YYYY')",
"contractCalculatedSchedule.tranches._.(principal + interest + eachRepaymentFee) | int_format",
"contractCalculatedSchedule.tranches._.principal | int_format",
"contractCalculatedSchedule.tranches._.interest | int_format",
"contractCalculatedSchedule.tranches._.eachRepaymentFee | int_format",
"contractCalculatedSchedule.tranches._.rest | int_format"
]
],
"blocks": {
"leaseBack": "contract.creditProductName includes 'LeaseBack'",
"leaseClassic": "contract.creditProductName includes 'Leasing classic'"
},
"emptyChar": "-",
"undefinedChar": "-"
}
}Most Important and Frequently Used Structure Sections
variables – here variables are redefined for quick access, allowing you to avoid editing the template with variables. It also simplifies the aesthetic appearance of the form template by replacing long variable references that are difficult to read within the template text.
For example, a long variable reference in the form template
${((contractBalance.all | arr_pick('inBalance.local') | arr_sum) + (contractBalance.all | arr_pick('outBalance.local') | arr_sum)) | float_format(2)}
Can be redefined as:
"totalDebtFormatted": "((contractBalance.all | arr_pick('inBalance.local') | arr_sum) + (contractBalance.all | arr_pick('outBalance.local') | arr_sum)) | float_format(2)" This variable retrieves the balance for all tranches (off-balance + on-balance)
and specified in the form template as ${totalDebtFormatted} Also, in the Text field editor, you can adjust the structure of this variable without editing the form template itself. For example, you can use conditions in variable redefinitions. "naturalPerson": "client.naturalperson && !client.businessman ? 'individual' : 'legal entity'"This variable outputs the text "individual" or "legal entity" depending on the values of the client.naturalperson and client.businessman variables
properties – defines variables in the form template that output a collection/list of data into a table (for example, a schedule or collateral properties) In this field, variables must be defined identically both in the form and in the field. The example above shows variable definitions for outputting a schedule into a form (template) table
Example of Table Filling for Outputting Planned Schedule from Contract
| # | Repayment Date | Payment Amount | Principal | Interest | Fees | Remaining |
|---|---|---|---|---|---|---|
${contractCalculatedSchedule.tranches._.number} | ${contractCalculatedSchedule.tranches._.repaymentDate | date_format('DD.MM.YYYY')} | ${contractCalculatedSchedule.tranches._.(principal + interest + eachRepaymentFee) | float_format} | ${contractCalculatedSchedule.tranches._.principal | float_format} | ${contractCalculatedSchedule.tranches._.interest | float_format} | ${contractCalculatedSchedule.tranches._.eachRepaymentFee | float_format} | ${contractCalculatedSchedule.tranches._.rest | float_format} |
${(contractCalculatedSchedule.tranches | arr_pick('principal') | arr_sum) + (contractCalculatedSchedule.tranches | arr_pick('interest') | arr_sum) + (contractCalculatedSchedule.tranches | arr_pick('eachRepaymentFee') | arr_sum)} | ${(contractCalculatedSchedule.tranches | arr_pick('principal') | arr_sum)} | ${(contractCalculatedSchedule.tranches | arr_pick('interest') | arr_sum)} | ${(contractCalculatedSchedule.tranches | arr_pick('eachRepaymentFee') | arr_sum)} |

blocks – defines blocks that will show or hide text (with or without variables) in the form template based on embedded conditions. Example
"blocks": {
"leaseBack": "contract.creditProductName includes 'LeaseBack'",
"leaseClassic": "contract.creditProductName includes 'Leasing classic'"
},or
"blocks": {
"block_person": "client.naturalperson && !client.businessman",
"block_company": "!client.naturalperson"
},- The first example checks whether the contract.creditProductName variable (containing the credit product name string) includes the phrase LeaseBack
- The second example checks the client type – individual or legal entity
Example of Block Usage

Uploaded Forms Table
- Toggle between active and inactive forms. Forms cannot be deleted, but they can be deactivated and restored.
- Navigate to PF performance analytics
- Navigate to the old variable collector page
- Archive button
- PF name column – contains links to the form variable structure editor page
- Loader type (JS-LOADER is the main one and will be the standard in the future)
- Main entities linked to the form
- Form update date/time

Test PrintForm Tab
Old variable collector and translator, there is a separate guide for it
Expressions Tab
Examples of data formatting (entities, numbering, strings, boolean data, arrays), detailed examples are on the tab itself
Used Variables Tab
List of variables and their combinations used in forms of the current customer. Each customer may have a very rich list of examples of using various variables in forms. A very convenient implementation to avoid browsing through forms and searching for what you need within the text.
Generations Tab
Shows sessions of generated forms and their processing speed.
Sandbox Tab
This tab is a sandbox where you can and should test and work out variable combinations. It also contains a built-in search for entities and variables. This page has fields for entering entity IDs. They are used to work with information contained in the database for any entity entered in the ID field.
Main Entities Requiring ID in Sandbox for Testing
Entity designations for working with variables and sandbox are shown in parentheses
- Leads (lead) – leads
- Clients (client) – clients
- LoanApps (loanApp) – loan applications
- Contracts (contract) – credit contracts
- Group of Signature Id (groupOfSignature) – signature groups
- Manager for Signature Id (managerForSignature) – manager (Credit Specialist)
- Share Contract (shareContract) - share contract
- Deposit Contract (deposit Contract) – deposit contract
- Group Agreements – group agreements, but there are no variables for them
- Collateral Line (collateralLine) – credit lines
- Fund transaction (fundTransaction) - cash flow
- On date – date in Financial Information (for viewing transaction information on a specific date)
Additional Entities (work when main entity IDs are filled)
FOR LEADS
leadRecurrentConsent \ clientRecurrentConsent – returns true\false consent for recurring debit (contained in Lanister) API link (https://flame-orangutan-1ed.notion.site/cc6badbca098498ea397663ff6219d66)
FOR CLIENTS
- clientRfmTerroristHistory – MVK variables
- clientRfmFreezeHistory – RFM variables
- clientRfmFromuHistory – FROMU variables
- client.contracts – list of all contracts by client
FOR LOAN APPLICATIONS
- loanAppFullCost – APR calculation for loan application
- loanAppSchedule – schedule for loan application
- loanAppInsurance – insurance for loan application
- loanAppStatuses – list of loan application statuses
- loanApp.calc – APR and schedule recalculation for loan application (without firstRepaymentDate, repaymentPlanDate)
- loanApp.calcExtraField – APR and schedule recalculation for loan application (without repaymentPlanDate and with contract.firstRepaymentDate extra field)
- loanApp.calcExtraField_HOTFIX - APR and schedule recalculation for loan application (with contract.firstRepaymentDate (required) and contract.repaymentPlanDate (optional) extra fields)
- loanApp.calcCollateralLine - APR and schedule recalculation for loan application for credit lines (with collateralLine.paymentDay = 0 and collateralLine.recalcGracePeriod = 5 extra fields for interestGracePeriod calculation)
- loanApp.calcSecondaryProduct - APR and schedule recalculation for loan application with SECONDARY credit product (without firstRepaymentDate, repaymentPlanDate)
- loanApp.calcExtraFieldSecondaryProduct - APR and schedule recalculation for loan application with SECONDARY credit product (without repaymentPlanDate and with contract.firstRepaymentDate extra field)
- loanApp.calcCollateralLineSecondaryProduct - APR and schedule recalculation for loan application with SECONDARY credit product (with collateralLine.paymentDay = 0 and collateralLine.recalcGracePeriod = 5 extra fields for interestGracePeriod calculation)
FOR CONTRACTS
- contractFullCost – APR calculation for contract
- contractEffectiveInterestRateAFN – Effective Interest Rate for Kazakhstan
- contractOperations – list of all operations performed on the contract
- contractBalance – contract balance (can interact with the On date field in the Sandbox tab to set the process date as in Financial Information)
- contractStatuses – list of contract statuses
- contractCalculatedSchedule – calculated planned schedule
- contractCompositeSchedule – composite planned schedule
- contractFactSchedule – actual schedule for issued contract
- contractCourtResolution – court case variables (if the contract is subject to a court decision)
- collateralTerminationRecord – variables for collateral detachment from contract (by contract ID)
- contractFundTransactions – list of cash flows for contract
- contract.calc – contract schedule and APR recalculation. Contains recalculated schedule (contract.calc.schedule)
FOR CREDIT LINE
- collateralLineOperations – list of credit line operations
- collateralLineEstimatedPaymentEarlyRepayment – credit line repayment calculation (early)
- collateralLineEstimatedPaymentRepayment – credit line repayment calculation (current)
- collateralLine.collaterals – list of collaterals for credit line
- collateralLine.loanApps – list of loan applications for credit line
- collateralLine.contracts – list of contracts for credit line
FOR CASH FLOW
- fundTransactionCashbox – list of cash flows for Kazakhstan microservice (Cashbox)
- fundTransaction.operations – list of operations contained in cash flow

Variable Search in Entities (Sandbox Tab)
In the field next to the Variables label, you need to enter the main or additional entity and view available variables by relevance (frequency of use). IMPORTANT!!! Before clicking SEND, make sure the entity ID you are working with is filled in (in the Expressions sandbox section)

You can also enter an entity in the Variables field itself (under the label), click the Send button, and view its structure (variable names, values, and types)

Important EXAMPLES for Working with Collections and Entity Arrays
array summation (contractCalculatedSchedule.tranches) by field (principal)
contractCalculatedSchedule.tranches | arr_pick('principal') | arr_sum| arr_pick('principal')- responsible for converting to an array by the specified field| arr_sum- calculates the sum by the field value that was previously formed into an arrayworking with conditions on a collection for table output Suppose you want to insert a dash if the eachRepaymentFee field equals zero In this example, there is an issue that when checking in the form, the field is already passed as a string, while in the sandbox as a number, it may not work correctly, you need to verify and notify the developer. Currently, it works this way.
contractCalculatedSchedule.tranches._.(eachRepaymentFee != '0') ? (eachRepaymentFee | float_format(2)) : '-'field summation for a specific array element
contractCalculatedSchedule.tranches._.(principal + interest + eachRepaymentFee) | float_formatcontractCalculatedSchedule.tranches.0.(principal + interest + eachRepaymentFee) | float_formatcalling an array element by subfield value Suppose you need to extract a value from a field in the first collateral in the list, where the subfield value is Model. This example demonstrates how to get the Model property and output its value.
loanApp.collaterals[0].collateralProperties[.collateralPropertyType.name == 'Model'].valueget balance sum by amount type ID
contractBalance.inBalance[.amountType.id == 101291] | arr_pick('inBalance.local') | arr_sumcurrent date
now() | date_format('DD.MM.YYYY')output collateral properties excluding specific properties
loanApp.collaterals[.collateralTypeId != 1017515 && .collateralTypeId != 121754]._.collateralType.nameloanApp.collaterals[.collateralTypeId == 1017515 || .collateralTypeId == 121754]._.collateralType.nameoutput values from extra fields
extraField(loanApp.collaterals[0].depositor, 'passport.managerKZ')
Example Expression – are IDs in the 'collateralTypeId' field across all collaterals
!((121754 || 1017515) in loanApp.collaterals | arr_pick('collateralTypeId'))
Calculating total fee amount (by rate and by amount)
contract.creditFieldReq.fees[.amountTypeId == 10129159][0].value + (contract.loanAmount * contract.creditFieldReq.fees[.amountTypeId == 10129161][0].value / 100) + contract.creditFieldReq.fees[.amountTypeId == 10129162][0].value
contract.creditFieldReq.fees[.amountTypeId == 10129159].value + (contract.loanAmount * contract.creditFieldReq.fees[.amountTypeId == 10129161].value / 100) + contract.creditFieldReq.fees[.amountTypeId == 10129162].value
Output either full name or legal entity organization name
"loanApp.collaterals[.collateralTypeId == 1017515 || .collateralTypeId == 121754]._.(depositor.naturalperson ? (depositor.lastName + ' ' + depositor.firstName + ' ' + depositor.patronymic) : depositor.title)",
contractFullCost APR
dates can be subtracted
date_diff∙ feat(js-loader): added date_diff (example: contract.issueDate | date_diff(contract.issuePlanDate); contract.issueDate | date_diff(contract.issuePlanDate, 'day'(unit), false(float)) (sttvld)
CARDS
lead.cardByToken
In template settings, specify in the format
Substituting loan application date into Financial Info date field
"overrideInputExpressions": {
"clientId": "loanApp.clientId",
"ondate": "ondate ? ondate : loanApp.creationDate | date_format('YYYY-MM-DD')"
}Output recurrent consent (Lanister address required)
clientRecurrentConsent
leadRecurrentConsentEXTRACT OVERDUE TRANCHES
contractBalance.all[.repaymentDate | date_format('U') <= now() | date_format('U')]._.inBalance.localOVERDUE START DATE
contractBalance.all[.repaymentDate | date_format('U') <= now() | date_format('U')][0].repaymentDate | date_format('DD MM YYYY')NUMBER OF OVERDUE DAYS
now() | date_diff((contractBalance.all[.repaymentDate | date_format('U') <= now() | date_format('U')][0].repaymentDate), 'days')