How to add multi-currency field
Glossary Item Box
Introduction
One of the common Creatio configuration tasks is adding a [Multi-currency field] control on a page. This control enables users to specify the currency when entering monetary sums. It also enables fixing the sum equivalent in the base currency specified in the system settings. The sum is automatically converted as per the exchange rate when the currency changes. Fig.1 displays a multi-currency field in the Creatio interface.
Fig. 1. Multi-currency field
To add a multi-currency field on an edit page:
1. Add 4 columns to the object schema:
- [Currency] lookup column
- [Exchange rate] column
- [Amount] column to store the total sum in the selected currency
- [Amount in the base currency] column to store the sum in the base currency
NOTE
The object schema should only contain one column – to store the total sum in the selected currency. The rest of columns can be virtual, unless the business task requires their values to be stored in the database. They can be determined as attributes in the view model schema.
2. Specify the following 3 modules as dependencies in declaring the view model class:
- MoneyModule,
- MultiCurrencyEdit,
- MultiCurrencyEditUtilities.
3. Connect the Terrasoft.MultiCurrencyEditUtilities mixin to the view model and initialize it in the init() overridden method.
4. Add a configuration object with the multi-currency field settings to the diff array of the edit page view model schema. In addition to common control properties, the values property must contain:
- primaryAmount – name of the column that contains the amount in the base currency
- currency – name of the column with reference to the currency lookup
- rate – name of the column that contains the currency exchange rate
- generator – control generator Specify MultiCurrencyEditViewGenerator.generate for a multi-currency field.
5. Add logic for recalculating the sum according to the currency. Apply the calculated field mechanism, as described in the Adding calculated fields article.
Case description
Add a multi-currency [Amount] field on the project edit page.
Source code
You can download the package with case implementation using the following link.
Case implementation algorithm
1. Add the necessary columns to the object replacing schema
Create the replacing schema of the [Project] object in the custom package (Fig. 2). More information about creating a replacing object and adding columns is available in the “Adding a new field to the edit page” article.
Fig. 2. Properties of the object replacing schema
Add 4 columns with properties (see Fig. 3 – Fig. 6) to the replacing schema. Column properties in the Object Designer are displayed in the extended mode.
Fig. 3. The [UsrCurrency] column properties
Fig. 4. The [UsrAmount] column properties
Fig. 5. The [UsrPrimaryAmount] column properties
Fig. 6. The [UsrCurrencyRate] column properties
To the [UsrCurrency] column, add the default value – the [Base currency] system setting (Fig.7).
Fig. 7. The default value for the [UsrCurrency] column
2. Create a project replacing edit page in custom package
Create a replacing client module and specify the [Project edit page], ProjectPageV2 schema as its parent object (Fig. 8). The procedure of creating a replacing page is covered in the “Creating a client schema” article.
Fig. 8. Properties of the [Projects] replacing edit page
Add the following modules as dependencies when declaring view model class: MoneyModule, MultiCurrencyEdit, MultiCurrencyEditUtilities (see the source code below).
3. Add the necessary attributes
Specify the UsrCurrency, UsrCurrencyRate, UsrAmount and UsrPrimaryAmount attributes that correspond to the added columns of the object schema in the attributes property of the edit page view model schema.
The multi-currency module operates only with the Currency column, so in addition you need to create a Currency attribute and declare a virtual column in it. Connect this column wit the previously created UsrCurrency column via a handler method.
To ensure the correct operation of the multi-currency module, add the CurrencyRateList (currency rate collection) and CurrencyButtonMenuList (collection for the button of selecting the currency) attributes (see the source code below).
5. Connect the Terrasoft.MultiCurrencyEditUtilities mixin to the view model
Declare the Terrasoft.MultiCurrencyEditUtilities mixin in the mixins property of the page view model schema. Initialize it in the init() overridden method of the view model schema (see the following code below).
6. Implement the recalculation logic according to the currency
Add handler methods of the attribute dependencies in the methods collection of the page view model schema (see the following code below).
7. Add the multi-currency field on the page
Add the configuration object with the multi-currency field settings to the diff array of the edit page view model schema.
The replacing schema source code is as follows:
// Specify modules as dependencies // MoneyModule, MultiCurrencyEdit and MultiCurrencyEditUtilities. define("ProjectPageV2", ["MoneyModule", "MultiCurrencyEdit", "MultiCurrencyEditUtilities"], function(MoneyModule, MultiCurrencyEdit, MultiCurrencyEditUtilities) { return { // Name of the edit page object schema. entitySchemaName: "Project", // Attributes of the view model. attributes: { // Currency. "UsrCurrency": { // Attribute data type is a lookup. "dataValueType": this.Terrasoft.DataValueType.LOOKUP, // Configuration of the lookup. "lookupListConfig": { "columns": ["Division", "Symbol"] } }, // Exchange rate. "UsrCurrencyRate": { "dataValueType": this.Terrasoft.DataValueType.FLOAT, // Attribute dependencies. "dependencies": [ { // Columns on which the attribute depends "columns": ["UsrCurrency"], // Handler method. "methodName": "setCurrencyRate" } ] }, // Amount. "UsrAmount": { "dataValueType": this.Terrasoft.DataValueType.FLOAT, "dependencies": [ { "columns": ["UsrCurrencyRate", "UsrCurrency"], "methodName": "recalculateAmount" } ] }, // Amount in base currency. "UsrPrimaryAmount": { "dependencies": [ { "columns": ["UsrAmount"], "methodName": "recalculatePrimaryAmount" } ] }, // Currency is a virtual column for compatibility with the MultiCurrencyEditUtilities module. "Currency": { "type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, "dataValueType": this.Terrasoft.DataValueType.LOOKUP, "lookupListConfig": { "columns": ["Division"] }, "dependencies": [ { "columns": ["Currency"], "methodName": "onVirtualCurrencyChange" } ] }, // Currency rate collection "CurrencyRateList": { dataValueType: this.Terrasoft.DataValueType.COLLECTION, value: this.Ext.create("Terrasoft.Collection") }, // Collection for the currency button menu "CurrencyButtonMenuList": { dataValueType: this.Terrasoft.DataValueType.COLLECTION, value: this.Ext.create("Terrasoft.BaseViewModelCollection") } }, // View model mixins. mixins: { // Mixin that controls multicurrency on the edit page. MultiCurrencyEditUtilities: "Terrasoft.MultiCurrencyEditUtilities" }, // Methods of the page view model methods: { // Overriding the Terrasoft.BasePageV2.onEntityInitialized() basic method. onEntityInitialized: function() { // Calling the parent implementation of the onEntityInitialized method. this.callParent(arguments); this.set("Currency", this.get("UsrCurrency"), {silent: true}); // Initialization of the mixin controlling the multi-currency. this.mixins.MultiCurrencyEditUtilities.init.call(this); }, // Sets the exchange rate. setCurrencyRate: function() { //Loads the exchange rate at the beginning of the project. MoneyModule.LoadCurrencyRate.call(this, "UsrCurrency", "UsrCurrencyRate", this.get("StartDate")); }, // Recalculates the amount. recalculateAmount: function() { var currency = this.get("UsrCurrency"); var division = currency ? currency.Division : null; MoneyModule.RecalcCurrencyValue.call(this, "UsrCurrencyRate", "UsrAmount", "UsrPrimaryAmount", division); }, // Recalculates the amount in base currency. recalculatePrimaryAmount: function() { var currency = this.get("UsrCurrency"); var division = currency ? currency.Division : null; MoneyModule.RecalcBaseValue.call(this, "UsrCurrencyRate", "UsrAmount", "UsrPrimaryAmount", division); }, // The handler of the currency virtual column change. onVirtualCurrencyChange: function() { var currency = this.get("Currency"); this.set("UsrCurrency", currency); } }, // Setting up the visualization of a multi-currency field on the edit page. diff: /**SCHEMA_DIFF*/[ // Metadata for adding the[Amount] field. { // Adding operation. "operation": "insert", // The meta-name of the parent container to which the component is added. "parentName": "Header", // The field is added to the collection of the // parent container. "propertyName": "items", // The meta-name of the schema component above which the action is performed. "name": "UsrAmount", // Properties passed to the constructor of the component. "values": { // The name of the column of the view model to which the binding is performed. "bindTo": "UsrAmount", // Element location in the container. "layout": { "column": 0, "row": 2, "colSpan": 12 }, // The name of the column that contains the amount in the base currency. "primaryAmount": "UsrPrimaryAmount", // The name of the column that contains the currency of the amount. "currency": "UsrCurrency", // The name of the column that contains the exchange rate. "rate": "UsrCurrencyRate", // The property that defines whether the amount field is enabled and editable in the base currency. "primaryAmountEnabled": false, // Generator of the control view. "generator": "MultiCurrencyEditViewGenerator.generate" } } ]/**SCHEMA_DIFF*/ }; });
After saving the schema and updating the application page the [Amount] multi-currency field will be displayed on the project edit page (Fig .1). The value of the field will be automatically recalculated after selecting a currency from the drop-down list (Fig. 9).
Fig. 9. Drop-down list of currencies