Hi Creatio Community,

We're encountering a puzzling issue on a Freedom UI List Page (specifically, our Invoices_ListPage) when trying to run a business process (IWVoid_API_POST) using a custom JavaScript handler. The goal is to test the business process by explicitly passing a hardcoded InvoiceId, as requested for a specific testing scenario where the button is not on the individual record's form page.

Our Setup:

  1. The Button (Menu Item on List Page's ActionButton):

    We've added a crt.MenuItem to the ActionButton on our Invoices_ListPage. This menu item is intended for testing and is configured to trigger a custom handler:

    JSON

     

    // In viewConfigDiff of Invoices_ListPage.js
    {
        "operation": "insert",
        "name": "TargetVoidButton", //
        "values": {
            "type": "crt.MenuItem",
            "caption": "Test Void BP (Hardcoded ID)", 
            "icon": "debug-icon",
            "visible": true,
            "clicked": {
                "request": "crt.HandleButtonClickRequest",
                "params": {
                    "buttonName": "RunTargetVoidProcessHandler" 
                }
            }
        },
        "parentName": "ActionButton",
        "propertyName": "menuItems",
        "index": 3 
    }
  2. The Handler (in handlers array of Invoices_ListPage.js):

    This handler is designed to run the IWVoid_API_POST process with a specific, hardcoded InvoiceId.

    JavaScript

     

    // In handlers array of Invoices_ListPage.js
    {
        request: "crt.HandleButtonClickRequest",
        handler: async (request, next) => {
            if (request.buttonName === "RunTargetVoidProcessHandler") { 
                console.log("RunTargetVoidProcessHandler triggered.");
                Terrasoft.showInformation("Test: Running process with hardcoded ID. Check console.");
     
                const processName = "IWVoid_API_POST";
                const hardcodedInvoiceIdForTest = "3c2b6d9f-4c1e-4364-99f2-53956562b606"; 
                const parameterNameInProcess = "InvoiceId"; 
     
                console.log(`Test: Attempting to run BP '<span class="math-inline">\{processName\}' with EXPLICIT HARDCODED ID '</span>{hardcodedInvoiceIdForTest}' for parameter '${parameterNameInProcess}'.`);
     
                try {
                    const response = await request.$context.executeRequest({
                        type: "crt.RunBusinessProcessRequest",
                        params: {
                            processName: processName,
                            processParameters: {
                                [parameterNameInProcess]: hardcodedInvoiceIdForTest
                            },
                            saveAtProcessStart: false, 
                            showNotification: true 
                        }
                    });
     
                    console.log("Test: BP execution request completed. Response:", response);
     
                    if (response && response.success === true && response.processId && response.processId !== '00000000-0000-0000-0000-000000000000') {
                        const successMsg = `Test: BP '${processName}' (ID: ${response.processId}) initiated. Check Process Log.`;
                        console.log(successMsg);
                        request.$context.showInformationDialog?.(successMsg);
                    } else {
                        let errorMsg = `Test: Failed to start BP '${processName}'.`;
                        let serverDetails = (response && response.errorInfo && response.errorInfo.message) ? response.errorInfo.message : "Details unavailable or process not found (zero ID / success:false).";
                        errorMsg += ` ${serverDetails}`;
                        console.error(errorMsg, "Full response:", response);
                        request.$context.showErrorDialog?.(errorMsg);
                    }
                } catch (error) {
                    console.error(`Test: Exception for BP '${processName}':`, error);
                    let exceptionMsg = (error instanceof Error && error.message) ? error.message : "Client-side exception.";
                    if (error.errorInfo && error.errorInfo.message) {
                        exceptionMsg = error.errorInfo.message;
                    }
                    request.$context.showErrorDialog?.(`Test: Error triggering BP: ${exceptionMsg}`);
                }
                return; 
            }
            return next?.handle(request);
        }
    }

The Problem:

When we click the "Test Void BP (Hardcoded ID)" menu item, the handler triggers, and the client-side logs show the crt.RunBusinessProcessRequest is being prepared correctly with processName: "IWVoid_API_POST" and the hardcoded InvoiceId.

However, the server responds with:

{
  processId: '00000000-0000-0000-0000-000000000000', 
  processStatus: 0, 
  resultParameterValues: null, 
  executionData: null, 
  success: false, 
  errorInfo: {
    errorCode: "ItemNotFoundException",
    message: "Item process schema \"\" not found.", // Note the empty quotes for schema name
    stackTrace: null
  }
}

The key error is <strong>Item process schema "" not found.</strong>

What We've Tried:

  • Confirmed the schematic name (Code) of our business process is indeed IWVoid_API_POST.
  • Confirmed the input parameter in the BP designed to take the ID is named InvoiceId.
  • Repeatedly saved, compiled, and published the IWVoid_API_POST business process and ensured it's marked as "Active."
  • Checked the package containing the process for any errors and recompiled the package.
  • Performed thorough browser cache clearing and hard refreshes (Ctrl+F5).
  • We also have another menu item on the same list page ("VoidInvoice") that uses a declarative crt.RunBusinessProcessRequest with processRunType: "ForTheSelectedRecords" and parameterMappings: { "InvoiceId": "Id" }. When a record is selected and this menu item is clicked, it successfully starts the <strong>IWVoid_API_POST</strong> process (verified in Creatio Process Log with a non-zero instance ID). This makes the current error even more puzzling.

Our Questions for the Community:

  1. Why would the ProcessEngineService report Item process schema "" not found (with empty quotes for the schema name) when the processName: "IWVoid_API_POST" is explicitly and correctly provided in the params of crt.RunBusinessProcessRequest from our custom handler?
  2. Is there any known difference in how process names are resolved or how schemas are looked up by the server when crt.RunBusinessProcessRequest is invoked programmatically from a handler with processParameters explicitly set (using a hardcoded ID), versus when it's invoked declaratively with processRunType: "ForTheSelectedRecords" or processRunType: "ForTheSelectedPage"?
  3. Are there any deeper caching mechanisms (server-side, metadata) or specific registration steps for business process schemas that we might be missing, which could lead to this behavior only for the explicit parameter call?
  4. Has anyone encountered a similar situation where a process is findable/runnable via one SDK invocation method (declarative, context-based) but not another (programmatic handler, explicit parameters) from the same Freedom UI page type?

We are unable to access detailed server-side application logs for this specific environment at the moment, which is hampering deeper diagnosis from our end.

Any insights, suggestions, or similar experiences would be greatly appreciated!

Thank you!

Like 0

Like

1 comments

Hi Andrew,

The behavior you described where the system responds with Item process schema "" not found despite providing the correct process name can occur when certain required parameters are missing during the execution of a business process from a handler. Specifically, when using crt.RunBusinessProcessRequest from a crt.HandleButtonClickRequest handler, the backend expects additional context that is typically provided automatically during declarative invocations.

To ensure that the process schema is correctly identified and executed, it is important to explicitly include the processRunType, the recordIdProcessParameterName. These parameters provide the necessary linkage between the UI context and the process runtime.

Below is an example of a working implementation where a business process is successfully launched from a button on a Freedom UI page. The button configuration and handler explicitly define all required fields:

Button configuration:
{
 "operation": "insert",
 "name": "Button_7y0uys4",
 "values": {
   "layoutConfig": {
     "column": 1,
     "row": 2,
     "colSpan": 1,
     "rowSpan": 1
   },
   "type": "crt.Button",
   "caption": "#ResourceString(Button_7y0uys4_caption)#",
   "color": "outline",
   "disabled": false,
   "size": "large",
   "iconPosition": "only-text",
   "visible": true,
   "clicked": {
     "request": "crt.HandleButtonClickRequest",
     "params": {
       "buttonName": "RunTestProcess",
       "processName": "UsrTestProcessInvoiceAdded",
       "processRunType": "ForTheSelectedPage",
       "recordIdProcessParameterName": "InvoiceId"
     }
   }
 },
 "parentName": "SideAreaProfileContainer",
 "propertyName": "items",
 "index": 1
}

Handler logic:
{
 request: "crt.HandleButtonClickRequest",
 handler: async (request, next) => {
   if (request.buttonName === "RunTestProcess") {
     const handlerChain = sdk.HandlerChainService.instance;
     const result = await handlerChain.process({
       type: "crt.RunBusinessProcessRequest",
       processName: "UsrTestProcessInvoiceAdded",
       processRunType: "ForTheSelectedPage",
       recordIdProcessParameterName: "InvoiceId",
       $context: request.$context
     });

     if (result.success) {
       console.log("The process was successfully executed!");
     } else {
       console.log("Exception: " + (result.errorInfo?.message || "Unknown issue"));
     }

     return;
   }
   return next?.handle(request);
 }
}

Answers to your questions:

1. Why would the ProcessEngineService report Item process schema "" not found (with empty quotes for the schema name) when the processName: "IWVoid_API_POST" is explicitly and correctly provided in the params of crt.RunBusinessProcessRequest from our custom handler? 

- This usually happens if processRunType, recordIdProcessParameterName are not passed when triggering the process from a handler. These parameters are essential for correctly resolving the process schema in the runtime context.

2. Is there any known difference in how process names are resolved or how schemas are looked up by the server when crt.RunBusinessProcessRequest is invoked programmatically from a handler with processParameters explicitly set (using a hardcoded ID), versus when it's invoked declaratively with processRunType: "ForTheSelectedRecords" or processRunType: "ForTheSelectedPage"? 

- Yes. In declarative calls, Creatio automatically adds all required metadata. In programmatic calls (handlers), this metadata must be passed manually, especially processRunType and recordIdProcessParameterName.

3. Are there any deeper caching mechanisms (server-side, metadata) or specific registration steps for business process schemas that we might be missing, which could lead to this behavior only for the explicit parameter call? 

- In general, no special registration is required if the process is active and compiled. However, if the process was recently created or modified, reload the page and make sure that the changes in the process were saved.

4. Has anyone encountered a similar situation where a process is findable/runnable via one SDK invocation method (declarative, context-based) but not another (programmatic handler, explicit parameters) from the same Freedom UI page type?

- Yes, this can happen if the required context parameters are not included in the handler call. Declarative calls handle this automatically, whereas in handlers you must explicitly set them.

Show all comments

Hello, is it possible to post a feed in a section record, for example an opportunity record, and this feed is only visible to the @mentioned user, but not all the users who have read access to that opportunity record?

Like 0

Like

4 comments
Best reply

Hello,

Unfortunately, it is not possible to restrict the visibility of feed messages to only specific users with tag through out-of-the-box tools in Creatio. Feed messages typically inherit the access rights of the record they are associated with, meaning anyone with access to the record can also see the feed.

However, you can manage access rights to feed messages by adjusting the permissions for the SocialMessage object. This object controls the visibility of comments and posts within the platform.

You can try to use a  business process to manage the visibility of feed messages. By incorporating logic within the business process, you could create custom steps to control who can access the feed message based on conditions like user roles or specific user mentions.

Best regards,
Ivan

Hi Andrew, were you able to achieve this?

No, that's why I asked here.

Hello,

Unfortunately, it is not possible to restrict the visibility of feed messages to only specific users with tag through out-of-the-box tools in Creatio. Feed messages typically inherit the access rights of the record they are associated with, meaning anyone with access to the record can also see the feed.

However, you can manage access rights to feed messages by adjusting the permissions for the SocialMessage object. This object controls the visibility of comments and posts within the platform.

You can try to use a  business process to manage the visibility of feed messages. By incorporating logic within the business process, you could create custom steps to control who can access the feed message based on conditions like user roles or specific user mentions.

Best regards,
Ivan

Thank you Ivan!

Show all comments

Hello Community,

I would like to know how to skip the warning message that appears when closing a page using a handler.

Currently, I’m using the following code to close the page:

 await request.$context.executeRequest({
  type: "crt.ClosePageRequest",
  $context: request.$context
 });

regards,

Ajay Kuthe.

Like 0

Like

1 comments
Best reply

There is a request called "crt.CanDiscardUnsavedDataRequest" that you can handle to suppress that. See here: https://customerfx.com/article/suppressing-the-unsaved-data-prompt-when-canceling-a-creatio-freedom-ui-modal-dialog/

Ryan

There is a request called "crt.CanDiscardUnsavedDataRequest" that you can handle to suppress that. See here: https://customerfx.com/article/suppressing-the-unsaved-data-prompt-when-canceling-a-creatio-freedom-ui-modal-dialog/

Ryan

Show all comments

Hello Community,

I would like to know how to skip the warning message that appears when closing a page using a handler.

Currently, I’m using the following code to close the page:

 await request.$context.executeRequest({
  type: "crt.ClosePageRequest",
  $context: request.$context
 });

regards,

Ajay Kuthe.

Like 0

Like

1 comments

Hi all,

I am trying to display a field from a related table on a page.

I have 2 objects: Account and Contact. I've added a new integer field to Account called UsrScore.

I'd like to display the UsrScore field on the Contact page (based on an attribute).

I'm fairly certain I want to use EntitySchemaQuery but I can't find the correct syntax. Any help would be appreciated.

Nb. I'm not using the Freedom UI. 

Like 0

Like

2 comments
Best reply

On the contact page, add an attribute to store the value from the account:

attributes: {
    "AccountScore": {
        dataValueType: Terrasoft.DataValueType.INTEGER
    }
}

Add onEntityInitialized in the methods where you'll retrieve the value from the account using the record's Account and store it in the attribute:

onEntityInitialized: function() {
    this.callParent(arguments);
 
    var account = this.get("Account");
 
    if (this.isAddMode() || !account) {
	    return;
    }
 
    var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "Account"
    });
    esq.addColumn("UsrScore");
    esq.getEntity(account.value, function (result) {
        if (result.success) {
            this.set("AccountScore", result.entity.values.UsrScore);
        }
    }, this);
}

Lastly, you'll need to add an element to the diff bound to the attribute to display it on the page. Easily way to do this is to drag something not currently on the page, like ModifiedOn, then find it in the diff and change the name and bindTo (make sure you set it as disabled):

{
    "operation": "insert",
    "name": "AccountScoreValue",
    "values": {
        "bindTo": "AccountScore",
        "enabled": false,
        // etc ...
    },
    "parentName": "SomeWhere",
    "propertyName": "items",
    "index": 0
}

Ryan

On the contact page, add an attribute to store the value from the account:

attributes: {
    "AccountScore": {
        dataValueType: Terrasoft.DataValueType.INTEGER
    }
}

Add onEntityInitialized in the methods where you'll retrieve the value from the account using the record's Account and store it in the attribute:

onEntityInitialized: function() {
    this.callParent(arguments);
 
    var account = this.get("Account");
 
    if (this.isAddMode() || !account) {
	    return;
    }
 
    var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
        rootSchemaName: "Account"
    });
    esq.addColumn("UsrScore");
    esq.getEntity(account.value, function (result) {
        if (result.success) {
            this.set("AccountScore", result.entity.values.UsrScore);
        }
    }, this);
}

Lastly, you'll need to add an element to the diff bound to the attribute to display it on the page. Easily way to do this is to drag something not currently on the page, like ModifiedOn, then find it in the diff and change the name and bindTo (make sure you set it as disabled):

{
    "operation": "insert",
    "name": "AccountScoreValue",
    "values": {
        "bindTo": "AccountScore",
        "enabled": false,
        // etc ...
    },
    "parentName": "SomeWhere",
    "propertyName": "items",
    "index": 0
}

Ryan

Worked perfectly. Thanks a lot.

Show all comments

We have a need to use the string_agg function of Postgres in some backend code which runs SQL against the DB using the Select class, but this is not one of the standard available AggregationTypeStrict enum types. Is there a method for using arbitrary database aggregation functions such as string_agg in a Select class query construction? Or is this not possible with Creatio's Select class? If so, is the only other alternative to use the deprecated CustomQuery class?

Like 0

Like

2 comments
Best reply

It's only possible using CustomQuery. 

I am not sure why CustomQuery is marked as deprecated - I believe it has been since 7.17.4. At the time of 7.17 I had discussions with Creatio and was told they were leaving CustomQuery in place and only certain removing DBExecutor functions, however, it's remained marked as deprecated since. I assume it isn't going anywhere and (hopefully) will continue to be safe to use despite being marked deprecated.

It's only possible using CustomQuery. 

I am not sure why CustomQuery is marked as deprecated - I believe it has been since 7.17.4. At the time of 7.17 I had discussions with Creatio and was told they were leaving CustomQuery in place and only certain removing DBExecutor functions, however, it's remained marked as deprecated since. I assume it isn't going anywhere and (hopefully) will continue to be safe to use despite being marked deprecated.

Thanks Ryan, the other alternative I thought of in the meantime was to do the aggregation in C# on unaggregated data returned from the query, which isn't great but could work for low data volume situations (like the one I was dealing with). Good to hear that maybe CustomQuery isn't as deprecated as it seems then!

Show all comments

Hi Community,

We are encountering this error when saving a business process in our local Creatio 8.1.3.6789 instance (PostgreSQL, SalesEnterprise + Marketing + ServiceEnterprise package):

 

Error occurred when saving: 23503: insert or update on table "SysLocalizableValue" violates foreign key constraint "FKYru8eiQRBeFoEfawvRwKSlCy2o"
 

The issue happens for all team members and seems related to missing schema or metadata.

Is this a known issue with this Creatio version? Any recommended fix or workaround?

Thanks!

Like 0

Like

1 comments

Hello Kani

It seems you don't have the corresponding record on the SysCulture table, try to enable the postgres log and get the insert or update that raises the error.

Show all comments

Hello community,

Is there any way to map the Parent object, while importing data in the detail?

(Example : We want to Import a (Product In Order) in an Order.

Thank you 

Sasor

 

 

Like 0

Like

4 comments

Hello!


Thank you for your question!

Allow me to clarify how the import process works. When importing data into Creatio, you are essentially transferring the information from your Excel file into the corresponding database table. Each detail in Creatio corresponds to a different object or database table. Therefore, during an import, data can be inserted into one table or object at a time.

Import to Contact/Accounts have custom core logic applied, but all other objects work with logic described above.

You can read more about Excel import on Creatio Academy: https://academy.creatio.com/docs/8.x/creatio-apps/creatio-basics/busine…

Have a nice day!

Hello community,

Any update regarding this topic?

Sasor

Hello, answer has been already provided , but we will duplicate it below for your convenience: 

"Thank you for your question!

Allow me to clarify how the import process works. When importing data into Creatio, you are essentially transferring the information from your Excel file into the corresponding database table. Each detail in Creatio corresponds to a different object or database table. Therefore, during an import, data can be inserted into one table or object at a time.

Import to Contact/Accounts have custom core logic applied, but all other objects work with logic described above.

You can read more about Excel import on Creatio Academy: https://academy.creatio.com/docs/8.x/creatio-apps/creatio-basics/busine…

Have a nice day!"

Dear support team members

Kateryna and Oleksandra

I believe you missunderstood our request

_____________________________________________

Here is the scenario

  1. We are in the Opportunity Section.
  2. We want to import a list of Competitors.
  3. While importing the excel file, containing the Competitors list, we need that the competitors list, is assigned to this specific Opportunity '495 / Fast Works / Sale of Goods'
  4. We want to obviously achieve this without manually adding the '495 / Fast Works / Sale of Goods' as a separate column for all the records of the excel. 

Is there any example in the Code-Base, or any other workaround where this is achieved?

Sasor
 

Show all comments

Hello,

 

I am currently generating multiple report templates, some of these templates need to show list components attached to a record. For example, A loan application that has multiple collaterals attached to it or a payment schedule stored in a list component. How do I achieve this?

Like 0

Like

2 comments

Hi.
Newbie here, so bear with me.  Best I start with an example --  

  • We have 200+ users who are sales reps and 2 Admins.
  • Some of these sales reps are managers of a sub-set of other subordinate reps.
  • Now, a rep quits, and it's up to an admin (in another country BTW) to manually go in and reassign his dozens of opportunities to a new sales rep.  This is a task his manager should be able to do, but can't (because only an admin can change other users' records).

This is just one example of a typical issue we run into, that could be fixed by giving "modify" rights to one user over certain other user's records -- or a "superuser" as exists in our other systems.

In Creatio, I am told only the individual rep can change his own "opportunities".  His manager cannot.  (The Admins of course can change everything about everyone, so logically we can not give admin rights to the managers.)

Is there a way around this?  
Perhaps the next release of Creatio will have some sort of granularity of "rights"? 

Thanks!
Rob

 

Like 0

Like

4 comments
Best reply

Creatio does have this, or at least it can work like this. If you're using organizational roles, each organizational role can have a management role. The management role inherits the permissions of the users in the organizational role. Meaning, if you create an org role called "sales" and then add an management role for the sales org role, the people in the management role inherit the permissions of the users in the org role. See https://academy.creatio.com/docs/8.x/setup-and-administration/administration/user-and-access-management/user-management/organizational-roles#title-2266-2

Note, this often means you also need to setup object/record permissions for things based on these roles as well, instead of by users (so the permissions can be inherited by the managers of the role). For example, you could add record access permissions that if anyone in "sales" creates a record, that edit permissions is given to anyone in the "sales managers role".

Ryan

Creatio does have this, or at least it can work like this. If you're using organizational roles, each organizational role can have a management role. The management role inherits the permissions of the users in the organizational role. Meaning, if you create an org role called "sales" and then add an management role for the sales org role, the people in the management role inherit the permissions of the users in the org role. See https://academy.creatio.com/docs/8.x/setup-and-administration/administration/user-and-access-management/user-management/organizational-roles#title-2266-2

Note, this often means you also need to setup object/record permissions for things based on these roles as well, instead of by users (so the permissions can be inherited by the managers of the role). For example, you could add record access permissions that if anyone in "sales" creates a record, that edit permissions is given to anyone in the "sales managers role".

Ryan

Ok, Thanks -- that's kind of what I thought, with my rudimentary experience with roles (and Creatio in general).

So, applying this to our large sales organization ...
Instead of implementing a single "sales" role, we would need to implement a "superuser" role, but for each sales division -- perhaps?

For example, we have 8 sales regions, like "Asia" and "Europe" and "South America".  There are 30-50 sales reps in each region.
We don't want all their "issues" trickling up to one admin, so as I mentioned we want a "SuperUser" in each region:  "SuperUser-Asia", SuperUser-India" and so on.  I guess these would be "management" roles in Creatio.

So, we would have to divide up the Sales Reps (users) into separate orgs (one for each region) so that their data would be visible to their SuperUser? 
Can I create separate orgs in Creatio, all living underneath the main Company org?

Thanks -- any suggestions you have are appreciated!

Rob

Yes, the roles are hierarchical. Each sub role inheriting the permissions of the roles before. You can have a role for sales, then sub roles for each division. Each division can have a managers role which could give them inherited permissions for the division they manage.  

I will have to review this with our integrator.   They are telling us that in the forthcoming release of Creatio, there are some enhancements to roles and permissions -- Are there any hints or documentation as to what this might be?   We need to allow certain roles to be able to edit specific data but not all.

(For example, a salesman creates a customer account DuPont Paints and can assign it to a "master" account DuPont International. This is really something that his local manager admin should also able to do, but can't)

Show all comments