Hi Community,

 

We need user to have a permission to access organizational roles and functional roles section. They will have permission to add/remove user for each organizational roles and functional roles. How can we achieve this? Thanks

Like 0

Like

1 comments

Hi Fulgen,

 

Thank you for your question!

 

For a user to be able to manage organizational and functional roles - he should be given CanManageAdministration and CanManageUsers operation permissions.

 

Best regards,

Anastasiia

Show all comments

Hi, 

 

I have this test code in source code schema, 

 

How can I call this In script task?

 

Thanks

 

Like 0

Like

4 comments

Hi Akshit,

 

Create an instance of your Example class and call the Execute method in the script task. For example study how the CreateReminding method is called in the "Push notification" script task of the OOB "Push expired licenses notification" business process.

 

Best regards,

Oscar

Oscar Dylan,

 

Thank you for the response, 



This is the code below : 

 

This is how I am calling it : 

 

But when I run the business process this is the error I am getting : 

 

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified

 

 

Can anyone please help me what should I do next ?

 

Thanks!

Akshit,

 

Most probably you haven't added Terrasoft.Configuration namespace as a using in your process as well as System.Threading.Tasks. Additionally to it I cannot see creating an instance of the Example class in your script task code.

 

Best regards,

Oscar

I have added the following : 

 

But still gettting the same issue?

 

From the error I get this as resolution https://github.com/box/box-windows-sdk-v2/issues/225#issuecomment-277012542  

 

But didn't understand what exactly I have to do? Like which assembly(dll file) I need to place in creatio?

Show all comments

Hi Team,

 

From the day I have started development on one of the trial instance I have set "Current package" system setting to my package, but I see after some time objects started reflecting in custom package.

 

I want ask :

 

1. Is there any other system setting (other than "Current Package" ) which is required to change ?

2. Is this the reason that If there are more than one users (system admin) involved in development.

 

Please tell me what could be the possible reason ? And does it create any major issue during data binding?

 

Thanks!

Like 0

Like

2 comments

Hello Akshit, 



We are not able no to say, why the current package value has changed. 



Before starting the development we recommend you to check:

1. 'Current package' System setting value

2.  Check whether the package is unlocked (you are able to change the object configuration for example) 



We strongly recommend using the development website only for one user to avoid such issues. 

 

Best regards,

Bogdan

Bogdan,

 

Thank you for you response, related to point number 2, I want to ask 

that whenever we create our custom package (VirtuosRefac_version_1) then by default it is marked as locked (please see the below image) then how to unclock it?

 

Thanks!

Show all comments

Hi community,

 

How do you make a link (string field) a hyperlink in a mini-page? It is displayed as a label (https://academy.creatio.com/api/jscoreapi/7.15.0/index.html#!/api/Terra…) but there is no "showValueAsLink" property like in a text field in a page.



And how can I create a field that has the same behaviour as the email field in the default contact page? I have a "linkedin" field that I need to sync with the communication option (which has a linkedin field added under "website") and I need to sync it with the same behaviour as the email field (which takes the main email in the communication option, automatically adds a new email or updates it etc.).

 

Best regards,

 

Julien

Like 0

Like

7 comments

Hi Julien,

 

As for your first question - it's not clear which string-link field on the mini page you are refering to. I hope this community post where a similar question was asked will be useful - https://community.creatio.com/questions/convert-text-field-hyperlink.

 

As for your second question - the logic behind the email column is stored in the BaseCommunication and ContactCommunication objects in the Base package (processes on these objects). You need to study how the logic is declared there.

 

Best regards,

Oscar

Oscar Dylan,

 

Thank you for your answer, about my first question I mean a mini page that shows when you hover on a record :

 

I need to change a field that shows on the minipage to a link (with target _blank). On a page directly I can use a "ShowAsLink" attribute, but the component on a minipage that shows a text field is a label, which don't have a "ShowAsLink" attribute.

 

Thank you for your answer on the second question, I'll dig into the Base Package.

 

Best regards,

 

Julien Gunther

Julien Gunther,

 

This minipage is a "view" type minipage for the section that is used as a lookup reference. So you need to create the same logic described in the community post I shared above for the field on that minipage.

 

Best regards,

Oscar

Oscar Dylan,

 

The text field is rendered as a label, and it throw me this error :

Uncaught Object { message: "Property showValueAsLink is not defined in class Terrasoft.controls.Label" }

 

here is my diff :

			{
				"operation": "insert",
				"name": "Linkedin889ba056-f389-4852-a0f2-b5f8caede729",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 10,
						"layoutName": "MiniPage"
					},
					"isMiniPageModelItem": true,
					"visible": {
						"bindTo": "isViewMode"
					},
					"bindTo": "Linkedin",
					"showValueAsLink": true,
					"controlConfig": {
						"enabled": true,
						"href": {
							"bindTo": "getLinkedin"
						},
						"linkclick": {
							"bindTo": "onExternalLinkClick"
						}
					}
				},
				"parentName": "MiniPage",
				"propertyName": "items",
				"index": 13
			},

and the methods :

		methods: {
			getLinkedin: function() {
				return this.getLink(this.get("Linkedin"));
			},
			onExternalLinkClick: function() {
				return;
			},
			getLink: function(value) {
				if (Terrasoft.isUrl(value)) {
					return {
						url: value,
						caption: value
					}
				}
			}
		},

Best regards,

 

Julien Gunther

Julien Gunther,

 

Ok, we can do it in another way. We can create a virtual column, populate it with the value from the main record and display it not as a label in the minipage, but as a string field. For example using the code below (was added to the ContactMiniPage in my case):

define("ContactMiniPage", [], function() {
	return {
		entitySchemaName: "Contact",
		attributes: {
			"LinkedIn": {
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"value": ""
			}
		},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				var linkedInValue = this.get("UsrLinkedIn");
				this.set("LinkedIn", linkedInValue);
			},
			getLinkedInLink: function() {
				return this.getLink(this.get("LinkedIn"));
			},
			getLink: function(value) {
				if (Terrasoft.isUrl(value)) {
					return {
						url: value,
						caption: value
					};
				}
			},
			onLinkedInLinkClick: function() {
				return;
			},
		},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "LinkedIn",
				"values": {
					"showValueAsLink": true,
					"controlConfig": {
						"href": {
							"bindTo": "getLinkedInLink"
						},
						"linkclick": {
							"bindTo": "onLinkedInLinkClick"
						}
					},
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 11
					},
					"caption": {
						"bindTo": "Resources.Strings.LinkedIn"
					},
					"bindTo": "LinkedIn",
				},
				"parentName": "MiniPage",
				"propertyName": "items",
				"index": 5
			},
			{
				"operation": "merge",
				"name": "HeaderContainer",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 0
					}
				}
			},
			{
				"operation": "merge",
				"name": "TimezoneMiniContactPage",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 9
					}
				}
			},
			{
				"operation": "merge",
				"name": "JobInfoContainer",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 10
					}
				}
			},
			{
				"operation": "move",
				"name": "JobInfoContainer",
				"parentName": "MiniPage",
				"propertyName": "items",
				"index": 2
			},
			{
				"operation": "merge",
				"name": "Name",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 1
					}
				}
			},
			{
				"operation": "merge",
				"name": "Type",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 2
					}
				}
			},
			{
				"operation": "merge",
				"name": "Account",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 3
					}
				}
			},
			{
				"operation": "merge",
				"name": "JobTitle",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 4
					}
				}
			},
			{
				"operation": "merge",
				"name": "Department",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 5
					}
				}
			},
			{
				"operation": "merge",
				"name": "MobilePhone",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 6
					}
				}
			},
			{
				"operation": "merge",
				"name": "Email",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 7
					}
				}
			},
			{
				"operation": "remove",
				"name": "OwnerEdit"
			},
			{
				"operation": "remove",
				"name": "Owner"
			},
			{
				"operation": "remove",
				"name": "OwnerButtonContainer"
			},
			{
				"operation": "remove",
				"name": "OwnerCallButton"
			},
			{
				"operation": "remove",
				"name": "OwnerEmailButton"
			}
		]/**SCHEMA_DIFF*/
	};
});

As a result I received a clickable linkedin field in the view-minipage:

Hope it will work in your case as well.

 

Best regards,

Oscar

Oscar Dylan,

 

I still have the same error :

Uncaught Object { message: "Propriété showValueAsLink is not defined in class Terrasoft.controls.Label" }

 

Here is my code :

define("MTF_Candidat1MiniPage", [], function() {
	return {
		entitySchemaName: "MTF_Candidat",
		attributes: {
			"LinkedinVirtual": {
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"value": ""
			}
		},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.set("LinkedinVirtual", this.get("UsrLinkedin"))
			},
			getLinkedinLink: function() {
				return this.getLink(this.get("LinkedinVirtual"));
			},
			onExternalLinkClick: function() {
				return;
			},
			getLink: function(value) {
				if (Terrasoft.isUrl(value)) {
					return {
						url: value,
						caption: value
					}
				}
			}
		},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[
			// other items in diff ....
			{
				"operation": "insert",
				"name": "Linkedin889ba056-f389-4852-a0f2-b5f8caede729",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 10,
						"layoutName": "MiniPage"
					},
					"caption": "Linkedin",
					"isMiniPageModelItem": true,
					"bindTo": "LinkedinVirtual",
					"showValueAsLink": true,
					"controlConfig": {
						"href": {
							"bindTo": "getLinkedinLink"
						},
						"linkclick": {
							"bindTo": "onExternalLinkClick"
						}
					}
				},
				"parentName": "MiniPage",
				"propertyName": "items",
				"index": 39
			}
		]/**SCHEMA_DIFF*/
	};
});

"isMiniPageModelItem" is a required attribute, if set to false or removed it raise this error:

Uncaught Object { message: "DataValueType.null is not supported" }

 

Do you have another solution ?

 

Best regards,

 

Julien

 

 

Julien Gunther,

 

Your error comes from some place that is not present in the code I shared. Everything is working on my end, please perform an absolutely same setup.

 

Best regards,

Oscar

Show all comments

HI, 

 

I'm working with a business process, I have added a "Perfom Task" element, but I need to be able to set a custom parameter to it. The field already exists in the activity, but I'm not able to set it from them "Perfom Task" element.

 

Is there a way to do this?

Like 0

Like

2 comments

Hello Javier,



Could you please specify which custom parameter do you mean?



Thanks in advance!



Best regards,

Bogdan

Hi Bodgan, I have figured it out. 

 

I added this code in "Advace settings" -> "After save" of "Perfom Task" element:

 

 activity.SetColumnValue("[FieldName]", [FieldValue]));

  activity.Save();

 

 

 

Thank you!

Show all comments

Hello,

when you send emails from creatio the sender is always shown at the top of the record (here John Best):

it would make more sense, if the recipients of the emails were shown at this place.

Is that possible?

 

For incoming emails that is fine but for outgoing email it would be better to show the recipients here.

 

BR

Like 0

Like

1 comments

Hello,

 

I've created a logic that will display recipients specified in the "To" field of the email. Here is how it looks like on my end:

To achieve this I've performed the following steps:

 

1) Created a replacing view module in configurations and selected EmailItemSchema as a parent module:

2) Added the following code there (the implementation was created using the email body as an analog):

define("EmailItemSchema", ["BusinessRuleModule", "EmailConstants"], function(BusinessRuleModule, EmailConstants) {
	return {
		entitySchemaName: EmailConstants.entitySchemaName,
		methods: {
			getRecipients: function() {
				var recipientsList = this.get("Recepient");
				return "Recipients: " + recipientsList;
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "RecipientsContainer",
				"parentName": "EmailMessage",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"items": []
				}
			},
			{
				"operation": "insert",
				"parentName": "RecipientsContainer",
				"propertyName": "items",
				"name": "RecipientsText",
				"values": {
					"itemType": Terrasoft.ViewItemType.LABEL,
					"caption": {bindTo: "getRecipients"},
					"classes": {
						"labelClass": ["message-email-text"]
					},
				}
			},
		]/**SCHEMA_DIFF*/,
		rules: {}
	};
});

3) Refresh the page

 

You can use the example above to develop your own logic if needed.

 

Best regards,

Oscar

Show all comments

Hello Community!

I want to save a record on button click. How is this done from the front-end. What is the line of code that I am missing. Best Regards!

Like 0

Like

6 comments
Best reply

Petrika,

 

It doesn't save the record since the click event is handled not by the onCardAction method, but by your custom one:

click": {
						"bindTo": "onGenerateReferencePriceClick"
					},

According to your need you can use another approach of saving a record: you can call the save function directly (save method parent implementation can be found in the BaseEntityPage module):

this.save();

just add it at the beginning of the code for your button click handling.  And also you can execute methods synchronously using Terrasoft.chain method (an example of the usage can be found in this community post).

 

Best regards,

Oscar

Hi Petrika,

 

Please study the logic of the SaveRecordButton element in the BaseDataView module and the logic of the onCardAction method and the "save" tag of the button and apply the same logic to your button.

 

Best regards,

Oscar

Oscar Dylan,

Dear Oscar!

I have added the save tag , in the button diff ( image below )

I am uncertain of the lines of code I have to put in the body of the Method, that the button calls(image below)

Your help is much appreciated Oscar! Thank you

Petrika,

 

Simply add:

"tag": "save",
"markerValue": "SaveButton",
...
"click": {
						"bindTo": "onCardAction"
					}

To your button "values" and refresh the page. This will do the trick.

 

Best regards,

Oscar

Oscar,

Still Its not working.

I will give a full explanation of the problem.

I have created a button Generate Reference Price (marked with Red), which calls a web-service that populates the Collateral Price indicator detail(marked with yellow).

In the moment That I click the Generate Reference Price button i want that the information entered in the page is saved (just like clicking the Save button marked with brown). You can get a better understanding from the image below.

This is the code from the button

"operation": "insert",
				"name": "FzGeneratePrecalButton",
				"values": {
					"itemType": 5,
					"style": "blue",
					"id": "74a20850-7021-4e0a-a2e6-98bdc419f323",
					"tag": "save",
					"markerValue": "SaveButton",
					"caption": "Generate Reference Price",
                     ...
					"click": {
						"bindTo": "onGenerateReferencePriceClick"
					},
					"visible": {
						"bindTo": "FZButtonVisible"
					},
					"enabled": true
				},

And this is part of the code, of the Method that the button calls

onGenerateReferencePriceClick: function()
			{
				const tag = arguments[0] || arguments[3];
				const cardModuleSandboxId = this.getCardModuleSandboxId();
				this.sandbox.publish("onGenerateReferencePriceClick", tag, [cardModuleSandboxId]);

This is the result from the debugger

I cant find a reaon why this is not working.

Petrika,

 

It doesn't save the record since the click event is handled not by the onCardAction method, but by your custom one:

click": {
						"bindTo": "onGenerateReferencePriceClick"
					},

According to your need you can use another approach of saving a record: you can call the save function directly (save method parent implementation can be found in the BaseEntityPage module):

this.save();

just add it at the beginning of the code for your button click handling.  And also you can execute methods synchronously using Terrasoft.chain method (an example of the usage can be found in this community post).

 

Best regards,

Oscar

Thanks very much Oscar!

Show all comments

Hi Team,



We are able to update the global search result for a few of the OOTB object schemas by replacing the corresponding module such as AccountSearchRowSchema and for contacts - ContactSearchRowSchema.



a)OOTB object schema,

Contact, Account



https://community.creatio.com/questions/modify-global-search-result



b)I couldn't find any schema as BankCardSearchRowSchema for the OOTB object

BankCard.  How to get this XSearchrowSchema generated?

No details on BankCardSchema



Please note the indexing for the object BankCard is enabled and the results are retrieved but wanted to update the result for this object. Unable to find 

 



Any help would be greatly appreciated!





Best Regards,

Bhoobalan P.

Like 0

Like

12 comments
Best reply

Hi Bhoobalan,

 

You can track if the global search results for the section uses its own SearchRowSchema or the BaseSearchRowSchema using the query below (MS SQL):

SELECT
	sme.Id, sme.ActionKindName, ss.[Name], ss.[UId]
FROM 
	SysModuleEdit sme
JOIN 
	SysSchema ss
ON
	sme.SearchRowSchemaUId = ss.UId
WHERE
	sme.SearchRowSchemaUId IS NOT NULL

But you can create a custom SearchRowSchema module for some section that doesn't have its own SearchRowSchema. The example below is for Documents section that also doesn't have its own SearchRowSchema module.

 

Here is the screenshot of the base result that the Global Search returns when searching a document:

Let's say we want to add the "Status" column to the search result (the one from the screenshot below):

To achieve this:

 

1) Create the "Page view model" in configurations with "UsrDocumentSearchRowSchema" code, "Document search row" name and select BaseSearchRowSchema as a parent:

2) Specify the following code in this schema:

define("UsrDocumentSearchRowSchema", [], function() {
	return {
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"parentName": "DataContainer",
				"propertyName": "items",
				"name": "State",
				"values": {
					"layout": {
						"column": 4,
						"row": 0,
						"colSpan": 12
					}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

and save the schema.

 

3) Find the SysModuleEdit record related to the Documents section (for example using the query below):

SELECT
	*
FROM
	SysModuleEdit
WHERE 
	ActionKindName = 'Document'

and then update the value for the "SearchRowSchemaUId" column in this record:

UPDATE 
	SysModuleEdit
SET 
	SearchRowSchemaUId = '63388eba-74f2-4bc4-85f2-e6c326adb3e5'
WHERE
	Id
IN
	(
		SELECT 
			Id
		FROM 
			SysModuleEdit
		WHERE
			ActionKindName = 'Document'
	)

4) Refresh the page and check the result. The "Status" column should appear in the SearchRowSchema for documents:

Same operation can be performed to any section needed.

 

Best regards,

Oscar

Hi Bhoobalan,

 

You can track if the global search results for the section uses its own SearchRowSchema or the BaseSearchRowSchema using the query below (MS SQL):

SELECT
	sme.Id, sme.ActionKindName, ss.[Name], ss.[UId]
FROM 
	SysModuleEdit sme
JOIN 
	SysSchema ss
ON
	sme.SearchRowSchemaUId = ss.UId
WHERE
	sme.SearchRowSchemaUId IS NOT NULL

But you can create a custom SearchRowSchema module for some section that doesn't have its own SearchRowSchema. The example below is for Documents section that also doesn't have its own SearchRowSchema module.

 

Here is the screenshot of the base result that the Global Search returns when searching a document:

Let's say we want to add the "Status" column to the search result (the one from the screenshot below):

To achieve this:

 

1) Create the "Page view model" in configurations with "UsrDocumentSearchRowSchema" code, "Document search row" name and select BaseSearchRowSchema as a parent:

2) Specify the following code in this schema:

define("UsrDocumentSearchRowSchema", [], function() {
	return {
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"parentName": "DataContainer",
				"propertyName": "items",
				"name": "State",
				"values": {
					"layout": {
						"column": 4,
						"row": 0,
						"colSpan": 12
					}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

and save the schema.

 

3) Find the SysModuleEdit record related to the Documents section (for example using the query below):

SELECT
	*
FROM
	SysModuleEdit
WHERE 
	ActionKindName = 'Document'

and then update the value for the "SearchRowSchemaUId" column in this record:

UPDATE 
	SysModuleEdit
SET 
	SearchRowSchemaUId = '63388eba-74f2-4bc4-85f2-e6c326adb3e5'
WHERE
	Id
IN
	(
		SELECT 
			Id
		FROM 
			SysModuleEdit
		WHERE
			ActionKindName = 'Document'
	)

4) Refresh the page and check the result. The "Status" column should appear in the SearchRowSchema for documents:

Same operation can be performed to any section needed.

 

Best regards,

Oscar

Oscar Dylan,

 

This is informative and thanks for sharing the steps!



I have an issue,



By default, the card search is working for the BankCard object in the customer journey bundle but one of the values shows as (not filled in)



a) Bound values not shown



b) When clicked on (not filled in) it opens the record and the top left label is filled in as depicted below,





I have ran the re-indexation, but still the value is not shown in UI.



Any help would be higly appreciated!







Best Regards,

Bhoobalan Palanivelu.

Bhoobalan Palanivelu,

 

Please send a complete code of the SearchRowSchema of the BankCard schema.

 

Best regards,

Oscar

Oscar Dylan,

Thanks for the quick response!



Unfortunately, there is no SearchRowSchema of the BankCard schema.



I have enabled the indexed in BankCard section and the result appears but there is no trace for "SearchRowSchema".

 



Also, I ran the query to track the schema of Global search below is the result

 

Attaching the "BaseSearchRowSchema" of Customer journey bundle,

define("BaseSearchRowSchema", ["NetworkUtilities", "ConfigurationEnums", "EmailHelper", "GlobalSearchViewGenerator",
	"MiniPageUtilities"], function(NetworkUtilities, ConfigurationEnums, EmailHelper) {
	return {
		hideEmptyModelItems: true,
		attributes: {
			/**
			 * Schema view config.
			 */
			"ViewConfig": {
				dataValueType: Terrasoft.DataValueType.CUSTOM_OBJECT
			},
			/**
			 * Array of found column names.
			 */
			"FoundColumnsCollection": {
				dataValueType: this.Terrasoft.DataValueType.COLLECTION
			},
			/**
			 * Entity schema caption.
			 */
			"EntitySchemaCaption": {
				"dataValueType": Terrasoft.DataValueType.TEXT,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			},
			/**
			 * Primary column url value.
			 */
			"PrimaryColumnURL": {
				"dataValueType": Terrasoft.DataValueType.TEXT
			}
		},
		mixins: {
			MiniPageUtilities: "Terrasoft.MiniPageUtilities"
		},
		methods: {
 
			/**
			 * Returns state object module id for edit page.
			 * @private
			 */
			_getStateObjModuleId: function() {
				return Ext.String.format("{0}_{1}_{2}", this.sandbox.id,
					this.entitySchemaName, this.get(this.primaryColumnName));
			},
 
			/**
			 * @private
			 */
			_initTypedColumnValue: function (callback, scope) {
				const typeColumnName = this.get("TypeColumnName");
				if (typeColumnName && !this.get(typeColumnName)) {
					NetworkUtilities.getAttributeValueByRecordId({
						entitySchemaName: this.entitySchemaName,
						entityId: this.get(this.primaryColumnName),
						attribute: typeColumnName
					}, function(typedValue) {
						this.set(typeColumnName, { value: typedValue });
						Ext.callback(callback, scope);
					}, this);
				} else {
					Ext.callback(callback, scope);
				}
			},
 
			/**
			 * @inheritdoc Terrasoft.BaseSchemaViewModel#init
			 * @overridden
			 */
			init: function(callback, scope) {
				const parentMethod = this.getParentMethod();
				Terrasoft.chain(
					function(next) {
						parentMethod.call(this, next, this);
					},
					this._initTypedColumnValue,
					function() {
						this.initEditPages();
						this.initMultiLookup();
						this.initAttributeValues();
						Ext.callback(callback, scope);
					}, this
				);
			},
 
			/**
			 * Fills lookup field.
			 * @param {String} name Entity schema name
			 * @param {String} value Entity value.
			 * @param {Function} callback Callback-function.
			 * @param {Object} scope Execution context.
			 */
			loadLookupDisplayValue: Terrasoft.emptyFn,
 
			/**
			 * @inheritdoc Terrasoft.BaseSchemaViewModel#sendGoogleTagManagerData
			 * @overridden
			 */
			sendGoogleTagManagerData: Terrasoft.emptyFn,
 
			/**
			 * Initializes viewmodel attributes.
			 * @protected
			 */
			initAttributeValues: function() {
				this.initSchemaCaption();
				this.set("PrimaryColumnURL", this.getPrimaryColumnURL());
			},
 
			/**
			 * Initializes entity schema caption.
			 */
			initSchemaCaption: function() {
				this.set("EntitySchemaCaption", this.entitySchema && this.entitySchema.caption || "");
			},
 
			/**
			 * Returns eintity image url or section logo url or default image url.
			 * @protected
			 * @return {String} Image url.
			 */
			getImage: function() {
				var primaryImageColumnValue = this.get(this.primaryImageColumnName);
				if (primaryImageColumnValue && primaryImageColumnValue.value) {
					return this.getSchemaImageUrl(primaryImageColumnValue);
				}
				var moduleStructure = this.getModuleStructure(this.entitySchemaName);
				if (moduleStructure && moduleStructure.logoId) {
					return this.Terrasoft.ImageUrlBuilder.getUrl({
						source: Terrasoft.ImageSources.SYS_IMAGE,
						params: {
							primaryColumnValue: moduleStructure.logoId
						}
					});
				}
				return this.getDefaultImage();
			},
 
			/**
			 * Returns default image url.
			 * @protected
			 * @return {String} Default image url.
			 */
			getDefaultImage: function() {
				return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.DefaultSearchImage"));
			},
 
			/**
			 * Returns primary display column value.
			 * @protected
			 * @returns {String} Primary display column value.
			 */
			getPrimaryDisplayColumnValue: function() {
				var notFilledValue = this.get("Resources.Strings.NotFilled");
				if (this.primaryDisplayColumnName) {
					return this.get(this.primaryDisplayColumnName) || notFilledValue;
				}
				return notFilledValue;
			},
 
			/**
			 * Returns primary display column caption.
			 * @protected
			 * @returns {String} Primary display column caption.
			 */
			getPrimaryDisplayColumnCaption: function() {
				if (this.primaryDisplayColumnName) {
					var primaryColumn =  this.columns[this.primaryDisplayColumnName];
					return primaryColumn.caption;
				}
				return "";
			},
 
			/**
			 * Returns found column items view config.
			 * @private
			 * @return {Array} Found column items view config.
			 */
			getFoundColumnItemsConfig: function() {
				var columnNames = this.getAdditionalColumnNames();
				var items = [];
				Terrasoft.each(columnNames, function(columnName) {
					var columnContainer = {
						"id": columnName + "Container",
						"className": "Terrasoft.Container",
						"items": []
					};
					var column = this.getColumnByName(columnName) || this.get(columnName);
					var caption = column && column.caption || columnName;
					var value = this.get(columnName);
					if (this.isNotEmpty(value)) {
						columnContainer.items.push({
							"className": "Terrasoft.Label",
							"classes": {"labelClass": ["found-column-caption"]},
							"caption": caption
						});
						columnContainer.items.push({
							"className": "Terrasoft.Label",
							"classes": {"labelClass": ["found-column-value"]},
							"caption": value.displayValue || value,
							"highlightText": this.getHighlightText(columnName)
						});
						items.push(columnContainer);
					}
				}, this);
				return items;
			},
 
			/**
			 * Returns found columns.
			 * @private
			 * @return {Object} Found columns array.
			 */
			getFoundColumns: function() {
				var foundColumnsCollection = this.get("FoundColumnsCollection");
				return foundColumnsCollection.getByIndex(0).get("FoundColumns");
			},
 
			/**
			 * Returns additional column names for view searcg result.
			 * Gets not showed found column names.
			 * @private
			 * @return {String[]} Not showed found column names.
			 */
			getAdditionalColumnNames: function() {
				var bindMap = this.getBindMap();
				var bindMapKeys = bindMap ? bindMap.getKeys() : [];
				var foundColumns = this.getFoundColumns();
				var additionalColumnNames = [];
				Terrasoft.each(foundColumns, function(item, columnName) {
					if(!(Ext.Array.contains(bindMapKeys, columnName)
							|| this.primaryDisplayColumnName === columnName)) {
						additionalColumnNames.push(columnName);
					}
				}, this);
				return additionalColumnNames;
			},
 
			/**
			 * Generates configuration of the element view.
			 * @protected
			 * @param {Object} itemConfig Link to the configuration element of ContainerList.
			 */
			onGetItemConfig: function(itemConfig) {
				var viewConfig = {
					"id": "foundColumns",
					"className": "Terrasoft.Container",
					"classes": {"wrapClassName": ["found-columns-list"]},
					"items": []
				};
				viewConfig.items = this.getFoundColumnItemsConfig();
				itemConfig.config = viewConfig;
			},
 
			/**
			 * Returns not showed columns container visibility.
			 * @protected
			 * @return {Boolean} Not showed columns container visibility.
			 */
			isFoundColumnsVisible: function() {
				var notShowedFoundColumns = this.getAdditionalColumnNames();
				return notShowedFoundColumns.length > 0;
			},
 
			/**
			 * Returns primary column link url.
			 * @protected
			 * @return {String} Primary column link url.
			 */
			getPrimaryColumnURL: function() {
				return Ext.String.format("ViewModule.aspx#{0}", NetworkUtilities.getEntityUrl(this.entitySchemaName,
						this.get(this.primaryColumnName), this.getTypeColumnValue(this)));
			},
 
			/**
			 * Handler on primary column link mouse over.
			 * @protected
			 */
			onPrimaryColumnMouseOver: function(options) {
				this.openMiniPage({
					targetId: options.targetId,
					entitySchemaName: this.entitySchemaName,
					recordId: this.get(this.primaryColumnName)
				});
			},
 
			/**
			 * Handler on primary column link click.
			 * @protected
			 * @return {Boolean} False.
			 */
			onPrimaryColumnLinkClick: function() {
				var typedColumnValue = this.getTypeColumnValue(this);
				NetworkUtilities.openEntityPage({
					entityId: this.get(this.primaryColumnName),
					entitySchemaName: this.entitySchemaName,
					typeId: typedColumnValue,
					sandbox: this.sandbox,
					stateObj: {
						moduleId: this._getStateObjModuleId()
					}
				});
				return false;
			},
 
			/**
			 * @overridden
			 * @inheritdoc Terrasoft.BaseSchemaViewModel#onLinkClick
			 */
			onLinkClick: function(url, columnName) {
				this.updateColumnReferenceSchemaByMultiLookupValue(columnName);
				var column = this.getColumnByName(columnName);
				var columnValue = this.get(columnName);
				var entityId = columnValue && columnValue.value;
				if (!column || !entityId) {
					return true;
				}
				NetworkUtilities.openEntityPage({
					entityId: entityId,
					entitySchemaName: column.referenceSchemaName,
					sandbox: this.sandbox,
					stateObj: {
						moduleId: this._getStateObjModuleId()
					}
				});
				return false;
			},
 
			/**
			 * Returns found column text for highlight.
			 * @private
			 * @param {String} columnName Column name.
			 * @return {String[]} Found column text array.
			 */
			getHighlightText: function(columnName) {
				var highlightTextArray = [];
				var foundColumns = this.getFoundColumns();
				if (columnName === "PrimaryColumn") {
					columnName = this.primaryDisplayColumnName;
				}
				Terrasoft.each(foundColumns, function(item, foundColumnName) {
					if (foundColumnName === columnName) {
						highlightTextArray = item;
					}
				}, this);
				return highlightTextArray;
			},
 
			/**
			 * Returns email url.
			 * @protected
			 * @param {String} columnName Column name.
			 * @return {String} Email url.
			 */
			getEmailUrl: function(columnName) {
				return EmailHelper.getEmailUrl(this.get(columnName));
			},
 
			/**
			 * Open browser mailto.
			 * @param {HTMLElement} target Target element.
			 * @param {String} columnName Email column name.
			 */
			onEmailUrlClick: function(target, columnName) {
				location.href = EmailHelper.getEmailUrl(this.get(columnName));
			},
 
			/**
			 * @overridden
			 * @inheritdoc Terrasoft.BaseSchemaViewModel#getLinkConfig
			 */
			getLinkConfig: function(columnName) {
				var config = this.callParent(arguments);
				var lookupLinkConfig = this.getLookupLinkConfig(columnName);
				this.Ext.apply(config, lookupLinkConfig);
				return config;
			},
 
			/**
			 * Gets lookup link config for open card.
			 * @private
			 * @param {String} columnName Column name.
			 * @return {Object} {schemaName: String} lookup link config for open card.
			 */
			getLookupLinkConfig: function(columnName) {
				var column = this.getColumnByName(columnName);
				var columnValue = this.get(columnName);
				if (column && this.isNotEmpty(column.multiLookupColumns)) {
					var multiLookupColumn = this.getColumnByName(columnValue.column);
					var referenceSchemaName = multiLookupColumn.referenceSchemaName;
					var schemaName = this.getCardSchemaName(referenceSchemaName, multiLookupColumn.name);
					return {schemaName: schemaName};
				}
				return {};
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "PrimaryImage",
				"propertyName": "items",
				"values": {
					"getSrcMethod": "getImage",
					"readonly": true,
					"onImageClick": {bindTo: "onPrimaryColumnLinkClick"},
					"generator": "ImageCustomGeneratorV2.generateSimpleCustomImage"
				}
			},
			{
				"operation": "insert",
				"name": "DataContainer",
				"propertyName": "items",
				"values": {
					"isViewMode": true,
					"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
					"items": [],
					"collapseEmptyRow": true
				}
			},
			{
				"operation": "insert",
				"name": "PrimaryColumnContainer",
				"parentName": "DataContainer",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"classes": {
						"wrapClassName": ["primary-column-container", "control-width-15"]
					},
					"items": [],
					"layout": {
						"column": 0,
						"row": 0,
						"colSpan": 12
					}
				}
			},
			{
				"operation": "insert",
				"name": "PrimaryColumnCaption",
				"parentName": "PrimaryColumnContainer",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.LABEL,
					"caption": {"bindTo": "getPrimaryDisplayColumnCaption"},
					"classes": {
						"labelClass": ["primary-column-caption"]
					}
				}
			},
			{
				"operation": "insert",
				"name": "PrimaryColumnValue",
				"parentName": "PrimaryColumnContainer",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.HYPERLINK,
					"classes": {"hyperlinkClass": ["primary-column-link"]},
					"caption": {"bindTo": "getPrimaryDisplayColumnValue"},
					"click": {"bindTo": "onPrimaryColumnLinkClick"},
					"linkMouseOver": {"bindTo": "onPrimaryColumnMouseOver"},
					"href": {"bindTo": "PrimaryColumnURL"},
					"tag": "PrimaryColumn",
					"highlightText": { bindTo: "getHighlightText" }
				}
			},
			{
				"operation": "insert",
				"name": "EntitySchemaCaption",
				"parentName": "DataContainer",
				"propertyName": "items",
				"values": {
					"caption": {"bindTo": "Resources.Strings.EntitySchemaLabelCaption"},
					"layout": {
						"column": 12,
						"row": 0,
						"colSpan": 6
					}
				}
			},
			{
				"operation": "insert",
				"name": "FoundColumnsContainerList",
				"propertyName": "items",
				"parentName": "DataContainer",
				"values": {
					"layout": {
						"column": 0,
						"row": 1,
						"colSpan": 12
					},
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"generator": "ContainerListGenerator.generateGrid",
					"collection": {"bindTo": "FoundColumnsCollection"},
					"onGetItemConfig": {"bindTo": "onGetItemConfig"},
					"visible": {"bindTo": "isFoundColumnsVisible"},
					"selectableRowCss": "",
					"items": []
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

 

Any insight or help is highly appreciated!





Best Regards,

Bhoobalan Planivelu.

Bhoobalan Palanivelu,

 

Thank you!

 

I understood that you've created the SearchRowSchema for the BankCard and asked to share its code.

 

I will try to implement the same on my side and see what happens.

 

Best regards,

Oscar

Oscar Dylan,

Thanks, please let me know the results once you have a successful implementation.



I enabled the index in the section page of BankCard but no SearchRowSchema is found for it.

 

Oscar Dylan,

Any update on this part, please?



Best regards,

Bhoobalan Palanivelu.

Bhoobalan Palanivelu,

 

Hi,

 

I am sorry, but I don't need the BaseSearchRowSchema from your app (I do also have access to the BaseSearchRowSchema module from the bank bundle app), I need your custom SearchRowSchema code for the BankCard schema.

 

Best regards,

Oscar

Oscar Dylan,

That is the catch here, I couldn't find any SearchRowSchema for BankCardSchema. That is what I have shared in previous comments.



1. The SQL query doesn't return the BankCardSchema

2. There is no SearchRowSchema for BankCard.

3. All I did is open the Bank Card section and enable the Indexing by clicking the check box Indexing for full-text search.



The results appear and it doesn't have any X-SearchRowSchema and at the same time it shows (not filled in).



Best Regards,

Bhoobalan Palanivelu.

Oscar Dylan,

Any help/update on this?



Best regards,

Bhoobalan PAlanivelu

Bhoobalan Palanivelu,

 

Please read my post with the instruction carefully. I've asked to create a replacing view module using the BaseSearchRowSchema as a parent and then connect it to the SysModuleEdit record of your section using the SearchRowSchemaUId column (and provided an example with the Documents section that also don't have its own SearchRowSchema).

Oscar Dylan,

I have followed the same steps as suggested and there needs a little update.



Step 1: Find the target object for GS result update (Here, it is BankCard)

Step 2: Create the "Page view model" in configurations with "CTZBanCardSearchRowSchema" code, "BankCard search row" name and select BaseSearchRowSchema as a parent

Step 3: Update the design of the schema and save.

Step 4: Find the SysModuleEdit record related to the BankCard section (for example using the query below):

SELECT
	*
FROM
	SysModuleEdit
WHERE 
	ActionKindName = 'BankCard'

Step 5: update the value for the "SearchRowSchemaUId" column in the target objects record.

UPDATE 
	SysModuleEdit
SET 
	SearchRowSchemaUId = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
WHERE
	Id
IN
	(
		SELECT 
			Id
		FROM 
			SysModuleEdit
		WHERE
			ActionKindName = 'BankCard'
	)



**Note: This Column's "SearchRowSchemaUId" value should be the UID of the newly created Page view model performed in Step 2.



UID can be obtained by using the below query,

select Id, UId, Name from SysSchema 
where 
Name like ('%CTZBanCardSearchRowSchema%')



Thanks for the guide!





Best regards,

Bhoobalan Palanivelu

 

Show all comments

Hi Team,

 

I have a business scenario where  let's say a user will first filter records for export(let's say export to excel) and if the records are more than 50 then before exporting the records user requires an approval from the department admin over email, Once the user receive an approval over email then only he/she will be able to export those records from system.

 

Note : Email for approval can be sent from the system, but approval email received will not come into the system.

 

Please suggest you solution how we can achieve this in Creatio.

 

Thank you for your time!

Like 0

Like

2 comments

Hi Akshit,

 

This task can be achieved using the following scenario:

 

1) Create two boolean columns in the "System administration object" (SysAdminUnit) object. One of them will be called "Was approval sent?" the second will be "Was approved?"

 

2) The preparation method that is called when clicking the export to excel action is called exportToExcel and located in the BaseDataView module that then calls the exportToExcel method from the GridUtilitiesV2 that then calls exportToExcelFile method from the DataUtilities module (all according to the call stack of calls, you can debug it on your end).

 

You need to add additional check if the "Was approved?" and "Was approval sent?" booleans are checked for the user that initiated the export. To get the current user info you can use the user session (can be received using Terrasoft.sessionId) and then you can perform an ESQ select query to SysUserSession object to get the UserId and then perform another ESQ select query to get information from the SysAdminUnit object directly (we are interested in two boolean columns and the SysAdminUnit Id column value).

 

3) If the "Was approved?" and "Was approval sent?" booleans are not checked then you need to trigger a business process that will send an email (using ProcessModuleUtilities). You need to pass the SysAdminUnit Id column value as a parameter of this process and use it inside the process to form a link to either Reject and Approve "Call to action" buttons.

 

4) To either approve or reject the possibility of export an email with two options "Approve" and "Reject" should be sent. The link should lead you to the webservice on the Creatio side. This webservice should update the specific SysAdminUnit record with an Id that will be passed as a parameter to this webservice (and the parameter will be specified as a part of the link).

 

As for the link itself it can be formed as a text parameter (based on the Id passed from the UI using ProcessModuleUtilities) and passed to the HTML body of the custom template in the "Send email" element as:

"<a href=" + [#LinkParameter#] + "><img alt= \"Accept\" src=\"link_to_the_image_here\" width=\"100\" height=\"100\" ></a>"

Before sending an email the "Was approval sent?" checkbox should be checked for the SysAdminUnit record (using modify data for example).

 

5) The webservice will update the boolean columns "Was approved?" and "Was approval sent?" using the following scenario:

 

5.1) If the approval was rejected - uncheck both "Was approved?" and "Was approval sent?" checkboxes for the user

5.2) If the approval was approved - check the "Was approved?" boolean and uncheck the "Was approval sent?".

 

6) On the section module also add additional check for both boolean columns (as in step 2): if the "Was approved?" is checked and the number of exported items is greater than 50 - permit the export and uncheck the "Was approved?" checkbox for the user.

 

Please study the scenario I described above and use it when implementing the logic on your end.

 

Best regards,

Oscar

Oscar Dylan,

 

Thank you!

Show all comments

Hi Community,

 

Any idea how can I achieve this requirement. I am throwing a custom exception message from object validation. However, in mobile it is showing as generic error, user needs to click on "Send Report" to view the actual exception message I was throwing from object validation. How can I show it on mobile's pop dialog right away?

 

 

Like 0

Like

1 comments

Hi Fulgen,

 

I am sure that your task can be achieved in another way. Please see this Academy article regarding push notifications where you can pass the validation message.

 

Best regards,

Oscar

Show all comments