Hi Team,
I am currently working on creatio mobile app and trying to get the list of roles that are being tagged to the current user in addBusinessRule.But I am not able to get it using Terrasoft.store.BaseStore.
I tried using Try catch block , the error message is empty. Can you please help me regarding this?

 

Terrasoft.sdk.Model.addBusinessRule("Activity", {
    name: "FieldForceActivityTypeRule",
    ruleType: Terrasoft.RuleTypes.Custom,
    triggeredByColumns: ["Type"],
    events: [Terrasoft.BusinessRuleEvents.Load],
    executeFn: function(record, rule, column, customData, callbackConfig, event) {
     var currentUser = Terrasoft.CurrentUserInfo.userId; 
      alert("currentUser: "+ currentUser);
    var modelName = "SysUserInRole";
    var store = Ext.create("Terrasoft.store.BaseStore", {
      model: modelName
    });
    var columns = ["SysRole", "SysUser"];
    var queryConfig = Ext.create("Terrasoft.QueryConfig", {
      modelName: modelName,
      columns: columns
    });
    var filtersConfig = {
      property: "SysUser",
      value: currentUser
    };
    store.setPageSize(Terrasoft.AllRecords);
    store.loadPage(1, {
      isCancelable: true,
      filters: Ext.create("Terrasoft.Filter", filtersConfig),
      queryConfig: queryConfig,
      callback: function(loadedRecords, operation, success) {
        if (success) {
          alert("success :"+ loadedRecords.length);
          for (var i = 0, ln = loadedRecords.length; i < ln; i++) {
            var record = loadedRecords[i];
            alert("i "+ record);
          }
        }
      },
      scope: this
    });
        Ext.callback(callbackConfig.success, callbackConfig.scope, [true]);
    }
});

 

 

 

Like 1

Like

1 comments

Hello,

 

First, you need to check if SysUserInRole and SysUser are syncing with the mobile app (correspondent records are present in the mobile application's manifest). Then check if you get any result at the callback function when you debug the code.

Show all comments

Hi Team,

 

We have a requirement for filtering the mobile application records in the freedom UI but we doesn't have the filter icon to filter the records. 
Please help us to solve the issues.

 

Note: We are using the updated mobile application version



Like 0

Like

2 comments

Hi Team,

Please help us solve the requirement.
 

Thanks,

Prem

 

Hello,
 

Unfortunately, fast filtering options on mobile devices are currently only available in Classic UI. We realize the importance of this feature and are actively working on implementing it in Freedom UI in future application releases.


Best regards,
Malika

Show all comments

Hi, i need to customize border, margin, and etc for customizing UI for my Application on Creatio Mobile, any info about how to customize border from text box, column, or detail on mobile creatio? 
Thanks

Like 1

Like

1 comments

Hello Aleksander,

Unfortunately, there is no possibility to customize the style for now.

Our R&D team is working on adding the different themes to the UI. Please follow the release updates.

Best regards,

Anhelina!

Show all comments

Hi, 

I have some hard times trying to iterate an array of object and insert/display the values one by one on this object detail named Product in Receive

 

and here is a chunk of the code:

var splitResult = decodedText
          .split("*")
          .filter((item) => item.trim() !== "");
        var doNumber = splitResult[0];
        var prodDataObj = [];
        var slocCode = doNumber.split("/")[1];
 
        for (let i = 1; i < splitResult.length; i++) {
          var prodDataSplit = splitResult[i].split("/");
          var productName = "";
          var materialcode = prodDataSplit[1] || "";
 
          if (materialcode) {
            productName = await new Promise((resolve) => {
              Terrasoft.productByMaterialCode(materialcode, (productData) => {
                if (productData && productData.Name) {
                  resolve(productData?.Name || "");
                }
              });
            });
          }
          prodDataObj.push({
            Line: prodDataSplit[0] || 0, //line number
            MaterialCode: prodDataSplit[1] || "", //mat code
            ProductName: productName,
            Quantity: prodDataSplit[2] || 0, //quantity
            UoM: prodDataSplit[3] || "", //uom
          });
        }
prodDataObj.forEach((data) => {
          const newRecord = Ext.create("Terrasoft.BaseModel", {
            modelName: "UsrEntity_93626c0",
          });
 
          newRecord.set("UsrSKUName", data.ProductName, true);
          newRecord.set("UsrQty", data.Quantity, true);
 
          Terrasoft.getUom(data.UoM, (record) => {
            newRecord.set("UsrUoM", record, true);
          });
 
          newRecord.save({
            isCancelable: false, 
            success: function (savedRecord) {
 
              const pageController = Terrasoft.PageNavigator.getLastPageController();
              pageController.refreshDirtyData();
            },
            failure: function (error) {
              console.error("Failed to create record:", error);
            },
          });
        });

i tried to iterate using forEach but when i use newRecord.save, some weird error appears, this is one of them: 

Error in Success callbackId: TSQueryExecutorPlugin1965367711 : TypeError: Cannot read properties of undefined (reading 'rule')

 

I would greatly appreciate any assistance or guidance in resolving this issue.
Thank you.

 

Like 1

Like

1 comments

Hello,
In this situation, only the full debug of the set code can tell what exactly went wrong. Based on the code alone it is impossible to tell where is the issue in it.
The error "TypeError: Cannot read properties of undefined (reading 'rule')" doesn't tell much easier, with it we can only tell that at some point the system didn't receive a correct parameter or didn't receive anything at all, either way, a debug is still needed.

Show all comments

Hi community , 

 

I find it a little difficult to figure out how to implement the freedom ui component configuration in my page, even if Creatio documentation lists it all:

 https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/mobile-development/customization/freedom-ui/customize-page/references/common-components

The "UsrMobileUsrLeaveRequestRecordPageSettingsWorkplace2" client module is attached to this mobile page for a custom section that I designed called "UsrLeaveRequest."
How do I proceed about adding a custom button to this edit page now? 

 

[
    {
        "operation": "insert",
        "name": "settings",
        "values": {
            "entitySchemaName": "UsrLeaveRequest",
            "details": [],
            "columnSets": [],
            "localizableStrings": {
                "SocialMessageDetailCaptionUsrLeaveRequest_caption": "Feed",
                "AttachmentsDetailCaptionUsrLeaveRequest_caption": "Attachments",
                "primaryColumnSetUsrLeaveRequest_caption": "General information",
                "UsrEmployeV2_DetailStandardDetailUsrLeaveRequest_caption": "Employees detail"
            },
            "settingsType": "RecordPage",
            "operation": "insert",
 
        }
    },
    {
        "operation": "insert",
        "name": "SocialMessageDetailV2StandardDetail",
        "values": {
            "caption": "SocialMessageDetailCaptionUsrLeaveRequest_caption",
            "entitySchemaName": "SocialMessage",
            "showForVisibleModule": true,
            "filter": {
                "detailColumn": "EntityId",
                "masterColumn": "Id"
            },
            "operation": "insert"
        },
        "parentName": "settings",
        "propertyName": "details",
        "index": 0
    },
    {
        "operation": "insert",
        "name": "AttachmentsFlutterDetailStandardDetail",
        "values": {
            "caption": "AttachmentsDetailCaptionUsrLeaveRequest_caption",
            "entitySchemaName": "SysFile",
            "filter": {
                "detailColumn": "RecordId",
                "masterColumn": "Id"
            },
            "operation": "insert"
        },
        "parentName": "settings",
        "propertyName": "details",
        "index": 1
    },
    {
        "operation": "insert",
        "name": "UsrEmployeV2_DetailStandardDetail",
        "values": {
            "caption": "UsrEmployeV2_DetailStandardDetailUsrLeaveRequest_caption",
            "entitySchemaName": "Employee",
            "filter": {
                "detailColumn": "Manager",
                "masterColumn": "UsrApplicant"
            },
            "detailSchemaName": "UsrEmployeV2_Detail",
            "operation": "insert"
        },
        "parentName": "settings",
        "propertyName": "details",
        "index": 2
    },
    {
        "operation": "insert",
        "name": "primaryColumnSet",
        "values": {
            "items": [],
            "rows": 1,
            "entitySchemaName": "UsrLeaveRequest",
            "caption": "primaryColumnSetUsrLeaveRequest_caption",
            "position": 0,
            "operation": "insert"
        },
        "parentName": "settings",
        "propertyName": "columnSets",
        "index": 0
    },
    {
        "operation": "insert",
        "name": "42d4b33c-f361-44d4-92cd-07e8db664fca",
        "values": {
            "row": 0,
            "content": "Leave Request No.",
            "columnName": "UsrLeaveReaquestNo",
            "dataValueType": 1,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 0
    },
    {
        "operation": "insert",
        "name": "0d5ca981-1558-4e4d-b1a2-2b2b9dbd422c",
        "values": {
            "row": 1,
            "content": "End Date",
            "columnName": "UsrEndDate",
            "dataValueType": 8,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 1
    },
    {
        "operation": "insert",
        "name": "2013f978-c87f-4896-96be-5383cfd044e3",
        "values": {
            "row": 2,
            "content": "Start Date",
            "columnName": "UsrStartDate",
            "dataValueType": 8,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 2
    },
    {
        "operation": "insert",
        "name": "266417d3-f847-4386-af45-2674e9e779bb",
        "values": {
            "row": 3,
            "content": "Applicant",
            "columnName": "UsrApplicant",
            "dataValueType": 10,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 3
    },
    {
        "operation": "insert",
        "name": "1655829d-ce75-476c-9350-ce2696ecbf6d",
        "values": {
            "row": 5,
            "content": "Reason",
            "columnName": "UsrReason",
            "dataValueType": 1,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 4
    },
    {
        "operation": "insert",
        "name": "9f677f71-3322-4e75-9938-69ca4e1c650f",
        "values": {
            "row": 6,
            "content": "Status",
            "columnName": "UsrStatus",
            "dataValueType": 10,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 5
    },
    {
        "operation": "insert",
        "name": "3d874029-b467-4d7b-9eb0-d2ebfbe20403",
        "values": {
            "row": 7,
            "content": "Working Days Count",
            "columnName": "UsrWorkingDaysCount",
            "dataValueType": 4,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 6
    },
    {
        "operation": "insert",
        "name": "bc0d7d7e-ffdf-44a5-98b3-0a10094341e2",
        "values": {
            "row": 4,
            "content": "Applicant.Manager",
            "columnName": "UsrApplicant.Manager",
            "dataValueType": 10,
            "operation": "insert"
        },
        "parentName": "primaryColumnSet",
        "propertyName": "items",
        "index": 7
    }
]

 

Like 0

Like

2 comments

Hello,
In order to add a button to a mobile page you need to modify the viewConfigDiff element. In your code it is missing, so you should add it manually in the "settings" element:

{
&nbsp; &nbsp; "operation": "insert",
&nbsp; &nbsp; "name": "settings",
&nbsp; &nbsp; "values": {
&nbsp; &nbsp; &nbsp; &nbsp; ---
&nbsp; &nbsp; &nbsp; &nbsp; "viewConfigDiff": "[]"
&nbsp; &nbsp; }
}

Here is an example of adding a new tab to the page:

"viewConfigDiff": "[{\"operation\":\"insert\",\"name\":\"LeadDecisionsPaths_Tab\",\"parentName\":\"Lead_Tabs\",\"propertyName\":\"items\",\"values\":{\"position\":2,\"text\":\"DecisionsPaths_Caption\",\"body\":{}}}]"

The button should be added similarly. 

Jimmy Meijon,

You can find an instruction on how to add a button and its logic in this article.

Show all comments

Anyone I want to ask how to create business rules in product in order mobile apps?

 

The case is when creating new orders in mobile apps then add product in order I want to make products that appear only products in the hardware category.

 

Can anyone help me to solve this case guys?

Thank you

Like 0

Like

1 comments

Hi anyone, this case solved with this code

Terrasoft.sdk.Model.addBusinessRule("OrderProduct", {
   ruleType: Terrasoft.RuleTypes.Filtration,
   events: [Terrasoft.BusinessRuleEvents.Load],
   triggeredByColumns: ["Product"],
   filters: Ext.create("Terrasoft.Filter", {
       modelName: "Product",
       property: "Category",
       value: "Hardware"
   })
});

Show all comments

Anyone can help me to enable live update data like in web application and implement in mobile app? or like Refresh button on the top right corner dashboard section at mobile app?

need to be implement in this preview page:

So the users didn't should click Back button and choose the record again. Thank you.

Like 2

Like

1 comments

Hello,

This community post regarding data refresh may be helpful to you.

Best regards,
Antonii.

Show all comments

Hello guys,

 

How to make the preview page of all sections in mobile apps readonly?

 


For example, when we open the opportunity section then we open one of the opportunity data, all fields that appear should be readonly. For now we can change the data without having to click the edit button, we should have to click the edit button first to edit the data.

 

Please help to solve the problem, thank you.

Like 3

Like

3 comments

Hi Agus Sulistiawan

If you want to make the mobile field read only, you can go for business rule on the client module it might be work.
For example:
If Name column filled in then Make it has read only.
 

Prem Kumar,

Hi Prem Kumar,

 

Yes, to make the field read-only, you can set business rules in the related client module.


But this is a different case, I want to make all fields in the preview page of mobile apps read-only. 

 

The question is, how to make all fields on the preview page of mobile apps read-only.

For anyone who wants to implement the case above, you can follow the guidelines at this link:

 

https://community.creatio.com/questions/mobile-app-hide-field-preview-page-and-show-edit-page

 

I have completed the case by following the guide

Show all comments

How can you set custom field e.g. UsrSecondType on Account as readonly in Mobile app with Freedom UI?

Like 0

Like

1 comments

If you go to Configurations and search for the object, open it on the left hand side you see business rules then you put conditions in a way where a field that is required is set to filled in and the field that you want read only select that. 


Here color is the field you want to make read only and Job number is a required filled. 

Show all comments

Hello, i want to ask about how to implement code on life cycle Initialized on Mobile Creatio. On Web version, i can use onInitiliazed function, but on mobile i didnt find any possible way to do so. 

In my case, i need to get current month everytime user open the page. 

Anyone can help? 

Like 0

Like

3 comments

Hello,

 

As was stated here, the analog of the onEntityInitialized method from the desktop version is the onLoadRecord method in the mobile application. It should be overridden in the Controller of the corresponded edit page of the mobile application. 

Oleg Drobina,

Hi Oleg Drobina, thanks for answer my question. 
Can i have example of onLoadRecord code, i still have no idea how to use it. 
Thanks

Yosua Aleksander Thanos, 

Hello! 

Here is an example of the controller for the PharmaMobileActivityEditPage, you may modify it according to your business task:

/* globals Activity: false */
/* globals ActivityCategory: false */
Terrasoft.LastLoadedPageData = {
	controllerName: "Terrasoft.configuration.controller.PharmaMobileActivityEditPage",
	viewXType: "fieldforceactivityeditpageview"
};
 
Ext.define("Terrasoft.configuration.controller.PharmaMobileActivityEditPage", {
	alternateClassName: "PharmaMobileActivityEditPage.Controller",
	extend: "FieldForceActivityEditPage.Controller",
 
	statics: {
		Model: Activity
	},
 
	/**
	 * @private
	 */
	createPromotedProducts: function(config) {
		var record = config.records.pop();
		if (!record) {
			Ext.callback(config.success, config.scope);
			return;
		}
		var product = record.get("Product");
		if (!product) {
			this.createPromotedProducts(config);
			return;
		}
		var failureFn = function(exception) {
			Ext.callback(config.failure, config.scope, [exception]);
		};
		var modelName = "ActivityPromProduct";
		var model = Ext.ClassManager.get(modelName);
		model.createWithDefaultValues(function(newRecord) {
			newRecord.set("Activity", config.activityId);
			newRecord.set("Product", product);
			newRecord.save({
				isCancelable: false,
				queryConfig: Ext.create("Terrasoft.QueryConfig", {
					modelName: modelName,
					columns: ["Activity", "Product"]
				}),
				success: function() {
					this.createPromotedProducts(config);
				},
				failure: failureFn
			}, this);
		}, failureFn, this, {isCancelable: false});
	},
 
	/**
	 * @private
	 */
	getPromotedProducts: function(config) {
		var filters = Ext.create("Terrasoft.Filter", {
			property: "Contact",
			value: config.contactId
		});
		var columns = ["Product"];
		Terrasoft.DataUtils.loadRecords({
			modelName: "PromotedProduct",
			filters: filters,
			columns: columns,
			success: function(records) {
				Ext.callback(config.success, config.scope, [records]);
			},
			failure: function(exception) {
				Ext.callback(config.failure, config.scope, [exception]);
			},
			scope: this
		});
	},
 
	/**
	 * @private
	 */
	createNosologiesByProducts: function(config) {
		var filters = Ext.create("Terrasoft.Filter", {
			property: "Product",
			funcType: Terrasoft.FilterFunctions.In,
			funcArgs: config.productIds
		});
		var failureFn = function(exception) {
			Ext.callback(config.failure, config.scope, [exception]);
		};
		Terrasoft.DataUtils.loadRecords({
			modelName: "NosologyInProduct",
			filters: filters,
			columns: ["Nosology"],
			success: function(records) {
				this.createNosologyInActivity({
					activityId: config.activityId,
					records: records,
					addedNosologies: [],
					success: function() {
						Ext.callback(config.success, config.scope);
					},
					failure: failureFn,
					scope: this
				});
			},
			failure: failureFn,
			scope: this
		});
	},
 
	/**
	 * @private
	 */
	createNosologyInActivity: function(config) {
		var record = config.records.pop();
		if (!record) {
			Ext.callback(config.success, config.scope);
			return;
		}
		var nosology = record.get("Nosology");
		var nosologyId = nosology ? nosology.getId() : null;
		if (nosologyId === null || Ext.Array.contains(config.addedNosologies, nosologyId)) {
			this.createNosologyInActivity(config);
			return;
		}
		var failureFn = function(exception) {
			Ext.callback(config.failure, config.scope, [exception]);
		};
		var modelName = "NosologyInActivity";
		var model = Ext.ClassManager.get(modelName);
		model.createWithDefaultValues(function(newRecord) {
			newRecord.set("Activity", config.activityId);
			newRecord.set("Nosology", nosology);
			newRecord.save({
				isCancelable: false,
				queryConfig: Ext.create("Terrasoft.QueryConfig", {
					modelName: modelName,
					columns: ["Activity", "Nosology"]
				}),
				success: function() {
					config.addedNosologies.push(nosologyId);
					this.createNosologyInActivity(config);
				},
				failure: failureFn
			}, this);
		}, failureFn, this, {isCancelable: false});
	},
 
	/**
	 * @private
	 */
	fillVisitToDoctorDetails: function(config) {
		var failureFn = function(exception) {
			Ext.callback(config.failure, config.scope, [exception]);
		};
		this.getPromotedProducts({
			contactId: config.contactId,
			success: function(promotedProducts) {
				this.createPromotedProducts({
					activityId: config.activityId,
					records: Ext.clone(promotedProducts),
					success: function() {
						var productIds = [];
						for (var i = 0, ln = promotedProducts.length; i &lt; ln; i++) {
							var productId = promotedProducts[i].get("Product.Id");
							if (productId) {
								productIds.push(productId);
							}
						}
						if (productIds.length === 0) {
							Ext.callback(config.success, config.scope);
							return;
						}
						this.createNosologiesByProducts({
							activityId: config.activityId,
							productIds: productIds,
							success: function() {
								Ext.callback(config.success, config.scope);
							},
							failure: failureFn,
							scope: this
						});
					},
					failure: failureFn,
					scope: this
				});
			},
			failure: failureFn,
			scope: this
		});
	},
 
	/**
	 * @inheritdoc
	 * @protected
	 * @overridden
	 */
	copyProductsFromAccount: function(config) {
		var activity = config.activity;
		var categoryId = activity.get("ActivityCategory.Id");
		if (categoryId === Terrasoft.Configuration.ActivityCategory.PharmacyVisit) {
			this.callParent(arguments);
		} else {
			Ext.callback(config.success, config.scope);
		}
	},
 
	/**
	 * @inheritdoc
	 * @protected
	 * @overridden
	 */
	onLoadRecord: function(record) {
		var detailConfig = this.getDetailConfig();
		if (record.phantom &amp;&amp; detailConfig &amp;&amp; record.get("Type.Id") === Terrasoft.Configuration.ActivityTypes.Visit) {
			var categoryId;
			switch (detailConfig.parentColumnName) {
				case "Account":
					categoryId = Terrasoft.Configuration.ActivityCategory.PharmacyVisit;
					break;
				case "Contact":
					categoryId = Terrasoft.Configuration.ActivityCategory.DoctorVisit;
					break;
				default:
					categoryId = null;
					break;
			}
			if (categoryId) {
				var activityCategory = ActivityCategory.Store.getById(categoryId);
				record.set("ActivityCategory", activityCategory);
			}
		}
		this.callParent(arguments);
		var pageHistoryItem = this.getPageHistoryItem();
		var rawConfig = pageHistoryItem.getRawConfig();
		if (rawConfig.focusColumn) {
			setTimeout(function() {
				var field = this.getFieldByColumnName(rawConfig.focusColumn);
				if (!field) {
					return;
				}
				if ("getPicker" in field) {
					var picker = field.getPicker();
					picker.show();
				} else {
					field.focus();
				}
			}.bind(this), 50);
		}
	},
 
	/**
	 * @inheritdoc
	 * @protected
	 * @overridden
	 */
	completeDataSaving: function() {
		var args = arguments;
		var record = this.record;
		var categoryId = record.get("ActivityCategory.Id");
		var contactId = record.get("Contact.Id");
		if (this.isNewVisit &amp;&amp; categoryId === Terrasoft.Configuration.ActivityCategory.DoctorVisit &amp;&amp; contactId) {
			var activityId = record.getPrimaryColumnValue();
			this.fillVisitToDoctorDetails({
				activityId: activityId,
				contactId: contactId,
				success: function() {
					var parent = Terrasoft.configuration.controller.PharmaMobileActivityEditPage.superclass;
					parent.completeDataSaving.apply(this, args);
				},
				failure: function(exception) {
					Terrasoft.Mask.hide({force: true});
					Terrasoft.MessageBox.showException(exception);
				},
				scope: this
			});
		} else {
			this.callParent(args);
		}
	},
 
	/**
	 * @inheritdoc
	 * @protected
	 * @overridden
	 */
	getCategoryId: function() {
		var activityRecord = this.record;
		var category = activityRecord.get("ActivityCategory");
		return category ? category.get("Id") : null;
	}
 
});
Show all comments