Studio_Creatio
8.0

Hello community

Is it possible to export on excel the duplicates for accounts?

Like 0

Like

5 comments

Hello,

Unfortunately, there is no built-in way to export all duplicates directly.

However, as a workaround, you can use one of the following approaches:

Option 1: Find duplicates directly in the database

You can identify duplicate records using an SQL query and then export the results manually.

SELECT email, COUNT(*)
FROM users
GROUP BY email
HAVING COUNT(*) > 1;


Option 2: Export data and use Excel to find duplicates

Export the dataset from your system to Excel (or CSV).

In Excel:

  • Select the relevant column(s).
  • Go to Home → Conditional Formatting → Highlight Cells Rules → Duplicate Values to highlight duplicates.

Hello Halyna,
 the results of duplicates search is complicated to reproduce using sql query.

I used postman and I called the following web service  {{BaseURI}}/0/rest/BulkDeduplicationService/GetGroupsOfDuplicates passing the following json

{
    "entityName": "Contact",
    "columns": [
        "Name",
        "Account
        "CreatedBy"
    ],
    "offset": 0,
    "count": 1000,
    "topDuplicatesPerGroup": 5,
    "filters": "{\"items\":{},\"logicalOperation\":0,\"isEnabled\":true,\"filterType\":6}"
}

If you want to get a rough equivalent using SQL - for example, to find contacts with identical or very similar names - you could try something like:

SELECT 
   Name,
   AccountId,
   CreatedById,
   COUNT(*) AS DuplicateCount
FROM Contact
WHERE Name IS NOT NULL
GROUP BY Name, AccountId, CreatedById
HAVING COUNT(*) > 1
ORDER BY DuplicateCount DESC;

This will show exact duplicates (same Name + Account + CreatedBy).

Hi, 

Duplicate management needs some improvement. Finally,  in 8.3.1 we can manually merge records.  

But we should be able to see total numbers of duplicates based on our duplicate rules etc.. 

Functionality has not evolved much for years (even lacking in Freedom UI for manual merge until now) and customer non-admin end-users are not satisfied with its functionality.

Marketing teams should be able to manage this without having to develop SQL programming knowledge or export excel lists. 

Customer data management is imperative, with contacts changing companies often, and this part is far from be up-to-standards with what Freedom UI offers. 

Simply have a list of duplicates and not even being able to provide some statistics without querying the db directly is something that end-users have a lot of difficulty accepting, considering what exists on the market today.

Damien Collot,

100% agree on this, there needs to be better tooling for handling this on the user end, with any appropriate guardrails that can be put in place via customisation for such actions.

Show all comments

Chart setup page with calculation of average duration in minutes

Take for example this setup,  Status change history is similar to Case Lifecycle in Cases, I want to find a way to add status ranges as 2 - Quick filters configured to Lookup- Status, with intended behavior as 1 Filter will initial status and 2nd Filter will be the final status and I will calculate the duration (average) for cases.

So the query will be -  Find average duration of cases moving from one status to another. 

  Version 8.3.0.3031
 

Like 1

Like

3 comments

If not can anyone help me with a correct approach for this, thanks for the help :) 

Hello!
In Creatio, it’s not possible to directly pass variables into filters. 

However, as a workaround, the user can create a custom view, similar to the one used for Opportunities — “View for analysis of sales by stages”.

Additionally, it’s possible to:

  • Install the Calculated Metrics for Creatio
    add-on from the Marketplace to calculate average values, or
  • Develop a custom business process to compute such data automatically.
     

Hello Valeriia,

Thanks for the reply. I will experiment with the approaches will let you know what worked best for me. 

 

 

Thanks

Rishav

Show all comments
Studio_Creatio
8.0

I am facing this issue and can't find the root cause or solution.

Last thing I did. I was editing form page and add extended panel and button also add some code in the source code of the page for the function of the button
But I can't save these changes because there was DB relation error.
By mistake, I closed the browser, and when tried to access it today got this error. 

Like 0

Like

1 comments

Hello Ahmed!

I hope this message finds you well!

Unfortunately, from the screenshot, the error is not really clear. We recommend checking the application logs for a more clear error message.

If you will not be able to identify and fix the issue on your own, please contact our support team at support@creatio.com

Have a great day!

Show all comments
remote_module
databinding
Studio_Creatio
8.0

Hi,

I am trying to pass few values to my remote module from the page schema but I am not receiving the values instead getting undefined. 

Am I missing something?


Like 1

Like

2 comments

The issue is that the values have not yet been set/bound in the init. Instead of retrieving them in the ngOnInit try using the ngOnChanges instead.

Ryan Farley,

Thank you.. that worked

Show all comments
Studio_Creatio
8.0

Hi Everyone,

Following this article - Add an individual portal user

I have to create a system user account for the portal user and manually create the username and password. Did not found an option of sending invites. 


I am looking for an out-of-the-box solution in Creatio that allows us to simply create contact records for these users and automatically send them an email with a portal invitation link. The users should be able to click the link, set their own password, and have their system user account automatically created and linked to their contact record—without manual user creation or password sharing.

Does Creatio provide such an OOTB workflow or feature? If yes, what is the best way to implement this, and are there any tips or recommended configurations?

Thank you in advance for your insights!

Like 0

Like

2 comments

Hi Akshit,

Thank you for your query.

Currently, Creatio does not provide an out-of-the-box process that automatically sends portal invitation emails upon creating contact records.

However, you can use the steps described in the Send portal invitations article to manually send portal invitation emails.
After adding a new portal user, simply click [Send invites] — this triggers an email with a one-time link for the user to set their password and access the portal.

This process ensures that users with the appropriate functional roles receive their credentials securely and gain access to the portal.

Alternatively, you can use the base business process available in the Process Library as a reference and adapt or duplicate it to create your own automated invitation flow.

Thank you!

Valeriia Hromova,

Thanks,

Can you please tell me the Business process name? 

Show all comments
edit page
Studio_Creatio
7.17

Hi;
I develop an edit page with planty of details
It happens that after page loaded a detail is empty even it has data
After page reloaded the detail get data.
if i use this.updateDetila method on EntityInitialzed event it solve the problem?

Regards
Tomek

Like 0

Like

2 comments

Hello,

You can resolve this by forcing the detail to refresh after the main record is initialized. To do this, please add the following code to your edit page schema:

onEntityInitialized: function() {
   this.callParent(arguments);
   this.updateDetail({
       detail: "YourDetailName",
       reloadAll: true
   });
}

Replace "YourDetailName" with the internal name of your detail.

Please make sure to call this.callParent(arguments) before this.updateDetail(...). This ensures that the base initialization logic runs first, and only after that the detail is refreshed correctly, otherwise the system might not yet have the necessary context for loading related data.

Adding reloadAll: true ensures the detail reloads with all required filters and parameters. Without this parameter, the method may trigger an unfiltered database query, which can lead to slow performance or UI freezing when the detail contains many records.

This ensures the detail refreshes and displays its data right after the page loads.

More information about configuring details:
Creatio Academy Detail overview

Daiana Gavrylenko,

ThankYou

Show all comments

I am trying to write attachments directly to the message composer from a separate list however, I can't figure out if there is a way to replicate what the button shown below does but through code. Anyone tried this:

Like 1

Like

2 comments

Hi!,

We have checked the possibility of adding attachments directly to the out-of-the-box Message Composer via code. At the moment, Creatio does not provide a supported interface or API that allows files to be programmatically inserted into the Message Composer in the same way the attachment button does. This component is not currently extensible in that regard.

Jakub Wieczorek,

Hi Jakub, 

Thank you very much for clarifying that, is there any other way to do this?

Show all comments
edit page
#BusinessProcess
Studio_Creatio
8.0

Hi All,

 

I have a BP with few elements, including the Edit Page element.

Problem is that, after opening the Page and hitting cancel, it does not cancel the process, so it get stucked in Running status.

I would like to use this action "Cancel" to setup the Business Process to handle with this information on a conditional flow. Is it possible?

Like 0

Like

2 comments

Hi Paulo,

Thanks for raising this question. The behavior you’re describing is actually expected in the current versions of Creatio. The Edit Page element in a Business Process does not “cancel” the process itself when the user presses the Cancel button.

Here’s how it works:
- If all required fields on the page are filled in and the user presses Cancel, the Edit Page element will be considered completed, and the process will continue according to the next flow.
- If required fields are not filled in and the user presses Cancel, the element is not completed, which means the process stays in the Running state and the conditional “Cancel” branch won’t be triggered. That’s why you see it “stuck.”

As a workaround, you can:
1. Set all fields optional by default.
1.1 Add the checkbox to the page (for example "make required").
1.2 Create a business rule for the fields:
      - If the checkbox is checked the fields become required, so the user must fill them in to proceed.
      - If the checkbox is unchecked the fields stay optional, and the process can be canceled without blocking.
2. Use only optional fields.
3. Use Classic UI (7.x) pages.

You could also try this approach where the edit page task gets canceled after a certain period of time: https://customerfx.com/article/automatically-cancelling-user-tasks-afte…

Show all comments
filter
8.2.3
Studio_Creatio
8.0
I have quick filter and i wanna set dynamically filters for each quick filter (related Filter).
Do you have solutions for my case? try to bind the value but not worked.
 
{
                    "operation": "insert",
                    "name": "QuickFilter_kp8pw59",
                    "values": {
                        "layoutConfig": {
                            "column": 9,
                            "colSpan": 2,
                            "rowSpan": 1,
                            "row": 1
                        },
                        "type": "crt.QuickFilter",
                        "config": {
                            "caption": "#ResourceString(QuickFilter_kp8pw59_config_caption)#",
                            "hint": "",
                            "icon": "filter-column-icon",
                            "iconPosition": "left-icon",
                            "defaultValue": [],
                            "entitySchemaName": "BsiArea",
                            "recordsFilter": {
                                "filterType": 6,
                                "items": {
                                    "byRegion": {
                                        "filterType": 1,
                                        "comparisonType": 3,
                                        "isEnabled": true,
                                        "leftExpression": {
                                            "expressionType": 0,
                                            "columnPath": "BsiRegion"
                                        },
                                        "rightExpression": {
                                            "expressionType": 2,
                                            "parameter": {
                                                "dataValueType": 10,
                                                "value": "SelectedRegionId"   // bind ke attribute
                                            }
                                        }
                                    }
                                }
                            }
                        },
 
Updated :
 
handlers: /**SCHEMA_HANDLERS*/[
			{
				request: "crt.HandleViewModelAttributeChangeRequest",
				handler: async (request, next) => {
					const regionQFAttrName = "QuickFilter_Region_Value"; // Region
					const areaQFAttrName = "QuickFilter_Area_Value"; // Area
					const outletQFAttrName = "QuickFilter_Cabang_Value"; // Outlet
 
					if (request.attributeName !== regionQFAttrName && request.attributeName !== areaQFAttrName) {
						return next?.handle(request);
					}
 
					const areaQFFilterAttrName = "QuickFilter_Area_ComboBox_List_Filter";
					const outletQFFilterAttrName = "QuickFilter_Cabang_ComboBox_List_Filter";
					const areaRegionColumnName = "BsiRegion";
					const outletRegionColumnName = "BsiRegion";
					const outletAreaColumnName = "BsiArea";
 
					const areaFilter = new sdk.FilterGroup();
					areaFilter.logicalOperation = sdk.LogicalOperatorType.Or;
					const outletFilter = new sdk.FilterGroup();
					outletFilter.logicalOperation = sdk.LogicalOperatorType.And;
					const outletFilterByRegion = new sdk.FilterGroup();
					outletFilterByRegion.logicalOperation = sdk.LogicalOperatorType.Or;
					const outletFilterByArea = new sdk.FilterGroup();
					outletFilterByArea.logicalOperation = sdk.LogicalOperatorType.Or;
 
					if (request.attributeName === regionQFAttrName) {
						let currentAreaValue = await request.$context[areaQFAttrName];
						const needAdditionalConfigurateoutletFilter = Array.isArray(currentAreaValue) && currentAreaValue.length > 0;
 
						if (Array.isArray(request.oldValue) && Array.isArray(request.value) && request.value.length > request.oldValue.length) {
							currentAreaValue = [];
							request.$context[areaQFAttrName] = [];
							request.$context[outletQFAttrName] = [];
						}
 
						if (Array.isArray(request.value) && request.value.length > 0) {
							for (var i = 0; i < request.value.length; i++) {
								await areaFilter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, areaRegionColumnName, request.value[i].value);
								await outletFilterByRegion.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletRegionColumnName, request.value[i].value);
							}
							outletFilter.add(outletFilterByRegion);
						}
 
						request.$context[areaQFFilterAttrName] = areaFilter;
 
						if (needAdditionalConfigurateoutletFilter) {
							for (var i = 0; i < currentAreaValue.length; i++) {
								await outletFilterByArea.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletAreaColumnName, currentAreaValue[i].value);
							}
							outletFilter.add(outletFilterByArea);
						}
 
						request.$context[outletQFFilterAttrName] = outletFilter;
					}
 
					if (request.attributeName === areaQFAttrName) {
						const currentRegionValue = await request.$context[regionQFAttrName];
						const needAdditionalConfigurateoutletFilter = Array.isArray(currentRegionValue) && currentRegionValue.length > 0;
 
						if (Array.isArray(request.value) && request.value.length > 0) {
							for (var i = 0; i < request.value.length; i++) {
								await outletFilterByArea.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletAreaColumnName, request.value[i].value);
							}
							outletFilter.add(outletFilterByArea);
						}
 
						if (needAdditionalConfigurateoutletFilter) {
							for (var i = 0; i < currentRegionValue.length; i++) {
								await outletFilterByRegion.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletRegionColumnName, currentRegionValue[i].value);
							}
							outletFilter.add(outletFilterByRegion);
						}
 
						request.$context[outletQFFilterAttrName] = outletFilter;
					}
 
					return next?.handle(request);
				}
			},
			{
				request: "crt.HandleViewModelInitRequest",
				handler: async (request, next) => {
					const regionQFAttrName = "QuickFilter_Region_Value";
					const areaQFAttrName = "QuickFilter_Area_Value";
					const currentRegionValue = await request.$context[regionQFAttrName];
					const currentAreaValue = await request.$context[areaQFAttrName];
					const hasRegionValue = Array.isArray(currentRegionValue) && currentRegionValue.length > 0;
					const hasAreaValue = Array.isArray(currentAreaValue) && currentAreaValue.length > 0;
 
					if (!hasRegionValue && !hasAreaValue) {
						return next?.handle(request);
					}
 
					const areaQFFilterAttrName = "QuickFilter_Area_ComboBox_List_Filter";
					const outletQFFilterAttrName = "QuickFilter_Cabang_ComboBox_List_Filter";
					const areaModelColumnName = "BsiRegion";
					const outletRegionColumnName = "BsiRegion";
					const outletAreaColumnName = "BsiArea";
 
					const areaFilter = new sdk.FilterGroup();
					areaFilter.logicalOperation = sdk.LogicalOperatorType.Or;
					const outletFilter = new sdk.FilterGroup();
					outletFilter.logicalOperation = sdk.LogicalOperatorType.And;
					const outletFilterByRegion = new sdk.FilterGroup();
					outletFilterByRegion.logicalOperation = sdk.LogicalOperatorType.Or;
					const outletFilterByArea = new sdk.FilterGroup();
					outletFilterByArea.logicalOperation = sdk.LogicalOperatorType.Or;
 
					if (hasRegionValue) {
						for (var i = 0; i < currentRegionValue.length; i++) {
							await areaFilter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, areaModelColumnName, currentRegionValue[i].value);
							await outletFilterByRegion.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletRegionColumnName, currentRegionValue[i].value);
						}
						outletFilter.add(outletFilterByRegion);
 
						request.$context[areaQFFilterAttrName] = areaFilter;
					}
 
					if (hasAreaValue) {
						for (var i = 0; i < currentAreaValue.length; i++) {
							await outletFilterByArea.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, outletAreaColumnName, currentAreaValue[i].value);
						}
 
						outletFilter.add(outletFilterByArea);
					}
 
					request.$context[outletQFFilterAttrName] = outletFilter;
 
					return next?.handle(request);
				}
			}
		]/**SCHEMA_HANDLERS*/,
Like 1

Like

3 comments

any one have idea?

Hi Fransetya Alfi Syahrin,

If I understand you correctly you are trying to dynamically change the filter value (SelectedRegionId).
Although there is no OOTB solution, you can try the following approach:

const quickFilter = await request.$context.QuickFilter_kp8pw59_Items_0_Arg_0;
quickFilter.target.customFilter.items.byLanguage.rightExpressions[0].parameter.value.value = SelectedRegionId; // assuming that SelectedRegionId is a variable that stores the Id

Hi Eduard Dovydovskyi,

Do I just add this _Items_0_Arg_0?

Show all comments
external
portal users
Studio_Creatio
8.0

Hello,

I have developed a custom component using remote module. its working fine for internal users.. but when I logged in as external user, all the APIs of my custom component are failing with 404 status code..

How do I fix this? TIA

Like 1

Like

6 comments

Configuration services exposed to external users need to have two changes:

First of all, the C# service itself needs to have the following attributes on the class:

[DefaultServiceRoute]
[SspServiceRoute]

You'll likely also need to add the using directives: 

using Terrasoft.Web.Common;
using Terrasoft.Web.Common.ServiceRouting;

Second of all, the url path to the service is different for external users. 

Full Creatio (internal) users will use: 

0/rest/UsrMyService/SomeMethod

External users will use: 

0/ssp/rest/UsrMyService/SomeMethod

You can use the following code, if needed, to get the correct path/url based on the user type, it will return the correct path for both user types: 

var workspaceBaseUrl = Terrasoft.utils.uri.getConfigurationWebServiceBaseUrl();
 
var servicePath = workspaceBaseUrl + "/rest/UsrMyService/SomeMethod";
 
//servicePath will now contain the correct URL for either user type

Ryan

Thank you. that worked

Ryan Farley,

Oops.. its not working.. 

the api path for internal users:
https://11007053-demo.creatio.com/0/rest/UsrCwService/CwGetRecordById

external users api path:
https://11007053-demo.creatio.com/0/ssp/rest/UsrCwService/CwGetRecordById

The external path looks good but still giving 404..

Sagar Rodda,

I assume you did also add the attributes to the C# service class and recompile? (Note, those are attributes for the class, not the method)

namespace Terrasoft.Configuration
{
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    using Terrasoft.Core;
    using Terrasoft.Web.Common;
 
    [DefaultServiceRoute]
    [SspServiceRoute]
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class UsrSourceCode1 : BaseService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        public string SayHelloTest(string Name)
        {
            return "Hello " + Name + "!";
        }
    }
}

Sagar Rodda,

Or can combine as: 

[DefaultServiceRoute, SspServiceRoute]

Ryan Farley,

Yeah, I overlooked the class part.. I added the attributes to methods that's why it was not working.. now its fixed.. thank you so much

Show all comments