I have created a button that will do the same thing as "Export to Excel" and I need to call the same function. But I couldn't identify what the function is, if you can help me with what function to call.

Like 1

Like

1 comments
Best reply

The function is named "exportToExcel" and implemented in BaseDataView. If you add a button to the parentName "Detail" and propertyName "tools", then add the click as: "click": {"bindTo": "exportToExcel"}. It will trigger the export to excel just as if it was selected from the actions menu.

Note, this button would need to be added to the detail schema (not the page). It would look something like this: 

{
	"operation": "insert",
	"parentName": "Detail",
	"propertyName": "tools",
	"name": "ExportToExcelButton",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": "Export to Excel",
		"click": {"bindTo": "exportToExcel"}
	}
}

Ryan

The function is named "exportToExcel" and implemented in BaseDataView. If you add a button to the parentName "Detail" and propertyName "tools", then add the click as: "click": {"bindTo": "exportToExcel"}. It will trigger the export to excel just as if it was selected from the actions menu.

Note, this button would need to be added to the detail schema (not the page). It would look something like this: 

{
	"operation": "insert",
	"parentName": "Detail",
	"propertyName": "tools",
	"name": "ExportToExcelButton",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": "Export to Excel",
		"click": {"bindTo": "exportToExcel"}
	}
}

Ryan

Show all comments

Hello!



how would you suggest to solve the following case:



There is a product with base unit of measure - pieces

There is additional unit of measure - kg. As weight of one piece is 0.6 kg, so Number of base units = 1.667





When I add 60 kg of this product, I would like to see 100 pieces, but rounding issue doesn't give me such possibility





As I cannot switch additional and base units, I see, it is necessary to expand functionality of units conversion - add an option to set 'Number of base units' OR 'Number in base unit'



But maybe you have better suggestions?



Kind regards,

Vladimir

Like 0

Like

1 comments

Hello Vladimir,

 

Thank you for this question. In the OOTB logic it was not expected to have irregular fractured values. As a workaround - using grams may be helpful to avoid the visible issue, or to use custom and specific logic to fulfill your needs.

 

We have noted this request to our Backlog for our Developers. If there will be more customers arriving with the same issue - we will develop and implement this feature in further releases.

 

Best Regards,

Dan

Show all comments

Hello!



How is it better to hide specific columns (from column setup in sections and details) in Partner Portal? 

I see two options now:

- use access rights by columns (columns still present, but are empty)

- deny Portal users to setup columns in sections and details (users still can get some information using filters)



Maybe there are more better options?



Thank you!

Vladimir

Like 0

Like

4 comments
Best reply

Vladimir Sokolov,

 

What you are looking for can be achieved by adding only the columns that you want to show to the Portal users into "List of schema fields for portal access" lookup. As a result those fields won't be available on any of the dropdown list.

 

Regards,

Sourav Kumar Samal

Hi Vladimir,



We recommend hiding specific columns in the Partner Portal by the Section Wizard. 

Hi Bogdan,

we can hide columns only from the page (as far as I know), but these columns are still available in Column setup and filters, that :

1) allows client to see all internal infromation in the Portal

2) makes filter and column setup for them much more difficult (as they see all internal fields in the list)



Vladimir Sokolov,

 

What you are looking for can be achieved by adding only the columns that you want to show to the Portal users into "List of schema fields for portal access" lookup. As a result those fields won't be available on any of the dropdown list.

 

Regards,

Sourav Kumar Samal

Sourav Kumar Samal,

Thank you very much!

Show all comments

Hello,



we need to improve lookup selection for several section. The main idea is to reduce quantity of records for selection, but still give user to search through full list.



We tried to use multiLookup feature to give 2 options: "All products" and "Active products" (like we select Account/Contact in the Order)



 

"UsrProductLookup": {
    "dataValueType": Terrasoft.DataValueType.LOOKUP,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "multiLookupColumns": ["UsrProductA", "UsrProductB"],
    "caption": "Product",
    "onChange": "setProduct"
},
"UsrProductA": {
    "dataValueType": Terrasoft.DataValueType.LOOKUP,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "isLookup": true,
    "referenceSchemaName": "Product"
},
"UsrProductB": {
    "dataValueType": Terrasoft.DataValueType.LOOKUP,
    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
    "isLookup": true,
    "referenceSchemaName": "Product"
}

But then got an error, that we cannot use the same object for both lookups. 



message: Item with key "Product" Already exists 

date: Tue Oct 18 2022 02:01:40 GMT+0400 

moduleId: CardModuleV2_02b6b083-3cfa-4daf-a93c-632cb2420805_AccountPageV2_LookupPage

moduleName: MultiLookupModule



How is it possible to use multiLookup for this purpose? 

Or what alternative is for user-friendly quick filter in Lookup window?



Thank you.

Vladimir

Like 0

Like

4 comments

Hello Vladimir,



Please find the information about up filtering of lookup field values on a record page in this article

 

Bogdan,

thank you for link to Creatio basics.



But combination of quick filters (tabs in this case) gives possibility to search by second condition - by product name.



If you use search in lookup for one criteria (e.g. Inactive), you cannot search by another criteria - name. 

Besides, search in lookup requires much more actions (more than 4 clicks) comparing to 1 click in quick filter



That's why we are searching for smart solution



Kind regards,

Vladimir

Vladimir Sokolov,

 

We recommend creating a business rule on the page depending on a particular checkbox: if the checkbox is activated, then display the field in which the code filtering is implemented, if deactivated - hide the column with filtering in the code and show the column without filtering on the page.

 

You might need two columns so that you control the visibility of one depending on a particular checkbox. It can be achieved by using a business rule. 

 

Please try using the filters described in the article above for one column, and for the other one - do not apply the filters from the code (so that all Lookup records are displayed). This way, you may not use code elements as you just implement the business rule - filtering on the page.

Alla Blinova,

Thank you. Yes, we use solution with field and business rules, but customer should open lookup, search, then close lookup, change checkbox, open lookup again... 



Sometimes it can be acceptable, sometimes not. That's why we are looking for better option - to allow user change lookup filtration directly in lookup window. It can be a checkbox in lookup window or several predefined tabs. Maybe it sounds like an idea for future versions, maybe it is possible implement with current one



Kind regards,

Vladimir

Show all comments

Hi, 

 

I'd liket to create a script task in a business process, that given an email template, it executes it on a specific context. I mean, if the email template is based on a custom macro related with the Lead entity, I can pass the LeadID and the emailTemplateId to the script task, and the result is the text of the email template executed for that specific lead. 



Is there way to do that?



Thanks!

Ignacio 

Like 0

Like

4 comments

Hi Ignacio,

 

You can pass LeadId and the TemplateId as process parameters (create two Guid parameters in the process settings). Then you can use the "Read data" element and read specific columns of the lead record (use the LeadId parameter in the "Read data" filtration to get the value for needed columns). Then you can create additional text parameters and pass the read column values to them (using formulas for example). The same approach is for the "Email template" object and TemplateId parameter (you need to get the template body, so you need to read it in the "Read data" process element). And finally you can use string interpolation (or String.Replace method) in the script task to replace macroses (macorses, not their values, like [#UsrSomeColumn#], it's passed in the template body) with the actual values read from the "Lead" object using the "Read data" element (the ones that we wrote to the process parameters). To get process parameters values in the script task you need to use Get<string>("ParameterCode") (see more examples here) construction in the script task, then you can use String.Replace in the following manner:

string UsrStringParameterValueToUse = Get&lt;string&gt;("UsrStringParameterValue");
string EmailTemplateBody = Get&lt;string&gt;("UsrEmailTemplateBodyParamter");
EmailTemplateBody= EmailTemplateBody.Replace("[#UsrSomeColumn#]", UsrStringParameterValueToUse);

And then you can return EmailTemplateBody to some another string parameter value using Set<string> command and as a result you will get the result needed.

Thank you for your response Oleg!

 

Right, that would be the "manual" approach. I was hoping I could reuse the same service that is being used when creating an email from a template. For example, I can use a ReportService to generate a printable inside a business process. I was hoping that we have in Creatio something like "EmailService" that processes an email template and returns the generated text.

Pavel Shkomov,

 

You need to use the script-task to send the email from the code directly. Please see this Academy article that describes how to form and send the email from the code (this article also have examples of implementations, please use the "Examples" tab at the top of the article).

Ignacio Alvarez,

 

there is another approach:

var macrosHelperClassFactory = ClassFactory.Get&lt;MacrosHelperV2&gt;(new ConstructorArgument("userConnection", UserConnection));
 
string emailTemplateCode = Get&lt;string&gt;("ResultEmailTemplatePlain");
string templateEntityName = Get&lt;string&gt;("ContactEntityName");
Guid templateEntityId = Get&lt;Guid&gt;("ContactRecordId");
 
var replacementResult = macrosHelperClassFactory.GetTextTemplate(emailTemplateCode, templateEntityName, templateEntityId);
Set&lt;string&gt;("ResultEmailTemplateHTML", replacementResult);
return true;

There should be also the following parameter values:

1) the code is ContactEntityName - Text (50 characters) data type ("Contact" value by default) - represents the object from which data for macros is selected

2) the code is ContactRecordId - Unique identifier data type - represents the record Id to get data for macroses

3) the code is ResultEmailTemplateHTML - Unlimited length text data type - contains the template with filled macroses

4) the code is ResultEmailTemplatePlain - Unlimited length text data type - contains the template without filled macroses

 

Also you need to add the following namespaces to the process usings:

Terrasoft.Configuration.Utils

Terrasoft.Core.Factories

 

You need to use the "Read data" process element and read specific email template (the object is "Message template") and you need only the "Body" column value. Then the read body of the template should be passed to the "ResultEmailTemplatePlain" parameter using the "Formula" process element.

 

As a result of the script-task process element you will get the formed email template body with filled macroses in the ResultEmailTemplateHTML parameter that can be then displayed for example using the autogenerated page.

Show all comments

Hello community,

 

I have a case where based on a lookup value, I need to display an image. The code is working and logging values as expected but the image does not seem to load. When inspect HTML I find the following

[object Object]" title="">

 

and the error

https://dev2-is-il.creatio.com/0/Nui/[object%20Object] 404

 

However my method is returning the correct URL 

https://dev2-is-il.creatio.com/0/conf/content/img/UsrRequests1Page-Dril…

 

Please find the code below



Diff

{
				"operation": "insert",
				"name": "UsrProjectCategoryCaption",
				"values": {
					"itemType": 6,
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 0
					},
					"visible":  {
						"bindTo": "IsPrjCatIconContVisible"
					},
					"caption": {
						"bindTo": "Resources.Strings.ProjectCategoryCaption"
					}
				},
				"parentName": "ProfileContainer",
				"propertyName": "items",
				"index": 0
			},
			{
				"operation": "insert",
				"name": "AccountPhotoContainer",
				"values": {
					"itemType": 7,
					"wrapClass": [
						"image-edit-container"
					],
					"items": [],
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 1
					},
					"visible":  {
						"bindTo": "IsPrjCatIconContVisible"
					},
				},
				"parentName": "ProfileContainer",
				"propertyName": "items",
				"index": 1
			},
			{
				"operation": "insert",
				"name": "Photo",
				"values": {
					"layout": {
						"colSpan": 24,
						"rowSpan": 1,
						"column": 0,
						"row": 2
					},
					"getSrcMethod": "getPhotoSrcMethod",
					"readonly": true,
					/*"defaultImage": {
								"bindTo": "getPhotoSrcMethod"
					},*/
					"generator": "ImageCustomGeneratorV2.generateCustomImageControl"
				},
				"parentName": "AccountPhotoContainer",
				"propertyName": "items",
				"index": 0
			},

 

Methods

 

getPhotoSrcMethod:function()
			{
 
			    var reqId=this.get("Id"); 
				this.getProjectCategory(reqId, function(result) {
 
					 this.console.log("cbdone:" + result);
					 if(result.pjtCatId==="5f43b0aa-f7f6-4ffa-bc6d-15cf1fd581e0")
							{
								this.console.log("getIcon NationalPriorityImage");
								this.set("Resources.Strings.ProjectCategoryCaption", result.pjtCatName);
								this.set("IsPrjCatIconContVisible", true);
								this.console.log("IsPrjCatIconContVisible true");
								//class="ts-image-edit-full-size-element ts-image-style-rectangular"
 
						 		return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.NationalPriorityImage"));
							}
						else if(result.pjtCatId==="08135814-ecdb-48ed-adea-5d4e5f1b0129")
							{
								this.console.log("getIcon BicyclePathsIcon");
								this.set("Resources.Strings.ProjectCategoryCaption", result.pjtCatName);
								this.set("IsPrjCatIconContVisible", true);
 
								return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.BicyclePathsIcon"));
							}
						else if(result.pjtCatId==="a1a8e24d-6c6c-49ea-bb3c-5d76da662a27")
							{			   
								this.console.log("getIcon DrillingExplorationIcon");
								this.set("Resources.Strings.ProjectCategoryCaption", result.pjtCatName);
								this.set("IsPrjCatIconContVisible", true);
								this.console.log(this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.DrillingExplorationIcon")));
							//	return this.getSchemaImageUrl(this.get("Resources.Images.DrillingExplorationIcon"));
								return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.DrillingExplorationIcon"));
 
							}
						else if(result.pjtCatId==="18588952-b4bf-4477-a614-a15a103adc28")
							{
								this.console.log("getIcon DrillimgAndNPIcon");
								this.set("Resources.Strings.ProjectCategoryCaption", result.pjtCatName);
								this.set("IsPrjCatIconContVisible", true);
 
								return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.DrillingAndNPIcon"));
							}
						else
							{
								this.set("IsPrjCatIconContVisible", false);
								this.console.log("IsPrjCatIconContVisible is false due to regular prj 2");
								return this.Terrasoft.ImageUrlBuilder.getUrl(this.get("Resources.Images.AnalyticsDataIcon"));
 
							}
 
                        },this);
 
 
			},
			getProjectCategory :function(reqId,callback,scope)
			{
				var result;
				var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
					rootSchemaName: "UsrRequests"
				});
				esq.addColumn("Id");
				esq.addColumn("UsrProject.UsrProjectCategory.Id","CatId");
				esq.addColumn("UsrProject.UsrProjectCategory.Name","CatName");
				esq.filters.add("ProjectFilter", Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.EQUAL, "Id",reqId));
				esq.getEntityCollection(function(result) {
 
					var resultValue = result.collection.collection.items;
					var pjtCatId = resultValue[0].values.CatId;
					var pjtCatName = resultValue[0].values.CatName;
					this.console.log("pjtCatId:" + pjtCatId);
					this.console.log("pjtCatName:" + pjtCatName);
					result ={ success:true,
							  pjtCatId : pjtCatId,
							  pjtCatName:pjtCatName
							};
					callback.call(scope || this, result);
				},this);
			},

 

Like 0

Like

6 comments
Best reply

Shivani Lakshman,

Rather than bind the image element in the diff to the function (which won't work since the ESQ in the function is asynchronous), bind it to an attribute, then set the attribute in the asynchronous function (and just call the function in the onEntityInitialized).

Example:

First add the attribute:

"MyImageAttr": {
	dataValueType: Terrasoft.DataValueType.TEXT,
	type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
	value: ""
}

Then, create the function that retrieves the image using the ESQ:

function getImage() {
	// do the ESQ to get the image, then simply set in attribute
	this.set("MyImageAttr", Terrasoft.ImageUrlBuilder.getUrl(imageConfig));
}
 
// also call image from onEntityInitialized so it runs when the record is loaded
function onEntityInitialized() {
	this.callParent(arguments);
	this.getImage();
}

Now, add the image to the diff, bound to the attribute:

// image element in diff
// note "MyImageAttr" is an attribute we're binding to
{
	"operation": "insert",
	"name": "MyImage",
	"parentName": "ImageContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.COMPONENT,
		"className": "Terrasoft.ImageView",
		"imageSrc": {"bindTo": "MyImageAttr"}
	}
}

Then the record loads, it will run the ESQ in the function, which will set the attribute with the image. Since the diff element is bound to the attribute, it will show the image when it is set, so it won't matter that the ESQ is asynchronous. 

Ryan

Hello Shivani,

 

As far as I remember there is no way to dynamically modify the image in the photo container from the client side code since it's strictly connected to the value stored in the "Photo" column of the object. In this case you may try modifying the photo on the server side and refresh the page if needed.

Oleg Drobina,

 

I believe we can. We have already implemented this in another section. Please see a screen grab in this link

 

https://drive.google.com/file/d/1BKT6E_azsOjjh1N9VZh0bPpfUjrttm79/view?…



We posted on the forum here because for some reason the code is not working when there is esq involved.

 

 

Shivani Lakshman,

 

Ok, I was wrong, then this is possible. Then probably the reason is that esq is asynchronous and you don't get the data needed at the moment the image should be loaded to the UI (this is the most probable reason). In this case try avoiding using esq and use some other approach.

Oleg Drobina,

 

I have used callback and when the breakpoint hits my method, the code for  

the image I need hits before the default image gets loaded. I am actually puzzled ? 

 

Can you please suggest another approach ? I don’t want to add another column because this image will be dynamic and change frequently.

 

Is there an attribute that can hold images and that can be loaded onto the UI?

 

Would appreciate your help here!

Shivani Lakshman,

Rather than bind the image element in the diff to the function (which won't work since the ESQ in the function is asynchronous), bind it to an attribute, then set the attribute in the asynchronous function (and just call the function in the onEntityInitialized).

Example:

First add the attribute:

"MyImageAttr": {
	dataValueType: Terrasoft.DataValueType.TEXT,
	type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
	value: ""
}

Then, create the function that retrieves the image using the ESQ:

function getImage() {
	// do the ESQ to get the image, then simply set in attribute
	this.set("MyImageAttr", Terrasoft.ImageUrlBuilder.getUrl(imageConfig));
}
 
// also call image from onEntityInitialized so it runs when the record is loaded
function onEntityInitialized() {
	this.callParent(arguments);
	this.getImage();
}

Now, add the image to the diff, bound to the attribute:

// image element in diff
// note "MyImageAttr" is an attribute we're binding to
{
	"operation": "insert",
	"name": "MyImage",
	"parentName": "ImageContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.COMPONENT,
		"className": "Terrasoft.ImageView",
		"imageSrc": {"bindTo": "MyImageAttr"}
	}
}

Then the record loads, it will run the ESQ in the function, which will set the attribute with the image. Since the diff element is bound to the attribute, it will show the image when it is set, so it won't matter that the ESQ is asynchronous. 

Ryan

Ryan Farley,

 

Thank you for your help! Really appreciate it :)

Show all comments

Hi community,

 

I am developing an application only for the "Sales" module which includes the Sales enterprise, the sales team and the sales commerce edition. Actually, I am developing the application in a "Sales Enterprise" environment and I only have the "SalesEntepriseSoftKey_ENU" package.

 

Which should be the right package to set to work with all the Sales product versions ?

 

Many thanks for your help.

 

Best regards,

Jonathan

Like 0

Like

3 comments

Hello,

 

Please refer to this Academy article (+ this) to define the package dependencies.

 

Best regards,

Mira

hi @Jonathan,



It's recommended to have the package that has access/connected to all the base packages of the Creatio bundle. Also, the package dependency diagram in the configuration section will give insight into the structure of the package of products (Sales, Service, Marketing, Studio).







In your case (i.e., sales bundle), the package SalesEntepriseSoftKey_ENU shall be added in dependency. Please be informed that SalesEntepriseSoftKey_Obselete package shouldn't be added in dependency as this might be removed in the product updates.





BR,

Bhoobalan Palanivelu.

Bhoobalan Palanivelu,

 

Hi @Bhoobalan,

 

The problem here is that if I put the dependency on "SalesEnterpriseSoftkey_ENU" package, it will only work with the "SalesEnterprise" products of Creatio, not SalesTeam nor SalesCommerce.

 

Best regards,

Jonathan

Show all comments

Hello team,

 

I was trying to replicate account photo functionality in a custom section. I noticed that the getAccountLogo method gets called twice. Please see below screenshot (Hello from getAccountLogo is repeated twice)



This is causing errors in my functionality. Can someone please check?

Like 0

Like

1 comments

Hi,

If you want to add a photo to your custom section then there is instruction on how to do it.

Take a look at this conversation, there you can find an article and example.

Show all comments

Hello

I have a business case were the managers need to extract a report to identify the accounts and/or contacts group by user, where the user is either the owner of the record or the user to whom the record has been shared with. Please note that the records are visible by owner, that said, is a private model.

i.e

  • Contact A is owned by Sales Rep 1 (only that sales rep has visibility on it)
  • Sales Rep 1 shares contact A with the Sales Rep 2 granted read-only rights (now both Sales Rep 1 and Sales Rep 2 can see the record)
  • Both sales reps have the same manager
  • Manager wants to have a list grouped by sales rep to track which are the records they have to work on. Expected result should be as follows:
    • Sales Rep 1: Contact A, Contact M, Contact Z
    • Sales Rep 2: Contact A, Contact X, Contact L

Any help on how to achieve above will help me a lot! 

 

Thanks!

 

Like 0

Like

2 comments
Best reply

Hi Adriana, 

 

You can create VIEW in the database (Access rights to Contact are stored in the table SysContactRight) and object based on that view. Then you can use this object for report or for tagging records.



A little bit more complicated situation is when record has access rights for group (e.g. All Employees). That means that this record is shared with more users and you need to calculatate all of them

 

Hi Adriana, 

 

You can create VIEW in the database (Access rights to Contact are stored in the table SysContactRight) and object based on that view. Then you can use this object for report or for tagging records.



A little bit more complicated situation is when record has access rights for group (e.g. All Employees). That means that this record is shared with more users and you need to calculatate all of them

 

Hello Vladimir

Thank you so much for your reply, I have also consulted internally and I got the same solution so I guess thats the best alternative!

Show all comments

We're looking for a way to link a document that is loaded into Creatio in an email template that is sent. 

 

For example, a contract is uploaded into the Attachments section of an Opportunity. The Opportunity is won, and a notification email goes out to specified users. The email includes information from the record, but also a link to the document within the Attachments section. 

Like 2

Like

1 comments

Hello Susan,

 

Your business task can be achieved via custom business process. You'd need to use [Process file] and [Send email] elements to achieve this business task. 

More detailed information about these elements can be found on our Academy:

https://academy.creatio.com/docs/user/bpm_tools/process_elements_refere…

https://academy.creatio.com/docs/7-17/user/bpm_tools/process_elements_r…



Best regards,

Anastasiia

Show all comments