Question

We are running with critical issue with the BPM Sync emails.

The email account password expired and we are trying to reset it.

 

We did reset in the exchange, but when we try to update the new password in BPM the system shows the below message.

"Invalid email or password" 

But we verified by logging in in M365, able to login.

 

 

Like 1

Like

5 comments

Hi Selva,



Microsoft stopped using the "Basic authentication" type for mailbox authorization. Therefore, to solve the issue, It recommends switching to the OAuth authorization type to restore mail synchronization in the application. Microsoft provides the following set up instructions - https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchan…

For the application version 8.0.2 and above the steps are the following:
 
1.  Setup the application in Azure.
2.  Make changes to the mail provider on the Creatio side (change from basic to OAuth and fill in data form Azure side). 
3.  All user mailboxes will require user action to grant permission to continue synchronization.
 
Older versions:
1.  Setup the application in Azure.
2.  Setup the mail provider on the Creatio side (It’s better to create a Copy of the existing mail provider and use it but it’s also possible to change the old one) 
3 .a If it is OK to delete the mailbox and add it with the new mail server – it’s the easiest way and will cause no additional issues. That’s all.
3 .b In case you cannot / don’t want to delete a mailbox and want to adjust it to use the new mail provider then your IT team should do steps 1 and 2 and then contact Creatio support asking to:
-	Update the MailServerId column of the MailboxSyncSettings table with the value of the new/adjusted mail server that can work with Oauth.
-	Run the script: update "MailboxSyncSettings" 
-	set "ErrorCodeId" = '5f906e1c-9521-45df-8e43-82b5109e0e4d' 
-	where "Id" = 'the_Changed_Mailbox'
4.  All user mailboxes will require user action to grant permission to continue synchronization.





BR,

Bhoobalan Palanivelu.

As Bhoobalan mentioned, Microsoft has disabled basic authentication for Office 365 accounts, which means you can no longer use a username & password to log in from other applications (such as Creatio). Instead, you need to create an OAuth app in the Office 365 Azure portal, then use that in Creatio. 

I have an article with screenshots showing how to set up OAuth for using Office 365 in Creatio here: https://customerfx.com/article/setting-up-microsoft-office-365-email-fo…

The account will no longer work in Creatio until you switch it to use OAuth.

Ryan

Bhoobalan Palanivelu,

Thanks for the detailed info, much appreciated !

We are running with the version 7.16, is the changes and steps still same ?

 

Thanks,

Selva

 

Ryan Farley,

 

Thanks for the detailed steps.

 

We followed all the steps as per your link, and then tried to update the new password in Creatio ( where it shows warning message like specify the new password). It gives the same error message.

 

But when I deleted my email account and re-added , it works fine.

 

Do we need to delete all the email accounts ( We have 5 email accounts for renewal, case process) and re-add them ? or do we have any other way to provide permission and make it sync without deleting them ?

 

Please let me know.

 

Thanks,

Selva

 

Selva,

Selva,

 

Yes, The steps are the same for versions below 8 as mentioned.

It's not mandatory to delete the mailbox and re-add them but if it is fine to remove and re-add the mailbox, it's the easiest method to do.



All 5 accounts must be of Office 365 and currently you have updated the OAuth in Creatio following Ryan's article. So you can remove the other mailbox and re-add them and synchronize it.





BR,

Bhoobalan Palanivelu.

Show all comments

I need this button to be on all rows and not on "activeRowActions", and I can't find the right parent.

 

{
	"operation": "insert",
	"parentName": "DataGrid",
	"propertyName": "activeRowActions",
	"name": "MoveQtyButton",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": "Move Qty",
		 "className": "Terrasoft.Button",
         "style":this.Terrasoft.controls.ButtonEnums.style.BLUE,
         "tag": "call",
	}
},

 

Like 1

Like

6 comments

Hi Gabriel,



Please find the solutions in the below community threads.

https://community.creatio.com/questions/add-button-datagrid-active-row
https://community.creatio.com/articles/add-button-active-row-detail







BR,

Bhoobalan Palanivelu.

Bhoobalan Palanivelu,

Thanks for responding, but I had seen these posts before, and they helped me in parts but not for what I need, the two are for activeRow, that is for when they are selected only, and I need them to appear in all rows even if not selected.

Gabriel Cassimiro,



Thanks for the briefing!

In this case, you need a button as a column in the grid.



ContactSectionV2 Grid

define("ContactSectionV2", ["css!UsrContactSectionV2CSS"], function() {
	return {
		entitySchemaName: "Contact",
		attributes: {
			"SelectButtonColumn": {
				"dataValueType": Terrasoft.DataValueType.TEXT,
				"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			}
		},
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			onGridDataLoaded: function(response) {
				this.mixins.GridUtilities.onGridDataLoaded.call(this, response);
				this.addSelectCustomerButton();
			},
			onRender: function() {
				this.callParent(arguments);
				this.addSelectCustomerButton();
			},
			unSelectRow: function(id) {
				this.mixins.ConfigurationGridUtilities.unSelectRow.apply(this, arguments);
				this.addSelectCustomerButton();
			},
			addSelectCustomerButton: function() {
				var baseSelector = "#grid-ContactSectionV2DataGridGrid-wrap div.grid-listed-row div:last-child";
				var selector = baseSelector + ">span";
				var scope = this;
				$(selector).unbind();
				$(baseSelector).html(
					Ext.String.format("<span>{0}</span>", this.get("Resources.Strings.SelectCustomerButtonCaption")));
 
				$(selector).addClass("glb-select-customer-button");
 
				$(selector).click(function() {
					var id = "";
					try {
						id = arguments[0].currentTarget.offsetParent.offsetParent.attributes.id.value.split("item-")[1];
					} catch(e) {}
					if (id) {
						scope.onSelectCustomerButtonClick(id);
					} else {
						this.error("Active row id was not found");
					}
				});
			},
			onSelectCustomerButtonClick: function(id) {
				this.showInformationDialog(id);
			}
		}
	};
});

CSS Module:

.glb-select-customer-button {
	background: #8ecb60;
	color: white;
	padding: 2px 10px;
	border-radius: 3px;
}
 
.glb-select-customer-button:hover {
	background: #74bc48;
	cursor: pointer;
}



Result will be like below,





You need to do the same in your detail schema.





BR,

Bhoobalan Palanivelu.

 

Bhoobalan Palanivelu,

This is fantastic Bhoobalan, thanks for sharing!

Ryan

Bhoobalan Palanivelu,

Thanks, I have a question, because I'm trying to apply in a list of a detail, but I'm not having the same result for when it is a grid of a section, is there something I have to put different or does it work the same way?

Gabriel Cassimiro,



Please be informed to define the value for this label through the localizable string available on your schema page.

this.get("Resources.Strings.SelectCustomerButtonCaption"))

Also, you can check about the CSS and its dependency included in your schema.


 

BR,

Bhoobalan Palanivelu.

Show all comments

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