I am trying to get contact collection data from creatio using OData 4. 

 

In my account, I have tons of contact data, but somehow API gives empty error.

 

Is it something related to permission access related issue?

 

 

@Community, please help to solve this issue

Like 0

Like

1 comments
Best reply

Hello. Make sure that the user used to authenticate the request has the right to read the data of the "Contact" Object. Check in the System Designer, Access Rights to Objects.

Hello. Make sure that the user used to authenticate the request has the right to read the data of the "Contact" Object. Check in the System Designer, Access Rights to Objects.

Show all comments

Is there a handler used when loading a List element for the first time or when reloading the list, including after changing quick filters? The crt.LoadDataRequest handler appears to only be called when reloading the list or loading in additional records via the infinite scroll mechanic, but not on the first load of the data or when reloading the data after quick filters are changed, so it does not fit the need.

 

What I'm looking to do is to intercept the initial loading of the data for the list to perform some async task, and once that async task has been completed allow the load to resume as usual. This should be triggered when the page first loads the list in, and whenever the user clicks to reload the list manually or changes quick filters that change the list data, but shouldn't be triggered on the infinite scroll.

Like 1

Like

4 comments

Hello,
 

The initial data loading request 'crt.LoadDataRequest' was not included in this step because it’s part of the system's core loading process, ensuring that essential page elements are set up first.

 On subsequent loads, the system publishes 'crt.LoadDataRequest' where users can apply their customizations.
 

Currently, there’s no default handler to directly intercept the system’s initial load, but there are other options for customization depending on the user’s needs.
 

Additional options include:
 

1) System "crt.HandleViewModelInitRequest" on view model initialization.

2) A change request on view model attribute change, more details on this approach below:

! Warning: Theoretically, this approach could cause slower performance when working with the card, as it increases the total number of handler calls (the approach will trigger on every list change: loading, reloading, sorting change, column list change, and column value change).

 

To use this approach, add a change marker to the appropriate DataGrid attribute (example below):


T
hen, add a handler to process the usr.MyRequest in the handlers, similar to how it's done for crt.LoadDataRequest and crt.DataGridCreateItemRequest.
 

As a result, your custom logic will execute when a new column is added, or when a column is deleted, and for other list changes.
 

Hope this helps, and thank you for reaching out!

Hi Pavlo, thank you for the detailed response! I'm sure that functionality will come in handy.

 

Unfortunately, for our use case, we need to perform an action before the data is fetched for the reload, whereas this change triggers only after the data has already been fetched from the database to reload the list. Is there anything that would fire in a similar way but before the data is requested from the server? LoadDataRequest does this, but has the drawbacks of being called only in certain circumstances.

 

Is there any documentation on the event handler "call stack"? This would be really useful, knowing that, for example, when a user clicks the reload button, first handler X is called to do some action, then handler crt.LoadDataRequest is called to handle the outbound data call to the servers, then the data is sent to the user's browser, then handler Y is called to do some action, then handlers that are associated with the change property of viewModelConfig are called when updating the data stored in the List, etc.

 

Many thanks,

Harvey

Harvey Adcock,

Hello,

Thank you for the additional clarification. Unfortunately, at this time, this option is not available.
 

I have created a task for the development team to implement such a handler in the system.
 

Thank you for helping us improve our product.

Best regards,
Pavlo

Hi Pavlo, thanks - I think we really need some more consistency in what triggers handlers and what doesn't. Performance implications of overriding certain handlers is something for the developers to consider (ideally armed with documentation on any things to look out for - the current info on request handlers in the Academy is incredibly limited) and not really something that should be prevented from being done entirely. Why even have the ability to override LoadDataRequest when one of the main times it should be called (first loading data for a List) it doesn't even fire? Developers just end up having to do workarounds that are even worse for performance, such as triggering a reload of the data from code, so the data gets requested twice.

 

There are so many page events which would've previously in Classic UI triggered something in the page code that developers could override as needed, but now it's just flipping a coin to find out if the event you need to capture and handle in some custom way is possible to be overridden or not.

Show all comments

Hi All,

 

Is it possible to create a detail similar to the detail "delivery address" in Order Section that allow user

  1.  to select specific address and 
  2. add new if one is not available (please see attached example image)

 

And does new Freedom UI have this feature?

 

Many thanks.

Like 0

Like

1 comments

Dear Mid,
 

This detail is developed in schema AddressSelectionDetailV2, where you can find the implementation details.
 

In the Freedom UI, this functionality is implemented by using a Contact/Account address as a data source:


Have a great day!

Show all comments

Hello, I'm currently trying to make a case stage process where an approval is sent out tothe selected approver by an user. I've set up so that when a case reaches the "Approval" stage a sub-process is run that will open a mini page for asking the approver name by a user.

 

But sub process is not automatically open that page for asking the approver name. Please see the screenshots below:

 

Can anyone please help with this? Any help is really appreciated!

Like 0

Like

0 comments
Show all comments

Hello Community,

 

                  I’ve built a custom page in Freedom UI to display my data in both List View and Calendar View. I implemented the logic in `SCHEMA_HANDLERS` and used `crt.LoadDataRequest` to toggle between the views. The logic works fine when switching to Calendar View for the first time.

 

                              

                              

Issue: 
1] When switching from Calendar View to List View and then back to Calendar View, the data disappears.

I have to refresh the page to make the data reappear in the Calendar.

 

Regards,

Ajay Kuthe

 

 

Like 0

Like

3 comments

Hello,

 

Please describe in detail how exactly this was implemented and provide screenshots of this button's settings.

Mira Dmitruk,

 

I used the 'Refresh data' action to trigger the 'crt.LoadDataRequest' and control the visibility of elements to switch between views (Calender and List).

Button Config

#Code Logic in Handler

handlers: /**SCHEMA_HANDLERS*/[{
    request: "crt.LoadDataRequest",
    handler: async (request, next) => {

 

// Check if the data source name is "ListOrCalenderView"
if (request.dataSourceName === "ListOrCalenderView") {

   // Retrieve the current view mode (Calendar or List)
   const IsCalenderView = await request.$context.IsCalenderView;

   // If the current view is not Calendar (i.e., it's List View)
   if (IsCalenderView === false) {
       // Set the Button caption to "List View"
       request.$context.ListOrCalenderView_caption = "List View";
       request.$context.IsCalenderView = true;
 // Set the ListView flag to false since we are now in Calendar view
       request.$context.IsListView = false;

   } else {
  // If the current view is Calendar, switch to List View
  request.$context.ListOrCalenderView_caption = "Calender View";   request.$context.IsCalenderView = false;
  request.$context.IsListView = true;

 }

}

 

Regards,

Ajay K
 

Mira Dmitruk,

Do you have any alternative solutions besides switching between List and Calendar views?

Show all comments

Hi there,

 

I am creating a business rule to auto-populates the field with the current user contact for custom field Owner, but I am not able to find out what should be the action for this and also not able to see the current user option. Please see the screenshot below

Like 0

Like

1 comments

Not possible with rules on classic pages. Best option would be to set it as the default for that column in the object. Select the object and choose the Owner column and set Current User Contact for default value. 
Otherwise, you'd need to get current user and populate via code in the onEntityInitialized - make sure the page is in add mode.

Ryan

Show all comments

I have created a signal-based Business Process that fires on modifying the data in Opportunity.

 

To Read the Email Template I write the following code:

using System;
	using System.Collections.Generic;
	using System.Linq;
	using Newtonsoft.Json;
	using Terrasoft.Common;
	using Terrasoft.Configuration;
	using Terrasoft.Configuration.Utils;
	using Terrasoft.Core;
	using Terrasoft.Core.Configuration;
	using Terrasoft.Core.DB;
	using Terrasoft.Core.Entities;
	using Terrasoft.Core.OperationLog;
	using SystemSettings = Terrasoft.Core.Configuration.SysSettings;
 
 
	public class EmailTemplateManager
	{
 
		private UserConnection _userConnection;
		private MacrosHelperService _macrosService;
		private readonly Dictionary<Guid, Entity> _cachedTemplates = new Dictionary<Guid, Entity>();
 
		public EmailTemplateManager(UserConnection userConnection) : base() {
			_userConnection = userConnection;
			MacrosHelperV2 macrosHelper = new GlobalMacrosHelper();
			macrosHelper.UserConnection = userConnection;
			_macrosService = new MacrosHelperService(macrosHelper, userConnection);
		}
 
		public string GetEmailTemplateSchemaName() {
			return _userConnection.GetFeatureState("EmailMessageMultiLanguage") == 0
				? "EmailTemplate"
				: "EmailTemplateLang";
		}
 
		public string GetTemplateBody(Guid recordId, Guid templateId) {
			var template = GetTemplate(templateId);
			if(template != null) {
				var schemaName = GetSchemaNameFromId(template.GetTypedColumnValue<Guid>("ObjectId"));
				var body = this.GetTemplateBody(new MacrosHelperServiceRequest
				{
					EntityId = recordId,
					EntityName = schemaName,
					TemplateId = templateId
				});
				return body;
			}
			return string.Empty;
		}
 
		public string GetTemplateBody(MacrosHelperServiceRequest request) {
			MacrosHelperServiceResponse template = null;
			string body = string.Empty;
			if (_userConnection.GetIsFeatureEnabled("EmailMessageMultiLanguageV2")) {
				template = _macrosService.GetMultiLanguageTextTemplate(request);
				body = template.TextTemplate;
			} else {
				template = _macrosService.GetMultiLanguageTextTemplate(request);
				body = template.TextTemplate;
			}
			return body;
		}
 
		public string GetTemplateSubject(MacrosHelperServiceRequest request) {
			MacrosHelperServiceResponse template = _macrosService.GetMultiLanguageTextTemplate(request);
			string title = template.SubjectTemplate;
			return title;
		}
 
		private bool IsNeedChangeMacrosCulture() {
			return _userConnection.GetIsFeatureEnabled("UseMacrosAdditionalParameters")
				&& _userConnection.GetIsFeatureEnabled("EmailMessageMultiLanguageV2");
		}
 
		public string GetTemplateSubject(Guid recordId, Guid templateId) {
			var template = GetTemplate(templateId);
			if(template != null) {
				var schemaName = GetSchemaNameFromId(template.GetTypedColumnValue<Guid>("ObjectId"));
				return GetTemplateSubject(new MacrosHelperServiceRequest
				{
					EntityId = recordId,
					EntityName = schemaName,
					TemplateId = templateId
				});
			}
			return string.Empty;
		}
 
		private string GetSchemaNameFromId(Guid objectId) {
			if(objectId != Guid.Empty) {
				var selectQuery  = new Select(_userConnection)
								.Column("Name")
								.From("SysSchema")
								.Where("UId")
									.IsEqual(Column.Parameter(objectId)) as Select;
 
				return selectQuery.ExecuteScalar<string>();
			}
			return string.Empty;
		}
 
		public Entity GetTemplate(Guid id) {
			Entity template;
			if (_cachedTemplates.ContainsKey(id)) {
				template = _cachedTemplates[id];
			} else {
				var esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, GetEmailTemplateSchemaName());
				esq.AddColumn("Object");
				esq.AddColumn("Subject");
				esq.AddColumn("Body");
				esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Id", id));
				template = esq.GetEntity(_userConnection, id);
				_cachedTemplates.Add(id, template);
			}
			return template;
		}	
	}

 

To call this class in the Business Process I used this code:

try{
 
	var userConnection = GetUserConnection();
	var emailManager = new EmailTemplateManager(userConnection);
	var templateId = Get<Guid>("TemplateId");
	var recordId = Get<Guid>("RecordId");
	var subject = emailManager.GetTemplateSubject(recordId, templateId);
	var body = emailManager.GetTemplateBody(recordId, templateId);
	Set<String>("Body", body);
	Set<String>("Subject", subject);
}
catch(Exception ex){
	Set<String>("Subject", ex.Message);
	Set<String>("Body", ex.StackTrace);
}
return true;

 

 

To get the UserConnection in the background I used this Code:

private UserConnection GetUserConnection(){
	return Get<UserConnection>("UserConnection");
}

 

Here is the error I get:

Error Message: Error creating an instance of the "Terrasoft.Configuration.ILanguageIterator" class 

Stack Trace:   at Terrasoft.Core.Factories.ClassFactory.GetInstance[T](Func`1 action)
  at Terrasoft.Configuration.MLangContentFactory.GetContentKit(String iteratorTagName, String storeTagName)
  at QTECX.Email.EmailTemplateManager.GetTemplateSubject(String schemaName, Guid recordId, Guid tplId)
  at QTECX.Email.EmailTemplateManager.GetTemplateSubject(Guid recordId, Guid templateId)
  at Terrasoft.Core.Process.QTXTestEmailProcessMethodsWrapper.ScriptTask1Execute(ProcessExecutingContext context)

 

 

Like 0

Like

6 comments

I created the very same business process and manually specified RecordId (Id is a random Opportunity record) as 

 

new Guid("6344D6CE-F889-4361-83F2-9CD71DBD6300")

 

and TemplateId (Id is a random email template) as

 

new Guid("8F5C1959-25E0-45BC-A62D-04B516502A82")

 

in the process parameters and didn't get the error you received (checked the application logs dicrectly, BusinessProcess.log, Common.log and the Error.log files). Both the EmailTemplateManager class and the business process were created in the Custom package.

 

So the assumption is that either both the business process and the class on your end are created in an assembly package (or in separate packages, one of which is an assembly package) or the issue is in the parameters that the business process receives. Tested everything in the full bundle 8.1.4 application.

But we have to use this code in the Creatio 7.16 Version and it returns this error.

Syed Ali Hassan Shah,

You can order a trial site of 8.1.4 and check the suggested solution. If it works, please update the application to the newest version.

Anhelina,

We can not update the site to the latest version there are many complications in it Creatio Team already tried it once but didn't work out. Can you please suggest a solution for Version 7.16

Is there any update on the solution for Version 7.16?

Any update on this?

Show all comments

Hi, does anyone have information on how best to carry out branching development in Creatio using Git? We've found plenty of pitfalls and issues with doing so that we work around in various ways, but it doesn't feel particularly streamlined and has plenty of trial and error involved, which isn't ideal!

 

Some of the things we encounter are desynchronisation of the database with the config, various errors thrown by the compiler, quite a consumption in time of switching branches, it being a bit easy to lose config changes unless you are very precise about how you change branches etc.

Like 1

Like

2 comments

Hello Harvey,

Based on our experience, most problems occur when switching branches that have different objects (for example, an object exists in one branch but not in another). This issue is not exclusive to Creatio but is common to all projects that use an ORM (Object-Relational Mapping) system to manage the database, such as EntityFramework. Therefore, the advice here is to avoid switching between such branches. If you must do so, remember to remove reverse references between objects (which are created for OData). I do this by executing the following queries in the database:

```sql
DELETE FROM SysSchemaSource WHERE SysSchemaId IN (SELECT Id FROM SysSchema WHERE SysPackageId NOT IN (SELECT Id FROM SysPackage));
DELETE FROM SysSchema WHERE SysPackageId NOT IN (SELECT Id FROM SysPackage);
DELETE FROM SysPackageSchemaData WHERE SysPackageId NOT IN (SELECT Id FROM SysPackage);
DELETE FROM SysSchemaSource WHERE Name LIKE '%backreference%';
```

After that, I perform a compilation.

Additionally, frontend schemas also have connections through the configuration (for example, the `SysModuleEdit` table), and if the schemas are missing, you might end up with a non-working UI.

In different branches, schemas can also be moved between packages, and the relationships in the configuration can break because of this.

This is precisely why only SVN is officially supported, and using Git comes with limitations similar to those when using SVN.

You should also consider that Git only deletes files, but folders may remain empty. While this is not an issue for Git, it is very important for Creatio. All empty folders are perceived as packages, and if a folder is empty, it will be populated when exporting code to the file system.

Also, deleting a package through Git will not remove the package in the configuration because Creatio reacts only to code changes, and if there are none, no changes will occur.

Our team has a whole list of such nuances, but we have written PowerShell scripts to solve most of them (for example, deleting all empty folders or removing a SQL script that remains when renaming it through the configuration and a new one is created with a new name).

I can describe our other rules as well, but that would take more time.

 

P.S. The Creatio system is well-designed if you follow its development features and keep it clean (for example, developers often delete schemas without removing resources, or they move schemas between packages through the file system to save time instead of doing it through the configurator). If you establish rules, adhere to them, and use helper scripts, development won't cause unpleasant issues.

Dear Harvey,

Unfortunately, there is no universal recommendation that could completely resolve your issue. However, here are a few key points to consider:
 

    1) All packages in the configuration should be tied to a single Git repository, since they depend on each other and need to be saved as part of a single commit. (It's not recommended to store each package in a separate repository.)


    2) Automatically generated folders in independent packages should be added to the .gitignore file.


    3) The obj folders in independent packages should also be added to the .gitignore.


    4) Only your custom packages should be added to the repository. For vendor packages (from Creatio) and Marketplace packages, use the standard methods (application installation, upgrading to a new version).


    5) Never modify vendor packages (from Creatio). To extend functionality, use inheritance and entity substitution.


    6) Schema metadata is difficult to merge and understand, so it is recommended that only one developer works on extending objects or modifying a specific schema.

    7) If a developer makes changes in one environment and commits them to the repository, and others pull these changes, there should be no database and configuration desynchronization issues.

    8) You can create scripts to quickly set up the environment and pull the necessary branch from the repository. This will help avoid issues with leftover data from a different branch.

Thank you!

Show all comments

Good day.

 

Creatio has S3 integration, so there must be a S3 client inside. 

Where i can find it? Or any other possibilities to put file inside the current file storage.

 

In documentation i find example of storage implementation, witch i dont need because it is already contains S3 file storage integration.

https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/back-end-development/api-for-file-management/examples/implement-a-file-content-storage

 

And a file data saved directly in database. This case is irrelevant too because im interested to put data in current storage (SysSetting ActiveFileContentStorage), not in database.

https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platfor…

 

Appreciate any help. Thanks.

Like 0

Like

1 comments

Hello,
 

Uploading or accessing existing files should be done through the API for file management. 
We encourage you to read the documentation on the API for file management on Creatio Academy.
Also, in the documentation there is an example for creating new files using the Terrasoft.File.Abstractions.IFileFactory interface.

 

IFileFactory
 

Thank you.

Show all comments

Hi. Is it possible to make the lookup fields of a record clickable in an editable detail?

Like 0

Like

3 comments

Hello,

In order to make the lookup fields of a record clickable, you need to set the Lookup view type to "Selection window." When the Lookup view type is set to "List," the records are not clickable.

image.png

Best regards,
Antonii.

Antonii Viazovskyi,

Hello. What's most interesting is that the value of this field is selected in the Window. And it's still not clickable. Maybe there's an option to hardcode this into the detail code?

Hello,
Take a look at this discussion, I believe there you can find an answer on how to do it.

https://community.creatio.com/questions/lookup-be-displayed-link-inside…

Show all comments