Время создания
Filters
auto
filter
Studio_Creatio
8.0

Hi All, question please, so I want to auto filter (not static value) in List, filtered by field with data type Text. How to do that in Creatio, need advice please, thank you.

Capture :

I already tried, but I can not found the way. The only way I can found is Apply static filter from Properties, but it is not my expected. Capture :

I already tried with Business Process too, but the value is not my expected also, because it can not read specific filter result, the result is : showing all data.
Capture :

Need advice please, how to auto filter in List by parameter data type Text (not static filter) ?

Thank you.

Like 0

Like

1 comments

Hello!

The no-code designer cannot do this. The "Apply static filter" dialog only accepts constants or current-user macros, and a business process can populate data but cannot filter a list on a page. To filter a list by a Text field of the current record, you need a few lines of code in the page schema. This is the documented Creatio approach for dynamic list filters.

Every list on a Freedom UI page has a data source attribute in viewModelConfig.attributes with a filterAttributes array. You add your own filter attribute there, then set that attribute to a sdk.FilterGroup in a handler. Whenever the attribute changes, the list reloads with the new filter.

Step 1. Add the SDK dependency

At the top of the page schema (UsrPreScreening_FormPage or whatever your form page is named):

define("UsrPreScreening_FormPage", /**SCHEMA_DEPS*/["@creatio-devkit/common"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/(sdk)/**SCHEMA_ARGS*/ {

Step 2. Register a filter attribute on the list's data source

Find the data source for your Application list in viewModelConfig.attributes. It will look something like GridDetail_xxxx_DS or DataGrid_xxxx_DS. Add a new entry to its filterAttributes:

"GridDetail_Application_DS": {

    "isCollection": true,

    "modelConfig": {

        "path": "GridDetail_Application_DS",

        "filterAttributes": [

            { "name": "GridDetail_Application_PredefinedFilter", "loadOnChange": false },

            { "name": "GridDetail_Application_ActiveFilter", "loadOnChange": true },

            { "name": "UsrCustomerNameFilter", "loadOnChange": true }

        ]

    }

}

Keep the existing entries; only the last line is new. Also declare the attribute itself next to the others:

"UsrCustomerNameFilter": {}

 

Step 3. Build the filter in handlers

Add two handlers to the handlers array. The first sets the filter when the page opens. The second rebuilds it when the user edits Customer Name. Replace the attribute names with the real ones from your page (PDS_UsrCustomerName_xxxx and PDS_UsrApplicationNumber_xxxx), and the column names with the real Application object column codes.

handlers: /**SCHEMA_HANDLERS*/[
    {
        request: "crt.HandleViewModelInitRequest",
        handler: async (request, next) => {
            await next?.handle(request);
            await applyCustomerNameFilter(request.$context);
        }
    },
    {
        request: "crt.HandleViewModelAttributeChangeRequest",
        handler: async (request, next) => {
            if (request.attributeName === "PDS_UsrCustomerName_xxxx" && !request.silent) {
                await applyCustomerNameFilter(request.$context);
            }
            return next?.handle(request);
        }
    }
]/**SCHEMA_HANDLERS*/,

 

Then define the helper above the return { ... } of the schema module:

async function applyCustomerNameFilter(context) {
    const customerName = context.PDS_UsrCustomerName_xxxx;
    const appNumber = context.PDS_UsrApplicationNumber_xxxx;
    const filter = new sdk.FilterGroup();
    filter.logicalOperation = sdk.LogicalOperation.And;
    if (customerName) {
        await filter.addSchemaColumnFilterWithParameter(
            sdk.ComparisonType.Equal, "UsrCustomerName", customerName);
    } else {
        // no name yet: show nothing instead of everything
        await filter.addSchemaColumnFilterWithParameter(
            sdk.ComparisonType.Equal, "Id", "00000000-0000-0000-0000-000000000000");
    }
    if (appNumber) {
        await filter.addSchemaColumnFilterWithParameter(
            sdk.ComparisonType.NotEqual, "UsrApplicationNumber", appNumber);
    }
    // required workaround: the filter must be a plain object to trigger reload
    const plainFilter = Object.assign({}, filter);
    plainFilter.items = filter.items;
    context.UsrCustomerNameFilter = plainFilter;
}

 

The last three lines are not optional. The list only reloads when the attribute receives a new plain object, so copying the FilterGroup this way is the standard trick.

Notes

  • Use sdk.ComparisonType.Contain instead of Equal if you want partial matches on the name.
  • Column codes in addSchemaColumnFilterWithParameter are Application object column codes, not page attribute names.
  • If you also want Date of Birth or ID Card matching, add more conditions the same way.
  • The static filter you configured in the designer can stay or be removed. Your code filter combines with it through the PredefinedFilter attribute.

Alternative without code

If you can change the data model, make Customer a lookup object instead of a Text field and reference it from both the pre-screening record and the Application object. Then the standard list-to-page binding by lookup column filters automatically. That is the only no-code option, but it only works if a shared lookup makes sense for your data.

Show all comments

test

Like 0

Like

0 comments
Show all comments
calculate
summary
Studio_Creatio
8.0

Hi All, question please.

I already googling also searching in Creatio document, but I can not find the answer.

So, how to calculate total summary from all currencies values in Business Process?
There is no summary function there.


Capture :

 

Need advice please, thank you.

Like 0

Like

1 comments

Hello,

First of all you read only 1 record in the "Read Insurance" read data element (it can be seen from the "First item of resulting collection" macro value). The sum of this will always be the value you read. I think something else was intended here.

Next, you can use Enumerable.Sum method, but you need to get an enumerable. Or introduce a method that can be called inside a script task like (and add Terrasoft.Core.DB to the process usings):

protected decimal GetInsurancePremiTotal(Guid insuranceTypeId) { //or any other argument suitable
    var query = (Select)new Select(UserConnection)
        .Column(Func.Sum("UsrPremi")).As("TotalPremi")
        .From("UsrInsurance").As("usrInsurance").WithHints(new NoLockHint())
        .Where("usrInsurance", "UsrTypeId").IsEqual(Column.Parameter(insuranceTypeId));
    decimal totalPremi = 0;
    using (DBExecutor executor = UserConnection.EnsureDBConnection()) {
        totalPremi = query.ExecuteScalar<decimal>(executor);
    }
    return totalPremi;
}

And set the result to process parameter and then use this parameter value to proceed in the business process.

Show all comments
Studio_Creatio
8.0

Hi all, 

contrarily to normal quickfilters, there does not seem to be a nocode option to filter the owner in the timeline component using nocode tools. Any idea how to fitler the owner, for example by system users of a certain role ?



thanks, 

Damien

Like 0

Like

1 comments

Hello,

As far as I understood you need to filter options in the "Owner" filter dropdown list. There is only one option to do that - override the crt.LoadDataRequest as (and also include "@creatio-devkit/common" to the schema dependencies):

{
                request: "crt.LoadDataRequest",
                handler: async (request, next) => {
                    if (request.dataSourceName?.includes("ByOwnerQuickFilterInTimeline_ComboBox_List_DS")) {
                        const filterGroup = new sdk.FilterGroup();
                        await filterGroup.addSchemaColumnFilterWithParameter(
                            sdk.ComparisonType.Equal, "Name", "Supervisor"); //add other filters here
                            const filterParameter = {
                                type: "filter",
                                value: {
                                    filterType: 6,
                                    logicalOperation: 0,
                                    isEnabled: true,
                                    trimDateTimeParameterToDate: false,
                                    items: filterGroup.items
                                }
                            };
                            request.parameters = request.parameters
                                ? [...request.parameters, filterParameter]
                                : [filterParameter];
                    }
                    return await next?.handle(request);
                }
            }

You also need to confirm the data source name. The easiest way to do that is to add console.log("LoadDataRequest:", request.dataSourceName); to the crt.LoadDataRequest override and see which datasource is logged when you first click this "Owner" filter.

Show all comments
How_can_I_bind_record_permissions_for_a_custom_object_in_Creatio_8.0?

Hello,

I am working with Creatio 8.0 using Freedom UI and have created a custom object.

I have configured record permissions for this object and now I need to deploy/migrate these record-permission configurations to another Creatio environment using a package.

I would like to know:

  1. How can I bind these record permissions to my package so that they are automatically installed in another environment?
  2. Do I need to use a SQL script in the package to migrate these permissions?

I am specifically looking for the recommended approach for binding/deploying these record permissions through a package, rather than manually configuring them in each environment.

Any guidance or example would be greatly appreciated.

Thank you!

Like 0

Like

2 comments

Hello,

Record permission definitions are stored in the SysEntitySchemaRecordDefRight table, while the actual record-level permissions are stored in system-generated tables such as SysCaseRight, SysContactRight, or, in general, Sys[ObjectName]Right.

Unfortunately, neither SysEntitySchemaRecordDefRight nor Sys[ObjectName]Right records can be migrated using the standard OOTB data binding mechanism available in packages and require an SQL script to be transfered between environments.

Example you might find useful:

INSERT INTO "SysFolderTreeRight"("Id","RecordId","SysAdminUnitId","Operation","RightLevel","Position")
VALUES ('9f4d6f1c-74f6-4b2d-a7d6-1c9f0f9f0001','ac7a534b-046b-1534-78ac-1b946522dbaf','a29a3ba5-4b0d-de11-9a51-005056c00008',0,1,0)
ON CONFLICT ("Id") DO UPDATE SET
    "RecordId" = EXCLUDED."RecordId",
    "SysAdminUnitId" = EXCLUDED."SysAdminUnitId",
    "Operation" = EXCLUDED."Operation",
    "RightLevel" = EXCLUDED."RightLevel",
    "Position" = EXCLUDED."Position";

Hi Oshi Varshney,

Two tables are involved, and only one of them is usually worth migrating:

  • SysEntitySchemaRecordDefRight — the record permission rules you configured (which role gets Read / Edit / Delete by default). This is what you want to move.
  • Sys[YourObject]Right — the actual per-record rights generated at runtime. Leave these alone; the target environment regenerates them.

1. Find your object's SubjectSchemaUId

System Designer → Object permissions → search your object → open it. The UId is right there in the URL:

.../#/AdministratedObjects/25d7c1ab-1de0-4501-b402-02e0e5a72d6e

Or from SQL:

SELECT "UId" FROM "SysSchema" WHERE "Name" = 'UsrYourObject';

2. Generate the INSERT on Dev (PostgreSQL)

WITH TargetPermissions AS (
    SELECT "Id", "AuthorSysAdminUnitId", "GranteeSysAdminUnitId",
           "Operation", "RightLevel", "Position", "SubjectSchemaUId"
    FROM public."SysEntitySchemaRecordDefRight"
    WHERE "SubjectSchemaUId" = '<YOUR-OBJECT-UID>'::uuid
)
SELECT
  'INSERT INTO public."SysEntitySchemaRecordDefRight" ("Id", "AuthorSysAdminUnitId", "GranteeSysAdminUnitId", "Operation", "RightLevel", "Position", "SubjectSchemaUId") VALUES ' || CHR(10) ||
  string_agg(
      '    (' || COALESCE(quote_literal("Id"::text) || '::uuid', 'NULL') || ', '
      || COALESCE(quote_literal("AuthorSysAdminUnitId"::text) || '::uuid', 'NULL') || ', '
      || COALESCE(quote_literal("GranteeSysAdminUnitId"::text) || '::uuid', 'NULL') || ', '
      || COALESCE("Operation"::text, '0') || ', '
      || COALESCE("RightLevel"::text, '0') || ', '
      || COALESCE("Position"::text, '0') || ', '
      || COALESCE(quote_literal("SubjectSchemaUId"::text) || '::uuid', 'NULL') || ')',
      ',' || CHR(10)
  ) || CHR(10) ||
  'ON CONFLICT ("Id") DO UPDATE SET ' ||
  '"AuthorSysAdminUnitId" = EXCLUDED."AuthorSysAdminUnitId", ' ||
  '"GranteeSysAdminUnitId" = EXCLUDED."GranteeSysAdminUnitId", ' ||
  '"Operation" = EXCLUDED."Operation", ' ||
  '"RightLevel" = EXCLUDED."RightLevel", ' ||
  '"Position" = EXCLUDED."Position", ' ||
  '"SubjectSchemaUId" = EXCLUDED."SubjectSchemaUId";' AS insert_sql
FROM TargetPermissions;

The ON CONFLICT ... DO UPDATE is the important part — it makes the script idempotent, so re-running the package install is safe.

Sample of what it produces:

INSERT INTO public."SysEntitySchemaRecordDefRight"
    ("Id", "AuthorSysAdminUnitId", "GranteeSysAdminUnitId", "Operation", "RightLevel", "Position", "SubjectSchemaUId")
VALUES
    ('73dab094-c821-4025-840b-c8d05d519a72'::uuid, 'a29a3ba5-4b0d-de11-9a51-005056c00008'::uuid,
     'b9c3d55d-6598-473b-901b-021399383963'::uuid, 2, 1, 0, '<YOUR-OBJECT-UID>'::uuid)
ON CONFLICT ("Id") DO UPDATE SET
    "AuthorSysAdminUnitId" = EXCLUDED."AuthorSysAdminUnitId",
    "GranteeSysAdminUnitId" = EXCLUDED."GranteeSysAdminUnitId",
    "Operation"            = EXCLUDED."Operation",
    "RightLevel"           = EXCLUDED."RightLevel",
    "Position"             = EXCLUDED."Position",
    "SubjectSchemaUId"     = EXCLUDED."SubjectSchemaUId";

Column meanings: Operation 0 = Read, 1 = Edit, 2 = Delete. RightLevel 1 = granted, 2 = granted with delegation. Position = the order the rules are listed in.

3. Bind it to the package — this is the part that makes it automatic

Configuration → select your package → Add → SQL script. Set:

  • DBMS type: PostgreSQL (Creatio cloud is Postgres-only; MSSQL/Oracle need a separate SQL script schema each, with MERGE or an IF EXISTS guard instead of ON CONFLICT)
  • Installation type: AfterSchemaData, so it runs after the object and any bound data are installed
  • Backward compatible: tick it if you want the package rollback path preserved

4. Make sure the roles exist in the target first

GranteeSysAdminUnitId points at SysAdminUnit rows. 

5. After install, actualize

Record permission rules only apply to records created after the rule exists. In the target environment, open the object's record permissions and run Actions → Update record permissions so existing records pick them up. It's resource-intensive on large tables, so schedule it off-hours.


BR,
Bala.

Show all comments