Question

Recipient filter

Hello,

On the send email task on a page, I am trying to filter the "Recipient" field. The problem is the object is "VwRecipientEmail" and it only contains a GUID "ContactId" and this isn't a lookup. 

 

The filter I want is to only show contacts that are associated with the account on this case or "our company" contacts. Originally I was able to solve this with some ESQ, but it's buggy and unstable. 



 

"Recipient": {
                    "dataValueType": Terrasoft.DataValueType.LOOKUP,
                    "lookupListConfig": {
                        "filters": [function() {
                            
                            var filters = Ext.create("Terrasoft.FilterGroup");
                            filters.logicalOperation = Terrasoft.LogicalOperatorType.OR;
                            
                            filters.add("AccountFilter", 
                                Terrasoft.createColumnFilterWithParameter(
                                    Terrasoft.ComparisonType.EQUAL, "ContactId", ""
                                )
                            );
 
 
 
                           filters.add("OurAccountFilter", 
                                Terrasoft.createColumnFilterWithParameter(
                                    Terrasoft.ComparisonType.EQUAL, "ContactId", ""
                                )
                            );
                            
                            return filters;
                        }]
                    }
                }

Any tips?

Thank you! 

 

I should add, all of this is happening on the "EmailMessagePublisherPage"

Like 0

Like

13 comments
Best reply

Tyler Rainey,

Tyler, I've not read through all your code, but glanced through it. I would assume that the issue is that in the function that returns the filters, you're using asynchronous ESQ queries. In doing so, the rest of the function continues and returns the result before the ESQ has returned. I assume that is what your setTimeout is attempting to do (wait until they've returned) but that just creates another callback, it won't stop the original function from returning.

You'll likely need to rethink how things are working. I would probably try using the sandbox in address mode to ask the case page for the values and return the contact Id list to the EmailMessagePublisherPage. You could pre-fetch the contact Id list on the case page in the onEntityInitialized and store in a collection attribute so they're ready to go when asked for by the sandbox message. Just throwing some ideas out there.

Ryan

Dear Tyler,

 

Using ESQ here will be the best option possible. But if it is buggy you can replace exiting "Recipient" field to custom one with needed filtration. 

 

Please let me know if this solution does not work for you, I will check other workarounds. 

 

 Best regards,

Angela

Angela Reyes,

Angela, I have an issue with it because when you close the page and go to another page it never works. It only works for the first page you look at and then afterwards the filter is wide open. The first filter doesn't stay on either.

Hi Tyler,

 

Could you please specify if you are creating a replacing client schema model? Also, could you please provide a complete code and a screenshot of what you want to change to avoid misunderstanding at our end? Looking forward to hearing from you! 

 

Regards,

Anastasiia

Anastasiia Markina,

Here is my code. Please do not judge haha

"Recipient": {
			        "dataValueType": Terrasoft.DataValueType.LOOKUP,
			        "lookupListConfig": {
			            "filters": [function() {
			                var filters = Ext.create("Terrasoft.FilterGroup");
			                filters.logicalOperation = Terrasoft.LogicalOperatorType.OR;
			                // filters.add("ActiveFilter", 
			                //     Terrasoft.createColumnFilterWithParameter(
			                //         Terrasoft.ComparisonType.EQUAL, "Active", true
			                //     )
			                // );
 
 
			                // Get [Id] of card object.
 
			                const split = window.location.href.split("/");
			                const id = split[split.length - 1];
 
							// Create Terrasoft.EntitySchemaQuery class instance with [Contact] root schema.
							var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
							    rootSchemaName: "Case"
							});
							// Add column with name of main contact of accounts that refers to given contact.
							esq.addColumn("Account.Id", "AccountId");
							// Get one record from selection on the basis of [Id] of card object and display it 
							// in an info window.
							esq.getEntity(id, function(result) {
							    if (!result.success) {
							        // error processing/logging, for example
							        this.showInformationDialog("Data query error");
							        return;
							    }
 
							    const accountId = result.entity.values.AccountId;
 
 
							    // Creation of query instance with "Contact" root schema. 
								var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
								    rootSchemaName: "Contact"
								});
								esq.addColumn("Id");
								esq.addColumn("Account");
								esq.filters.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
								// Creation of the first filter instance.
								var esqIdFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", accountId);
								// Filters will be updated by OR logical operator in query filters collection. 
								var ourAccountFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", Terrasoft.SysValue.CURRENT_USER_ACCOUNT.value);
 
								// Adding created filters to collection. 
								esq.filters.add("esqIdFilter", esqIdFilter);
								esq.filters.add("ourAccountFilter", ourAccountFilter);
								let count = 0;
								// This collection will include objects, i.e. query results, filtered by two filters.
								esq.getEntityCollection(function (result) {
								    if (result.success) {
								        result.collection.each(function (item) {
 
								        	filters.add(`Filter${count}`, 
							                    Terrasoft.createColumnFilterWithParameter(
							                        Terrasoft.ComparisonType.EQUAL, "ContactId", item.values.Id
							                    )
							                );
 
							                count++;
 
								        });
								    }
								}, this);
 
							}, this);
 
 
			                setTimeout(function(){}, 8000);
 
			                return filters;
			            }]
			        }
			    },

 

Hi Tyler Rainey,

 

We have carefully tested your solution and it works correctly at our end. Could you please follow the instructions below and make sure that everything is completed? There could be slight differences between our approaches: 

 

1. Firstly, you need to create a replacing client module schema for the "EmailMessagePublisherPage" client module (set "Email Message Publisher Page ( EmailMessagePublisher )" as a parent object). Please find the information about it in the article by the link below:

 

https://academy.creatio.com/documents/technic-sdk/7-16/creating-custom-…

 

2. In a new replacing client schema, please insert the code below:

 

define("EmailMessagePublisherPage", ["LookupUtilities"],
function(LookupUtilities) {
    return {
        entitySchemaName: "Activity",
        messages: /**SCHEMA_DIFF*/ {} /**SCHEMA_DIFF*/ ,
        attributes: /**SCHEMA_DIFF*/ {} /**SCHEMA_DIFF*/ ,
        methods: /**SCHEMA_DIFF*/ {
 
            openRecepientLookupEmail: function() {
                var lookup = this.getLookupConfig("Recepient");
                lookup.config.actionsButtonVisible = false;
                var searchValue = this.get("RecepientLookupSearchValue");
                if (searchValue) {
                    lookup.config.searchValue = searchValue;
                }
                LookupUtilities.Open(this.sandbox, lookup.config, lookup.callback, this, null, false, false);
            },
 
            getLookupConfig: function(columnName) {
                var scope = this;
                var callback = function(args) {
                    scope.onLookupSelected(args);
                };
                return {
                    config: {
                        entitySchemaName: "VwRecepientEmail",
                        columnName: columnName,
                        columns: ["ContactId"],
                        filters: this.returnNewFilter(),
                        multiSelect: true
                    },
                    callback: callback
                };
            },
            returnNewFilter: function() {
                    // your code here
            }
        }/**SCHEMA_DIFF*/ ,
        diff: /**SCHEMA_DIFF*/ [] /**SCHEMA_DIFF*/
    };
});

3. Save the changes and hard-reload the page.

 

It seems that you've used the wrong attribute for your code (it should be located inside returnNewFilter() method). Please let us know the result. Looking forward to hearing from you!

 

Regards,

Anastasiia

Anastasiia Markina,

Hi,

I have tried your implementation in you new trial instance and doesn't work at all.

Please see the code. 

 

 

define("EmailMessagePublisherPage", ["LookupUtilities"],
function(LookupUtilities) {
    return {
        entitySchemaName: "Activity",
        messages: /**SCHEMA_DIFF*/ {} /**SCHEMA_DIFF*/ ,
        attributes: /**SCHEMA_DIFF*/ {} /**SCHEMA_DIFF*/ ,
        methods: /**SCHEMA_DIFF*/ {
            openRecepientLookupEmail: function() {
                var lookup = this.getLookupConfig("Recepient");
                lookup.config.actionsButtonVisible = false;
                var searchValue = this.get("RecepientLookupSearchValue");
                if (searchValue) {
                    lookup.config.searchValue = searchValue;
                }
                LookupUtilities.Open(this.sandbox, lookup.config, lookup.callback, this, null, false, false);
            },
 
            getLookupConfig: function(columnName) {
                var scope = this;
                var callback = function(args) {
                    scope.onLookupSelected(args);
                };
                return {
                    config: {
                        entitySchemaName: "VwRecepientEmail",
                        columnName: columnName,
                        columns: ["ContactId"],
                        filters: this.returnNewFilter(),
                        multiSelect: true
                    },
                    callback: callback
                };
            },
            returnNewFilter: function() {
                    var filters = Ext.create("Terrasoft.FilterGroup");
			                filters.logicalOperation = Terrasoft.LogicalOperatorType.OR;
			                // filters.add("ActiveFilter", 
			                //     Terrasoft.createColumnFilterWithParameter(
			                //         Terrasoft.ComparisonType.EQUAL, "Active", true
			                //     )
			                // );
 
 
			                // Get [Id] of card object.
 
			                const split = window.location.href.split("/");
			                const id = split[split.length - 1];
 
							// Create Terrasoft.EntitySchemaQuery class instance with [Contact] root schema.
							var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
							    rootSchemaName: "Case"
							});
							// Add column with name of main contact of accounts that refers to given contact.
							esq.addColumn("Account.Id", "AccountId");
							// Get one record from selection on the basis of [Id] of card object and display it 
							// in an info window.
							esq.getEntity(id, function(result) {
							    if (!result.success) {
							        // error processing/logging, for example
							        this.showInformationDialog("Data query error");
							        return;
							    }
 
							    const accountId = result.entity.values.AccountId;
 
 
							    // Creation of query instance with "Contact" root schema. 
								var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
								    rootSchemaName: "Contact"
								});
								esq.addColumn("Id");
								esq.addColumn("Account");
								esq.filters.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
								// Creation of the first filter instance.
								var esqIdFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", accountId);
								// Filters will be updated by OR logical operator in query filters collection. 
								var ourAccountFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", Terrasoft.SysValue.CURRENT_USER_ACCOUNT.value);
 
								// Adding created filters to collection. 
								esq.filters.add("esqIdFilter", esqIdFilter);
								esq.filters.add("ourAccountFilter", ourAccountFilter);
								let count = 0;
								// This collection will include objects, i.e. query results, filtered by two filters.
								esq.getEntityCollection(function (result) {
								    if (result.success) {
								        result.collection.each(function (item) {
 
								        	filters.add(`Filter${count}`, 
							                    Terrasoft.createColumnFilterWithParameter(
							                        Terrasoft.ComparisonType.EQUAL, "ContactId", item.values.Id
							                    )
							                );
 
							                count++;
 
								        });
								    }
								}, this);
 
							}, this);
 
 
			                setTimeout(function(){}, 8000);
 
			                return filters;
            }
        }/**SCHEMA_DIFF*/ ,
        diff: /**SCHEMA_DIFF*/ [] /**SCHEMA_DIFF*/
    };
});

Any help appreciated.

Tyler Rainey,

 

Could you please specify what does not work for you? Are you able to load the "Case" section and open a lookup? Do you see contacts connected to the account or all contacts you have in a system? Are we talking about the modal window lookup? The result should be displayed there. Are there any errors in the console?

 

Regards,

Anastasiia

Anastasiia Markina,

I am able to load the case section. I do not see only contacts connected to the account. I see all the contacts in the system. Yes, this is for the modal box. I don't see errors in the console.

Thanks!

Tyler Rainey,

Tyler, I've not read through all your code, but glanced through it. I would assume that the issue is that in the function that returns the filters, you're using asynchronous ESQ queries. In doing so, the rest of the function continues and returns the result before the ESQ has returned. I assume that is what your setTimeout is attempting to do (wait until they've returned) but that just creates another callback, it won't stop the original function from returning.

You'll likely need to rethink how things are working. I would probably try using the sandbox in address mode to ask the case page for the values and return the contact Id list to the EmailMessagePublisherPage. You could pre-fetch the contact Id list on the case page in the onEntityInitialized and store in a collection attribute so they're ready to go when asked for by the sandbox message. Just throwing some ideas out there.

Ryan

Ryan Farley,

Worked great! Thank you.

Hi Tyler,

 

Could you please share your code and let us see how it works now? How were you able to solve the case? Looking forward to hearing from you! 

 

Regards,

Anastasiia

Anastasiia Markina,

Yes,

here is the "EmailMessagePublisherPage" code.

messages: {
			    "GetContactIds": {
			        mode: this.Terrasoft.MessageMode.PTP,
			        direction: this.Terrasoft.MessageDirectionType.PUBLISH
			    }
			}
"Recipient": {
			        "dataValueType": Terrasoft.DataValueType.LOOKUP,
			        "lookupListConfig": {
			            "filters": [function() {
 
			            	const contactIdArr = this.sandbox.publish("GetContactIds", null, ["EmailMessagePublisherPage"]);
 
			                var filters = Ext.create("Terrasoft.FilterGroup");
			                filters.logicalOperation = Terrasoft.LogicalOperatorType.OR;
 
			                contactIdArr.forEach(function(id, index) {
 
								filters.add(`AccountFilter=${index}`, 
								    Terrasoft.createColumnFilterWithParameter(
								        Terrasoft.ComparisonType.EQUAL, "ContactId", id
								    )
								);
 
 
			                });
 
 
			                return filters;
			            }]
			        }
			    }

here is the "CasePage" code

messages: {
		    "GetContactIds": {
		        // Message type – address.
		        mode: this.Terrasoft.MessageMode.PTP,
		        // Message direction – publication
		        direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
		    }
		},
		attributes: {
			"AccountContactIds": {
				"dataValueType": this.Terrasoft.DataValueType.COLLECTION,
				"type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				"value": "NameValue"
			}
		},
		methods: {
			init: function() {
				this.callParent(arguments);
				this.sandbox.subscribe("GetContactIds", this.getContactIds, this, ["EmailMessagePublisherPage"]);
			},
			onEntityInitialized: function() {
				this.callParent(arguments);				
				this.setAccountContactIds();
			},
			getContactIds: function() {
				return this.get("AccountContactIds");
			},
			setAccountContactIds: function() {
				const contactIdArr = [];
				const accountId = this.get("Account").value;
 
				var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
				    rootSchemaName: "Contact"
				});
				esq.addColumn("Id");
				esq.addColumn("Account");
				esq.filters.logicalOperation = this.Terrasoft.LogicalOperatorType.OR;
				// Creation of the first filter instance.
				var esqIdFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", accountId);
				// Filters will be updated by OR logical operator in query filters collection. 
				var ourAccountFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", Terrasoft.SysValue.CURRENT_USER_ACCOUNT.value);
 
				// Adding created filters to collection. 
				esq.filters.add("esqIdFilter", esqIdFilter);
				esq.filters.add("ourAccountFilter", ourAccountFilter);
				// This collection will include objects, i.e. query results, filtered by two filters.
				esq.getEntityCollection(function (result) {
				    if (result.success) {
				        result.collection.each(function (item) {
				        	contactIdArr.push(item.values.Id);
				        });
				        this.set("AccountContactIds", contactIdArr);
				    }
				}, this);
			},
		}

 

Tyler Rainey,

 

Thanks for sharing!

 

Regards,

Anastasiia

Show all comments