New release Clio 6.0.2.11 provide support backend unit tests for Creatio package:

  • Create unit test project
  • Auto add package reference
  • Support run unit tests without Creatio environment for fast CI\CD pipelines

for details see article. Feature is a part of clio workspace and supported by clio explorer.

 

P.S: In this release also contains functionality of saving live logging into file and provide experimental functionality deactivate package for Creatio 8.1.1+

clio deactivate-package PACKAGE_NAME -e ENVIRONMENT_NAME
2 comments

Would love to see some tutorial videos, of have a training on how to maximise the use of Creatio - you guys are doing a lot of great updates recently 🙂

We already provided some video on youtube channel and this link already include in clio explorer and in future this will be grow

 

Show all comments
Idea
Discussion

For monitoring Creatio and debugging your code, Clio and Clio explorer provide Love Logging functionality. You can search and select the logger type to specify the concrete logs producer.

P.S: The latest update of Clio 6.0.2.9 and Clio explorer 2.0.49 provides extended functionality for quick locking and unlocking packages*

* update cliogate are required

0 comments
Show all comments

Hello,



I've made a page with Creatio Freedom UI and need to be able to have 1 button on the page that both adds a record and then redirects the user to a specific page.  It appears I can only have the button do 1 action or the other (save a record or open a specific page).  To do both actions with one button, I instead tried creating a business process for this.  It's adding the record fine but I am having trouble getting it to open a specific page afterwards.  Opening an edit page and choosing the home page I want the user to be directed to does not work and instead.  I think it's because edit pages on a business process are treated like tasks and are not simply a redirect. 



Should I use a script element instead to redirect the user to a specific page after the record is added in the business process or is there a more simple way to do this?

Like 1

Like

2 comments

This can be done with custom code on the Freedom UI page. You'd need to wire up the button to execute a custom request on the page: 

See https://customerfx.com/article/adding-a-button-to-execute-custom-code-o…

Then, in that custom request, you'd need to first save the page:

See https://customerfx.com/article/saving-a-page-before-some-action-on-a-cr…

And then open the other page: 

See (for opening an add or edit page): https://customerfx.com/article/opening-an-edit-page-to-add-or-edit-a-re…

Or (if the page isn't a record page): https://customerfx.com/article/navigating-to-a-page-via-code-in-a-creat…

Ryan

Ryan Farley, thank you so much for this detailed, thoughtful reply and all the articles you've written!  I was able to get the button to save a record and redirect to the desired page after with custom code. 

Show all comments

Hello,



I've made a page with Creatio Freedom UI and need to be able to have 1 button on the page that both adds a record and then redirects the user to a specific page.  It appears I can only have the button do 1 action or the other (save a record or open a specific page).  To do both actions with one button, I instead tried creating a business process for this.  It's adding the record fine but I am having trouble getting it to open a specific page afterwards.  Opening an edit page and choosing the home page I want the user to be directed to does not work and instead.  I think it's because edit pages on a business process are treated like tasks and are not simply a redirect. 



Should I use a script element instead to redirect the user to a specific page after the record is added in the business process or is there a more simple way to do this?

Like 0

Like

1 comments

Hello community!

When we create a Business Process is there C#  code generated automatically that relates to that process ?

If so where and how can I find it ?

I need the answer for debugging purposes.sa

Thank you

Sasori

Like 0

Like

2 comments

Good day,

 

Thank you for your question.

If you are using some custom methods or functions in the business processes, your code should be displayed in the source code of the process:

 

Thank you.

Thank you very much for the response Artem!

I can not see the code that is generated behind the Low-Code elements like 'Add Data' for example ?

Where is that code located , or is it generated during runtime ?

Sasori

Show all comments

Hello

I have this code that checks is a contact/account is inactive or has all the required fields filled in. If this is true, then the user is not allowed to create a new activity.

I need to add another condition for fields in account: if Customer type = "Related account" AND Customer code is not filled in -> the user is not allowed to create a new activity.

Does anybody know how I can do this?

I tried to write it like this but I think that it doesn't read my fields properly.

Thank you!

Like 0

Like

1 comments

Hello,

 

You can review the process in the Activity object from the Exchange package and the UpdateContactAndAccountByParticipant method in it:

If you need to compare actual IDs you can either specify them as new Guid("Id value here") or create a separate source code and specify values there and use this separate source code (like it's done in the DoCollectEmailParticipants method using ActivityConsts source code):

and

Show all comments

Hi guys,

I am working on a custom "ContactFieldConverter" [the thing that splits the Contact's FullName imported by excel/ webserveces etc] in order to split new contact's names into "GivenName" and "Surname", and preventing the OOTB function from filling in the "MiddleName" column.

In order to do so, I created a custom ContactGsFieldConverter in my package and inserted the value of the Separator and Converter in the Lookup "ShowNamesBy" and sysSetting "ContactFieldConverter".

[myContactGsFieldConverter code:]

 

 namespace Terrasoft.Configuration {
	using System;
	using System.Linq;
	using System.Text;
	using Terrasoft.Common;
	using Terrasoft.Configuration;
 
	#region Class: myContactGsFieldConverter
 
	/// <summary>
	/// Contact "Full name" field converter class.
	/// Separates "Full name" string using "Given name Surname" rule.
	/// </summary>
	public class myContactGsFieldConverter : IContactFieldConverter
	{
 
		#region Properties: Public
 
		/// <summary>
		/// Contact "Full name" separator characters array.
		/// </summary>
		private char[] _separator = { ' ' };
		public char[] Separator {
			get {
				return _separator;
			}
			set {
				_separator = value;
			}
		}
 
		#endregion
 
		#region Methdos: Public
 
		/// <summary>
		/// <see cref="IContactFieldConverter.GetContactSgm"/>
		/// </summary>
		/// <remarks>
		/// After splitting <paramref name="name"/> first element will be used as <see cref="ContactSgm.GivenName"/>,
		/// Everything else as <see cref="ContactSgm.Surname"/>.
		/// </remarks>
		ContactSgm IContactFieldConverter.GetContactSgm(string name) {
			var sgm = new ContactSgm();
			if (string.IsNullOrEmpty(name)) {
				return sgm;
			}
 
			var array = name.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
			switch (array.Length) {
				case 0:
					return sgm;
				case 1:
					sgm.GivenName = array[0];
					break;
				case 2:
					sgm.GivenName = array[0];
					sgm.Surname = array[1];
					break;
				default:
					sgm.GivenName = array[0];
					StringBuilder sb = new StringBuilder();
					for (var i = 1; i <= array.Length - 1; i++) {
						sb.AppendFormat("{0} ", array[i]);
					}
					sgm.Surname = sb.ToString().Trim();
					break;
			}
			return sgm;
		}
 
		/// <summary>
		/// <see cref="IContactFieldConverter.GetContactName"/>
		/// </summary>
		/// <remarks>
		/// "Full name" string will be created using "Given name [Middle name] Surname" rule.
		/// </remarks>
		public string GetContactName(ContactSgm sgm) {
			var concatChar = Separator.FirstOrDefault();
			return new[] { sgm.GivenName, sgm.MiddleName, sgm.Surname }.ConcatIfNotEmpty(concatChar.ToString());
		}
		#endregion
	}
	#endregion	
}

The converter is not working. I tried to debug and noticed that my contact converter is returned as null to [this is a method in the Contact c# object]: 

public virtual void SetSgm(Contact contact) {
			if (contact == null) {
				return;
			}
			contact.FillSgmFields(GetContactConverter());
		}

Do you know if I need to do something specific in case of separate-assembly package?

ie: Using a different namespace for the converter/ setting the converter path in a different way within the system setting/ recreate the method on the Contact Object in my custom package.





Thank you in advance!

Like 1

Like

5 comments

Hello Federica,

 

I just completed the test - convertor works in the assembly package as well. The code (since we don't need middle name) was:

namespace Terrasoft.Configuration {
    using System;
    using System.Linq;
    using System.Text;
    using Terrasoft.Common;
    #region Class: UsrCustomContactFieldConverter
    /// &lt;summary&gt;
    /// Contact "Full name" field converter class.
    /// Separates "Full name" string using "Surname Given name" rule.
    /// &lt;/summary&gt;
    public class UsrCustomContactFieldConverter : IContactFieldConverter
    {
        #region Properties: Public
        /// &lt;summary&gt;
        /// Contact "Full name" separator characters array.
        /// &lt;/summary&gt;
        private char[] _separator = { ' ' };
        public char[] Separator {
            get {
                return _separator;
            }
            set {
                _separator = value;
            }
        }
        #endregion
        #region Methdos: Public
        /// &lt;summary&gt;
        /// &lt;see cref="IContactFieldConverter.GetContactSgm"/&gt;
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// After splitting &lt;paramref name="name"/&gt; first element will be used as &lt;see cref="ContactSgm.Surname"/&gt;,
        /// second element as &lt;see cref="ContactSgm.GivenName"/&gt;
        /// &lt;/remarks&gt;
        ContactSgm IContactFieldConverter.GetContactSgm(string name) {
			var sgm = new ContactSgm();
			if (string.IsNullOrEmpty(name)) {
				return sgm;
			}
			var array = name.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
			switch (array.Length) {
				case 0:
					return sgm;
				case 1:
					sgm.GivenName = array[0];
					break;
				default:
					sgm.GivenName = array[0];
					sgm.Surname = array[1];
					break;
			}
			return sgm;
		}
        /// &lt;summary&gt;
        /// &lt;see cref="IContactFieldConverter.GetContactName"/&gt;
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// "Full name" string will be created using "Surname Given name" rule.
        /// &lt;/remarks&gt;
        public string GetContactName(ContactSgm sgm) {
            var concatChar = Separator.FirstOrDefault();
            return new[] { sgm.Surname, sgm.GivenName }.ConcatIfNotEmpty(concatChar.ToString());
        }
        #endregion
    }
    #endregion
 
}

and then this convertor was registered in the database (ShowNamesBy table). As a result newly created contacts where full name is Test 1 2 had the first (Test) and last (1) name only while middle name was skipped.

Hi Oleg Drobina,

Could you share with me the record registered in the database table ShowNamesBy for a separate assembly pkg?

Hence, in case the site receives a Contact "Name": "Federica Rose Cattani" I don't want to "lose" the "MiddleName" but I want it to be concat to the "Surname". That's what I did in the converter shared. 

Federica,

 

Hi,

 

Sorry, I guess I was wrong with the package. Tested the same approach today and it didn't work until I unchecked the "Compile into separate assembly" checkbox in the package settings. So in your case you need to also do the same to make the converter work.

 

The insert was:

INSERT INTO ShowNamesBy (Name, Separator, Converter) VALUES (N'UsrCustomContactFieldConverter', N' .,;', N'Terrasoft.Configuration.UsrCustomContactFieldConverter');

 

Oleg Drobina,

Ok! In my case I can't "undo" the separate assembly since it contains customer's implementation and separate assembly it's way faster to compile.

The actual possible workaround would be to implement a second package without separate assembly containing only the custom ContactGsFieldConverter, am I correct?

Hello, some conclusion regarding this, in Spain we have the same problem with names than in Italy

Show all comments

Hi all

I have created a web service that accepts values from a third party server. Next, I need to transfer one value from the request to the section field.

Question:

How do I call my finished web service in C#?

Like 0

Like

4 comments

Hi,

Are you talking about a service created in the configuration or in the "Web services" section?

Dmytro Vovchenko, in the web services section

 

the question is how to set up its call in c#, so that in the future to use its result in one of the fields of the section

 

Alexandr Bezbozhnov,

As far as I know, currently, there is no direct way of running this sort of web service from code. However, you can run it inside a business process and you can run this process inside C# code using

ProcessEngineService.svc, with it you even can get the result values of the process.

Show all comments

Hi everyone,

how to use filter month and year Esq Server (EntitySchemaQuery)?

SELECT 
* 
FROM UsrTable 
WHERE 
MONTH(CreatedOn) = 1 AND YEAR(CreatedOn) = 2022

I found there is a function at https://academy.creatio.com/api/netcoreapi/7.17.0/#Terrasoft.Core~Terrasoft.Core.Entities.EntitySchemaQuery~CreateMonthFunction.html for get month and year.

https://prnt.sc/8brMGtYq3qhP

But how to use in filter?

esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "CreatedOn", Month));
esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "CreatedOn", Year));

Thank you.

Like 1

Like

1 comments
Best reply

Hello Romadan,

You can do filters like this using macros: 

// CreatedOn is the 1st month (January)
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.Month, 1));
 
// CreatedOn is the first day of the month
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.DayOfMonth, 1));
 
// CreatedOn is in the year 2022
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.Year, 2022));

Ryan

Hello Romadan,

You can do filters like this using macros: 

// CreatedOn is the 1st month (January)
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.Month, 1));
 
// CreatedOn is the first day of the month
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.DayOfMonth, 1));
 
// CreatedOn is in the year 2022
esq.Filters.Add(esq.CreateFilter(FilterComparisonType.Equal, "CreatedOn", EntitySchemaQueryMacrosType.Year, 2022));

Ryan

Show all comments

Hello Community,

 

We have a requirement for fetching all the column names of an object using source code.

 

I have taken this community post https://community.creatio.com/questions/get-title-columns-esq as reference and tried.

 

As per the article, the below code is used for fetching the column names after fetching the entity collection.

 titleColumnCaption = entity.Schema.Columns.GetByName("Title").Caption.Value;

But the code returns the null value.

 

Kindly let us know whether the above line of code is correct or not?

If not, suggest us an other way to achieve the functionality.

 

Thanks,

Sivaranjani

Like 0

Like

2 comments

Hello Sivaranjani,

 

It happens because the code above returns the "Title" column caption only and if your object doesn't have the column with such a name the result is null.

 

You need to use something like:

var columnCaptionsArray = activityEntity.Schema.Columns;
    foreach (var columnCaption in columnCaptionsArray)
    {
    	var captionForColumn = columnCaption.Caption.Value;
    }

and use the captionForColumn in your logic furhter.

 

Best regards,

Oscar

Oscar Dylan,

Thanks for the reply. The above code is working.

Show all comments