Hi everyone!

 

I am stuck with the BP, hope you can help me out.

 

I have a detail with duplicate records in it. These records are automaticaly added after the certain emailing (via webhooks). The issues is there are duplicates and I do need them - I need some of them be deleted and at least one should be staying (see image below). 

 

I cannot understand how to write the deleting part in business process

 

Like 1

Like

1 comments

Hello,

Basically, when a webhook comes to the system, there is no process of searching for duplicates, so that duplicate records could be created. However, you can create a business process in which you can use the Find and merge duplicate process element to search and merge these records.

Best regards,
Antonii.

Show all comments

Hi Community,

 

We are trying to create a filter for this detail, that will use two conditions (one for each column) and a logical operator of “OR”. So basically, we only want the records that have the main record id on one of these columns (Contrato or Contrato Umbrella).

 

 

To achieve this, we first tried to add the filter using the FreedomUI Page Designer. However, the filter does not work with the logical operator “OR”.

 

 

So we needed to add it manually, through code. By following this post https://community.creatio.com/questions/detail-filter-freedom-ui. But that didn’t work.

 

 

An alternative was to add the filter in the viewModelConfigDiff section, but we don’t know how can we make the value dynamic.

 

 

Could you please help us find a solution to this problem?

 

Thank you.

Like 3

Like

1 comments

Hello Pedro,

Please review one of the community questions to find the example of Terrasoft.LogicalOperatorType.OR usage.

Additionally here is an explanation of how filtration on Detail work for FreedomUI. 

Case description:
On Contacts page there is a Job experience detail with listed companies where the person worked. Our goal is to show only those departments in the department field that are specified for chosen employer (Account object). So, for this case, Alpha Business has only 2 departments listed in the Departments detail. We only want to see those 2 departments when choosing a department for this account on Job experience detail on Contact page. 

For filtering we basically need just 2 base handlers to be triggered:

  1. crt.DataGridActivateRowBusinessRulesRequest – triggered when we click on an existing detail row or add a new one.
  2. crt.HandleViewModelAttributeChangeRequest – triggered when we change a value of fields.

We also need to create our own handler which we can name usr.ApplyDepartmentFilter. This one would find the currently active row of our detail to have access to its manipulations. After that, we check if account field is filled in and if yes, we create a filter for the Department field. To apply it, we need to use setValue method by targeting filterAttributeName that can be created using the formula: 
"{detailName}DS_{targetFieldName}_List_BusinessRule_Filter".
After that, it is important to use markAsPristine method to make sure that the attribute is applied silently, without forcing us to save the row.

As for crt.DataGridActivateRowBusinessRulesRequest, here we just need to filter it by request.dataGridViewElementName === "CareerList" to target only the detail needed and then call the execution of usr.ApplyDepartmentFilter request that was added earlier.

In crt.HandleViewModelAttributeChangeRequest handler we need to cover the situation when the Employer (Account) field is changed to update the filtration for Department field. First of all, we check if request.attributeName === "CareerList". After that we select the active row and get control over Account field. We check if it’s changed by using account?.dirty property and also if it has value with account?.value?.value, because we would want to filter Department field only in case the Employer is filled in. If those 2 conditions are met, we use markAsPristine method for the account field attribute. We use this one here because it will allow us to handle the subsequent changes of the Employer field. Without it, the field will remain dirty until we save the row. Eventually, we need to set value of the Department field to null using: row?.getAttributeControl(attributeName + "DS_Department").setValue(null, {silent: true});
After that, the usr.ApplyDepartmentFilter handler can be executed to apply the filtration of Department field by Employer.

Show all comments

Hello creatio community,

 

I am trying to apply a filter into cases mini page which is developed using freedom ui screens. Code as below:

{
	request: "crt.LoadDataRequest",
	handler: async (request, next) => {
 
		if(request.dataSourceName == "CaseDS_OPCaseType_4943d10_List_DS") {
			const caseType = await request.$context.CaseDS_OPCaseType_4943d10;
 
			var moduleTypesIds = await OPPermissionFunctionsSsp.getModuleTypes();
 
			const filter = new sdk.FilterGroup();
			if(moduleTypesIds.length > 0){
				filter.logicalOperation = sdk.LogicalOperatorType.Or;		
				for (let i = 0; i < moduleTypesIds.length; i++) {
					await filter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, "Id", moduleTypesIds[i].value);
				}
			}
			else{
				await filter.addSchemaColumnFilterWithParameter(sdk.ComparisonType.Equal, "OPCode", '');
			}
 
			const newFilter = Object.assign({}, filter);
			newFilter.items = filter.items;
 
			request.parameters.push({
				type: "filter",
				value: newFilter
			});
		}
		return await next?.handle(request);
	}
}

 

The filter newFilter shows the right filter condition. I also used sql profiler and it returned the correct values. The issue here is that the CaseDS_OPCaseType_4943d10_List_DS lookup its not showing any value and does not apply the developed filter.

 

This issue happens only in the mini page. I have used this approach in freedom ui form pages and it works fine. Is there something I'm missing?

 

Kind regards

Like 0

Like

2 comments

I assume this is a dropdown lookup and not a lookup that opens the Select dialog? 

I just double-checked and I do have similar code to filter a dropdown on a Freedom UI mini page/dialog and it is working. I don't see anything that looks incorrect in the code you posted - just wanted to confirm that it does work on mini pages (at least in my case it is)

Show all comments

Hey Guys, we are using Creatio marketing to send newsletters but when we send campaign or test emails, all the links are not working meanwhile in builder when we click on them they work fine. Is it due to tracking or something else? How to fix this?

Like 0

Like

1 comments

When you send the emails the links are changed to go through the tracking links. In the Domain setup in Creatio it has you create a CNAME DNS entry for "tracking" and links in the email are changed to go through "tracking.thedomain.com" - have you set up that CNAME DNS entry?

Ryan

Show all comments

Hello 
It 's possible to add business process buton on Mobile App Freedom Ui in section , or section page.

 

Thank you 

Like 0

Like

1 comments

Hello Safa,

Unfortunately, there is no no-code way to add the custom button. We've already registered the suggestion for the R&D team.

 

Meanwhile, this article explains how to create a custom button. Please follow the release updates to find out when SDK for Mobile will be implemented.

Show all comments

Hello,

 

In the development version (on-site deployment), is it possible to configure webhooks to receive information from Microsoft Power Automate?

Like 3

Like

1 comments

Hello,

 

There are several limitations in working with webhooks: 

  • Only POST request method is supported.
  • Only JSON and FormData request header types are supported.
  • Any webhook sending frequency is supported.

 

As long as Microsoft Power Automate can fit into these limitations, it is possible to configure webhooks to receive information from it.

 

Here is the article that might be useful for you: https://academy.creatio.com/docs/8.x/no-code-customization/base-integra…

Show all comments

Hi community,

Calling a Business process is quite easy in FreedomUI, by adding a button and choosing

Action: Run process.

The problem with this approach is that once the button is clicked, there is no validation happening in the page.

Is there any code snippet or workaround that when clicking a button that runs a business process, prior to the calling of the process a validation(practically a Save) happens?

Sasori

Like 1

Like

6 comments

The only option currently is to wire up code for the button. It would first save the page, then if the save was successful you would execute the process. 

See how to save the page and detect if it was successful here: https://customerfx.com/article/saving-a-page-before-some-action-on-a-creatio-freedom-ui-page/

See how to start the process via code here: https://customerfx.com/article/starting-a-process-from-client-side-code-on-a-creatio-freedom-ui-page/

Ryan

Ryan Farley,

Thanks for the response Ryan. Do you actually have an example on how to integrate within the 'CustomMethod' both crt.SaveRecordRequest and crt.RunBusinessProcessRequest ?

Ryan Farley,

Ryan if im not mistaken, with the suggested approach , every time the user will click the SAVE button, the overriden crt.SaveRecordRequest will be called?

In the first linked example, you would only be running that `usr.CustomCodeRequest` handler when you click your custom button. If you put the code inside the crt.SaveRecordRequest handler, then it would be run every time the user saved the page in some way.

Sasori Oshigaki,

As Harvey mentioned, the code for your button will only execute when the button is clicked, not when the Save is clicked. Your button will also initiate a save and then, if successful and validated (and the save occurred) it will then execute the process. The code from the first article triggers the save to happen and then provides the result. In the article (the first one) the save returns a result, where the code has // save was successful, continue with something else here you'd replace that with the code to start the process (the second article). If needed, you can see how to wire up custom code to your button in this article: https://customerfx.com/article/adding-a-button-to-execute-custom-code-on-a-creatio-freedom-ui-page/

Ryan

Thank you  both Ryan and Harvey! Was able to achieve what i intended!

     {
    request: "so.SaveAndRunBP",
    handler: async (request, next) =&gt; {
            const saveRecordRequest = {
            type: "crt.SaveRecordRequest",
            preventCardClose: true,
            $context: request.$context
        };
        if ((await request.$context.executeRequest(saveRecordRequest)))
        {
          const handlerChain = sdk.HandlerChainService.instance;
          const result = await handlerChain.process({
              type: "crt.RunBusinessProcessRequest",
              processName: "SoGenerateContact",
              processParameters: {
                  ContactId: await request.$context.Id,
              },
              $context: request.$context
          });
        }
        return next?.handle(request);
    }
}
Show all comments

I have a detail "OrderProductDetailV2" (editable registry), in which I added my totals to "summaryItemsContainer". When changing a record in the detail, quantity, price, etc., I need to update my signatures, since the standard ones are updated (number of records, total amount). I've read many articles. I've figured out how the standard modules work. Everything is clear. I've tried different options through messages, with "onDataChanged" I get a cycle, in another option my signatures are updated, but the standard ones stop updating. Can anyone help?

Like 0

Like

1 comments

Hello,

The base logic of updating Amount and Total columns is mostly located inside the event logic of objects OrderProduct and Order. You can add your logic of updating fields using the same event logic or business process. There is definitely a risk of ending up in a loop, unfortunately, there are no recommendations to avoid it, you just need to pay attention to your code. But, because the base update is handled in event logic, you can update your values without triggering the event logic, for example with direct DB request or class Update. 

Show all comments

I want to add contact object and the dropdown values should be the contact object column value. suppose I have a column name full name. its value i don't want as my lookup value. i want the full name column as my lookup value. is it possbile automatically?

Like 1

Like

1 comments

Hello,

 

The search field in the lookup column displays the object parameter — displayedColumnValue, which is usually the name column.
You can change this column to any other object field, but it will apply to the entire system — meaning this column will act as a link to the record. It will be used in filters and during selection. I suggest setting up quick filters and adding the contact value link there.

Show all comments

Hi, 

I have some hard times trying to iterate an array of object and insert/display the values one by one on this object detail named Product in Receive

 

and here is a chunk of the code:

var splitResult = decodedText
          .split("*")
          .filter((item) => item.trim() !== "");
        var doNumber = splitResult[0];
        var prodDataObj = [];
        var slocCode = doNumber.split("/")[1];
 
        for (let i = 1; i < splitResult.length; i++) {
          var prodDataSplit = splitResult[i].split("/");
          var productName = "";
          var materialcode = prodDataSplit[1] || "";
 
          if (materialcode) {
            productName = await new Promise((resolve) => {
              Terrasoft.productByMaterialCode(materialcode, (productData) => {
                if (productData && productData.Name) {
                  resolve(productData?.Name || "");
                }
              });
            });
          }
          prodDataObj.push({
            Line: prodDataSplit[0] || 0, //line number
            MaterialCode: prodDataSplit[1] || "", //mat code
            ProductName: productName,
            Quantity: prodDataSplit[2] || 0, //quantity
            UoM: prodDataSplit[3] || "", //uom
          });
        }
prodDataObj.forEach((data) => {
          const newRecord = Ext.create("Terrasoft.BaseModel", {
            modelName: "UsrEntity_93626c0",
          });
 
          newRecord.set("UsrSKUName", data.ProductName, true);
          newRecord.set("UsrQty", data.Quantity, true);
 
          Terrasoft.getUom(data.UoM, (record) => {
            newRecord.set("UsrUoM", record, true);
          });
 
          newRecord.save({
            isCancelable: false, 
            success: function (savedRecord) {
 
              const pageController = Terrasoft.PageNavigator.getLastPageController();
              pageController.refreshDirtyData();
            },
            failure: function (error) {
              console.error("Failed to create record:", error);
            },
          });
        });

i tried to iterate using forEach but when i use newRecord.save, some weird error appears, this is one of them: 

Error in Success callbackId: TSQueryExecutorPlugin1965367711 : TypeError: Cannot read properties of undefined (reading 'rule')

 

I would greatly appreciate any assistance or guidance in resolving this issue.
Thank you.

 

Like 1

Like

1 comments

Hello,
In this situation, only the full debug of the set code can tell what exactly went wrong. Based on the code alone it is impossible to tell where is the issue in it.
The error "TypeError: Cannot read properties of undefined (reading 'rule')" doesn't tell much easier, with it we can only tell that at some point the system didn't receive a correct parameter or didn't receive anything at all, either way, a debug is still needed.

Show all comments