Время создания
Filters
List_Widget
Export_To_Excel
Studio_Creatio
8.0

I’m having trouble enabling the Export to Excel action for a List Widget.

The built-in Export to Excel action works for List Components, but I can’t find a way to configure it with the newer List Widget released in version 8.3.1.

 

Here’s what I’ve tried:

  • I added a button to trigger the default Export to Excel action.
  • In the button’s settings, under “Which data to export?”, the List Widgets on the page do not appear.
  • If I add a standard List Component to the page, it does show up in the export configuration as expected.

 

Is it possible to use the built-in Export to Excel action with a List Widget?


If not, is there a recommended workaround (e.g., custom code, BPM, or another approach) to export the list widget’s data to Excel?

 

Like 0

Like

2 comments

Hello, 

Unfortunately at this moment there is no built-in possibility to enable Export to Excel for List Widget. 

The team is aware of the request to enable the ‘Export to Excel’ option for list widgets in Freedom UI dashboards. There is a corresponding task in progress, but at this time there is no confirmed release date for this functionality.

As a temporary workaround, it is possible to add a button directly to the dashboard schema that will export the list widget to Excel. Below is an example configuration for such a button:

{
    "operation": "insert",
    "name": "Button_cfj1ji4",
    "values": {
        "layoutConfig": {
            "column": 1,
            "colSpan": 1,
            "row": 1,
            "rowSpan": 1
        },
        "type": "crt.Button",
        "caption": "Export list widget to excel",
        "color": "default",
        "disabled": false,
        "size": "large",
        "iconPosition": "only-text",
        "visible": true,
        "clicked": {
            "request": "crt.ExportDataGridToExcelRequest",
            "params": {
                "viewName": "ListWidget_1ocamke",
                "filters": "$ListWidget_1ocamke | crt.ToCollectionFilters : 'ListWidget_1ocamke' : $ListWidget_1ocamke_SelectionState"
            }
        },
        "clickMode": "default"
    },
    "parentName": "Main",
    "propertyName": "items",
    "index": 1
}

In this example, ListWidget_1ocamke should be replaced with the items attribute name of your list widget.

 

Thank you for reaching out! 

Thank you for the guidance, Oleksandra!

Show all comments
pivot
Studio_Creatio
8.0

Hi Everyone,

I’m setting up a pivot in the Dashboards section, and I noticed that under the Date part functions we currently have options like PartYear, PartMonth, PartWeek, PartDay, etc., but there’s no option to get the quarter of a date.

My use case is quite common: I’d like to group or report records by the quarter of the Created on date (e.g. Q1–Q4), similar to how months or weeks can be derived.

Is there a recommended workaround for this today (for example using formulas or logic), or is there a plan to introduce something like a PartQuarter function in future releases?

Any tips, best practices, or ideas would be much appreciated. Thanks in advance!

Like 0

Like

0 comments
Show all comments

Problem: I am unable to enable the Change Log for replaced objects (e.g., Contact) within a custom package (CRMPackage) that was restored from a Git repository. When selecting columns and clicking "Apply," the ChangeLogService.svc throws the following error:

"Unable to save... The item was created by a third-party publisher. To modify this item, save it to your package."

Environment Context:

  • Version: 8.3.1.4498 (PostgreSQL).
  • Setup: Docker-based development using File System Development Mode (FSDM).
  • Current Package: CRMPackage, Maintainer: CRMDev, Packager maintainer = CRMDev
  • Workflow: Package files (CRMPackage) are managed via Git and symlinked from /workspace to the Creatio root /app/Terrasoft.Configuration/Pkg.
  • Current State: All other development actions—saving Schemas, Data, SQL Scripts, and Lookups—work perfectly and sync to the file system and the custom package as expected.

Technical:

  1. Service Failure: The ChangeLogService.svc call to SaveObjectChangeLogSettings fails during the internal DesignItemInCustomPackage process.
  2. The "Third-Party" Block: The error specifically states the item was created by a third-party publisher and must be saved to my package. However, the object is already in my package and physically joined to the correct SysPackageId in the database.
  3. Workaround behavior: If I set the global Maintainer system setting to "Customer" and apply the change log, it gets saved into the Custom package. But I want change log for Contacts to be reflected in my current development package.

Other Ways:

I'm able to enable the change log for my object directly as below but how to enable the change log for "Inactive column". I have replaced the contact object and enabled "Allow record for deactivation"

Error:
Request
Response

Response Error:

{
   "success": false,
   "errorInfo": {
       "errorCode": null,
       "message": "Unable to save changes for item \"Contact\". It is either created by third-party publisher or installed from the file archive",
       "stackTrace": "   at Terrasoft.Core.SchemaManager`1.CheckIsPackageForeign(ISchemaManagerItem`1 designItem, Guid packageUId, UserConnection userConnection)\n   at Terrasoft.Core.SchemaManager`1.InternalSaveSchema(ISchemaManagerItem`1 designItem, Guid packageUId, Boolean removeDesignItem, UserConnection userConnection, Boolean generateBundles, Boolean validateNamePrefixes, Boolean lockSchemaInSourceControlStorage, Boolean useFullHierarchy, Boolean regenerateReferencedSchemaSources)\n   at Terrasoft.Core.Entities.EntitySchemaManager.InternalSaveSchema(ISchemaManagerItem`1 designItem, Guid packageUId, Boolean removeDesignItem, UserConnection userConnection, Boolean generateBundles, Boolean validateNamePrefixes, Boolean lockSchemaInSourceControlStorage, Boolean useFullHierarchy, Boolean regenerateReferencedSchemaSources)\n   at Terrasoft.Core.Entities.EntitySchemaManager.InternalSaveSchema(ISchemaManagerItem`1 designItem, Guid packageUId, Boolean removeDesignItem, UserConnection userConnection, Boolean generateBundles, Boolean validateNamePrefixes, Boolean lockSchemaInSourceControlStorage)\n   at Terrasoft.Core.SchemaManager`1.SaveSchema(Guid uid, Boolean removeDesignItem, UserConnection userConnection, Boolean generateBundles, Boolean lockSchemaInSourceControlStorage)\n   at Terrasoft.Core.SchemaManager`1.SaveSchema(Guid uid, UserConnection userConnection, Boolean generateBundles, Boolean lockSchemaInSourceControlStorage)\n   at Terrasoft.Core.ServiceModel.ChangeLogService.SaveChangeLogSettings(ObjectChangeLogSettings settings)\n   at Terrasoft.Core.ServiceModel.ChangeLogService.SaveObjectChangeLogSettings(ObjectChangeLogSettings changeLogSettings)"
   }
}


Query:
Is there a way to enable the "Change Log" for the Contact object's Inactive column via DB query?



BR,
Bala.

Like 2

Like

0 comments
Show all comments

Hi everyone,

We have received inquiries from customers regarding the following matters. We are seeking relevant case studies to response.

・Please tell me the approximate timeline required when switching systems.

Could you share various reference values based on your experiences?

For Enterprise companies, how many days did it take for implementation and development?

How many days did data migration take? etc.

 I'm looking to grow the Creatio community!

Thank you,

 

Sui

Like 0

Like

0 comments
Show all comments
webhooks
webhook
businessProcess

Creatio’s webhook service will technically accept every webhook you throw at it, regardless of whether the formatting matches the existing process structure. Processing, however, is very particular about format. Many times, you will receive webhooks from a source with no control over payload structure. Some customers turn to middleware tools to reformat the payload, however, you can create some psuedo-ETL (extract-transform-load) business processes in Creatio using OOTB tools to manage your payloads as well. To do this, you can create your own processes to handle the incoming webhook records, based on the OOTB webhook business processes. This guide is not intended to be an exhaustive solution, but merely an intro to the OOTB webhook components and how you can use some creativity in combination with Creatio’s business processes to work around your payload structure difficulties. This guide is also intended to be a foundation. I encourage you to expand, grow, and add your own scale/complexity as needed.

 

First, you should note the key processes of webhook consumption in Creatio. I assume you already have webhooks configured, and if not, that is already well documented, so I won’t get into that piece here.

  1. Start process to create object records based on incoming webhooks
    This is the first business process used to process the incoming webhooks. The OOTB business process runs on a timed trigger with a 1 minute interval. This process immediately calls the following via subprocess and nothing more. This first process is simply a trigger. (Arguably, redundant, as you could’ve just started your 1min trigger on #2 below, which I will recommend later when we build our custom replacements.)
    1. Engagement tools App: Start process to create object records based on incoming webhooks
      The name above is an alternative version that appears in new versions of Creatio. If you have the Engagement App version, then you will likely have BOTH versions available with one disabled. The Engagement App version includes an additional subprocess: Define contact based on submitted form.
      For simplicity, we will ignore this flow for now. I’ll address this at the end, as there’s many ways to incorporate the find/create contact processes.

 

  1. Create object records based on incoming webhooks
    This is where the magic happens. This process reads all webhooks that are in a “New” status, indicating they need to be processed. To process the webhooks, Creatio calls a user task “Webhook To Entity UT”, which translates the incoming JSON payload to the appropriate objects and fields identified. This assumes you’ve strictly followed the Creatio webhook format – and if not, then your webhook stalls here and fails to process. This user task handles every part of webhook processing, from identifying the appropriate object, the fields, and the status of the incoming webhook record/payload itself.

We will disable both business processes above and create our own to handle our custom logic.

 

Start with a stable foundation.
The second process of Creatio’s webhook pair is the one with all the juice. We can simplify and combine these two as mentioned previously. Likewise, we want to keep Creatio’s OOTB webhook processing in place, so we’ll start with a copy of process number 2.

  1. Open the process “Create object records based on incoming webhooks”
  2. Select Actions -> Copy Diagram
  3. Save this new process with a new title and code as desired. Otherwise, you can also just use a “Custom - ” or “Usr” prefix – whatever is relevant for your environment. Be sure to set your package appropriately as well.

 

The customization.
Now that we have our foundation, we can start to make the necessary adjustments.

  1. The trigger
    This process starts with a manual trigger. We have two options here: timer or trigger.

    • Trigger
      My personal preference in all scenarios is to convert these to a trigger. Not only will this help to keep your logs from bloating with processes that run every 1 min doing nothing, but this will also simplify our processing for ETL, as we need to read the incoming payload to determine how to route the record through our new process. For a trigger, set the object to Webhook and event to “Record added”. For added security, we’ll set a condition on this for “Status = New” as well.


       
    • Timer
      If you regularly receive a very high volume of webhooks (several per minute, constantly, throughout the day), then stick with the 1 min interval. For most, running 1 min timers on batch is overkill. Likewise, this will complicate our ETL process as we would have to add an additional read collection element with our new criteria, alongside another subprocess to manage the collection of incoming records. I’ve documented this for reference, but we will not be using timer for this guide.

     

  2. Webhook read
    The OOTB process, built for handling webhooks in batch, uses a “Read collection” element. The OOTB user task “Webhook to Entity UT” expects a collection for input. For simplicity, we’re going to keep this node but simply move to later in the process. We’ll also need to read the newly triggered record as well.

    • Copy the “Read collection”, paste this just after the trigger, then update this element to “Read the first record in the selection”
    • Set the label to “Read new webhook”
    • Update the filter to read the incoming trigger Id

     

  3. Conditional evaluation
    The ‘OR’ element currently evaluates for webhooks “yes or no”. Since we moved to a trigger, this is always yes. However, we want to sort based on OOTB behavior vs. our custom behavior. We’ll keep the OR element but update the label and conditions. Since we are reading each record independently, we can analyze in incoming request body to determine whether the format matches Creatio’s suggested format OR some other format. Creatio’s payloads always start with {"EntityName": which we will leverage in our conditional evaluation.
    • Change the “Conditional flow” evaluation from the existing “Count” logic to our new behavior determining whether or not the payload is an OOTB Creatio format or something else:
      [#Read new webhook.First item of resulting collection.Request body#].StartsWith("{\"EntityName\"")
    • The NO path is where we will begin to integrate our custom logic for our new ETL process.
  4. ETL process
    You can use strictly a process alone to manage the webhook behavior, without any additional objects/tables, though this tends to get messy and requires a lot of C# formula steps and substrings. However, if your source is completely inflexible then you may need to go on this route. This does get a bit messy and is inherently sensitive to incoming data format as we’re doing simple string manipulation/extraction but can be reliable assuming the data structure remains the same. Likewise, if your incoming data structure were to change for whatever reason, you’d likely still have an issue importing your payload regardless of method of extraction.

    In some instances, you might even be able to create the entire Creatio structure as desired, but perhaps there are some additional field wrappers preventing direct ingestion. This step will require you to conduct your own analysis, development, and testing for your unique incoming payload.

    In this example, I’m assuming that I have an incoming lead from a web form, so I want to grab a few key data points like first and last name, phone, email. I might also have information like interested products, notes, as well. Alternatively, this webform might be uniquely specific to a certain product, like a Mortgage. In that case, even though the payload may not have the info, I can still set those values in the process.
    • Create a new subprocess that will manage the logic for our unique payload format.
    • Create a new input parameter for “Request body” so that we can pass this in from the parent record.
    • Define the fields we want to extract from the request body by creating a “parameter” for each field.
    • Set the value of each parameter to a C# string formula to extract the desired values. You will need to adjust this based on your use case. I’ve included an example payload and formula string for reference:
      • [#Request body#].Substring(([#Request body#].IndexOf("\"name\":\"") + 8), ([#Request body#].IndexOf("\"", ([#Request body#].IndexOf("\"name\":\"") + 8)) - ([#Request body#].IndexOf("\"name\":\"") + 8)))
      • You can use this formula, adjusting the field name and offsets for the desired incoming fields. Name, consisting of 4 characters, plus 4 from 3 quotations and a colon. First name, by contrast, is 10 characters, plus the four from quotations and the colon. Be sure to account for any other characters or spaces when constructing your Substring formula.
      • [#Request body#].Substring(([#Request body#].IndexOf("\"First Name\":\"") + 14), ([#Request body#].IndexOf("\"", ([#Request body#].IndexOf("\"First Name\":\"") + 14)) - ([#Request body#].IndexOf("\"First Name\":\"") + 14)))


         
    • Now that we’ve defined our field values in the parameter formulas, we can drop in an “Add data” node, setting the fields as desired. In this case, we’re going to create a new Lead record, using a few of the relevant fields from our payload: Name (as lead name), first name, last name, and phone (which we will map to email as this appears to have been repurposed on the web form based on incoming data). This part is nice and simple – drop the node, select the Lead object, add the relevant fields, then map each of those to the parameters we created.
    • With this process completed / saved, move back to our “parent” process with the trigger and add this as a subprocess. Set the “Request body” parameter to the value of the “Read new webhook” element’s “Request body”.

    • Now that we’ve processed our payload, we need to update the status of the webhook appropriately. To do so, we’ll add a new node after the subprocess to set the webhook record’s status to “done”.
    • Finally, we need to make sure to update the status of failed webhooks in our “default path”. Since we’re adding logic to conditionally skip the OOTB Webhook user task, we want to include some redundancy of our own. In this case, we failed to register the webhook as an OOTB payload, we failed to match our condition for the lead subprocess, so we need to set the status to “Failed.”

 

Extra credit – find / create contact records
Remember my mention of the “Engagement App” version of the process? That version includes some additional logic for tracking UTM information. This can be helpful depending on your implementation. Likely, a Marketing customer will want to track this info. If so, I suggest getting familiar with that subprocess and incorporating this into your new custom webhook processor. Even if you’re not a Marketing user, there’s another subprocess buried in these subprocesses that is beneficial for everyone: Searching and creating contact.

This process allows for input parameters for common contact information data points, then will identify a matching contact based on the determined logic, returning the contact Id for matched existing contact records or will create a new contact record based on the searched values. Most likely, you will want this. You’ll get better insights to leads that you’ve had prior interactions with, establish history with new contacts, and generally just improve your data quality. Adding this to our subprocess is quite simple.

  • Return to our ETL subprocess, then add a new “Subprocess” node, selecting the “Searching and creating contact” process from the list.
  • Define our input parameters on this node, allowing the subprocess to find/create the contact as appropriate.
  • Update the “Add data” node. Now that we are working with Contact records, rather than string fields, we can simply pass the Id from the find/create subprocess, as this will have the contact info we provided. As such, you can remove the name/phone/email fields from the Lead record, as that would be redundant alongside the contact record.

 

Final cleanup

Be sure to disable the old webhook processes…

  • Start process to create object records based on incoming webhooks
  • Engagement tools App: Start process to create object records based on incoming webhooks

…and enable our new processes

  • Custom - Create object records based on incoming webhooks
  • Custom - Webhook - New lead from website
Like 3

Like

Share

0 comments
Show all comments