Is it possible to set the value of a System setting which has the "Save value for current user" setting enabled for a specified user from C# code, e.g. from a script task? I've found the below code for setting a System setting, but presume that if the checkbox for the above is selected, then it will only set the value for the current user (or the System User if running in the system context):

var settingCode = Get<string>("UsrSystemSettingCode");
var value = Get<string>("UsrSettingValue");
Terrasoft.Core.Configuration.SysSettings.SetValue(UserConnection, settingCode, value);
return true;

 

We need to be able to set the per-user system setting for a specific user (determined by data in the BP in our case) but looking at the (always hard to find) API documentation, it doesn't seem like there's an overloaded version of SetValue that allows you to do so as a specified user - except possibly one that is marked as being deprecated in a much older version:

 

Like 0

Like

3 comments

Anybody have any info on this?

Does anyone have any other methods for managing per-user system settings in Creatio? It seems like there aren't a lot of options besides setting them in JS code when a user does a given action, but then that feels like it defeats some of the purpose of system settings being that the value doesn't have to be calculated every time a user does something, and also means it can't reliably be used for tasks like setting a default field value on an entity.

Contemplating using this methodology for running code when a user logs in to set it, hopefully it will work. Would be nice to have some clean way of doing it though, especially since we don't really need to be calculating it every time a user logs in but just when certain data changes: https://customerfx.com/article/executing-code-in-creatio-application-an…

Show all comments

Hi,

I'm trying to pass the result of below "json" (in script task),

var schema = UserConnection.EntitySchemaManager.GetInstanceByName("Account");

    var entity = schema.CreateEntity(UserConnection);

    entity.FetchFromDB(id);

    json = Terrasoft.Core.Entities.Entity.SerializeToJson(entity);

 

to a process parameter and that process parameter needs to be passed to web service element as an request object. Since, the structure of "json" variable might vary, how to send this to a process parameter and eventually to web service element?

 

Any suggestions would be appreciated. Thanks.

Like 2

Like

5 comments

public bool FetchFromDB(object keyValue, bool useDisplayValues = true)

All the `FetchFromDB` methods return a bool, you could test the call.

SerializeToJson(Entity)

Should work.

 

I've had a great deal of trouble with JSON in Creatio in the past.   What's the error you're getting?

Hi Gareth,

Thanks for your reply.

Is there a sample as how this can be sent to webservice element? Use case is to handle this as an object while sending it to webservice element and not as a string. For example, the request at the web service element should look like below.

{

"objectName" : "Contact",

"Payload" : { "Name" : "Halludeen", "Age" : 24 }

}

But, if I pass it as a string then it looks like,

{

"requestJson" : "{\r\n \"ObjectName\": \"Contact\", \r\n \"Payload\": { \"Name\" : \"Halludeen\"}"

}

 

Let me know if you have any suggestions for this.

 

Thanks again.

 

 

 

Halludeen,

The only JSON library I have been able to get to work in Creatio is 

`System.Text.Json.JsonSerializer`.  You have to call it with the full namespace rather than add the namespace in a `using` statement, see here.

 

You could use the `Serialize<TValue>(TValue, JsonSerializerOptions)` method.  The technique is essentially the reverse of the example linked to above, create an object for the deserialised JSON in a module (see example), add the namespace to your process, create an object with the data you want to serialise, and serialise it using the above method into a string.  Hopefully that will work!

Gareth Osler,

Having said the above, I wrote in June,

By way of an epilogue, while the `System.Text.Json` namespace is available in a trial, for some reason it was not available in the dev environment I was using.  However classes in the `Terrasoft.Common.Json` namespace were available.  I was able to use the `Deserialize<T>(String)` method of the Json class.  (Note at the time of writing the `DeserializeDictionary(String)` method has a bug in it and cannot be used.)

You may have to use the above class to do the same.

Show all comments

Hello!

 

I have this array that gives me the prefixes of phone numbers. I need to use it in a Process in Script Task.

I don't really like that I have to add all the values in the array manually. Is there an option to get the values from a lookup and to add them in an array?

 

I would like to just create a lookup for all the prefixes instead of adding them one by one in the array.

 

Thank you!

Like 0

Like

1 comments

Hi,

 

In the business process you can read collection of records using examples provided here, add the result to some parameter and then process this parameter. Otherwise you can read values using standard "Read data" element in a cycle (which is not a good approach) and each read value can be also added to the array. 

Show all comments

Hi!

 

I wanted to add a pop-up through a script task and i used this:

 

this.showInformationDialogue("Message");

return true;

 

The problem is that it says that it doesn't recognize showInformationDialogue. I tried to add Terrasoft libraries, but it says that I can't use "using Terrasoft..." in a script task.

 

Does anybody have any idea how I can add a pop-up?

 

Thank you!

Like 0

Like

1 comments
Best reply

The only way this can happen is to send a message to the UI/browser from the script task. On the page or somewhere in the UI you need to listen for that message. Then, when received, display the popup message. 

I have an article here about how to send the message from the backend process/script task to the client: https://customerfx.com/article/sending-a-message-from-server-side-c-to-…

And an article about displaying popup messages from client-side code here: https://customerfx.com/article/displaying-information-confirmation-and-…

Ryan

The only way this can happen is to send a message to the UI/browser from the script task. On the page or somewhere in the UI you need to listen for that message. Then, when received, display the popup message. 

I have an article here about how to send the message from the backend process/script task to the client: https://customerfx.com/article/sending-a-message-from-server-side-c-to-…

And an article about displaying popup messages from client-side code here: https://customerfx.com/article/displaying-information-confirmation-and-…

Ryan

Show all comments

Hi!

 

I found this article where you can add a 'Refresh page' through a script task in a process. It uses this: "Terrasoft.Configuration.MsgChannelUtilities.PostMessageToAll("FXRefreshContactPage", "");"

How to Refresh a Page from a Process in Creatio (formerly bpm’online) | Customer FX

 

Is there a way to do the same for adding a po-up?

I tried with "this.showInformation()" but it doesn't work.

 

Also, I tried the Add-on from the Marketplace but it doesn't work.

 

Thank You!

Like 0

Like

1 comments

Hello,

 

You need to add the client-side handler method for the received message from the server (using ClientMessageBridge described here) and in this method handler (like onNewUserSet in the example) call the showInformation method and display the popup.

Show all comments

Hi, 

 

I'd liket to create a script task in a business process, that given an email template, it executes it on a specific context. I mean, if the email template is based on a custom macro related with the Lead entity, I can pass the LeadID and the emailTemplateId to the script task, and the result is the text of the email template executed for that specific lead. 



Is there way to do that?



Thanks!

Ignacio 

Like 0

Like

4 comments

Hi Ignacio,

 

You can pass LeadId and the TemplateId as process parameters (create two Guid parameters in the process settings). Then you can use the "Read data" element and read specific columns of the lead record (use the LeadId parameter in the "Read data" filtration to get the value for needed columns). Then you can create additional text parameters and pass the read column values to them (using formulas for example). The same approach is for the "Email template" object and TemplateId parameter (you need to get the template body, so you need to read it in the "Read data" process element). And finally you can use string interpolation (or String.Replace method) in the script task to replace macroses (macorses, not their values, like [#UsrSomeColumn#], it's passed in the template body) with the actual values read from the "Lead" object using the "Read data" element (the ones that we wrote to the process parameters). To get process parameters values in the script task you need to use Get<string>("ParameterCode") (see more examples here) construction in the script task, then you can use String.Replace in the following manner:

string UsrStringParameterValueToUse = Get&lt;string&gt;("UsrStringParameterValue");
string EmailTemplateBody = Get&lt;string&gt;("UsrEmailTemplateBodyParamter");
EmailTemplateBody= EmailTemplateBody.Replace("[#UsrSomeColumn#]", UsrStringParameterValueToUse);

And then you can return EmailTemplateBody to some another string parameter value using Set<string> command and as a result you will get the result needed.

Thank you for your response Oleg!

 

Right, that would be the "manual" approach. I was hoping I could reuse the same service that is being used when creating an email from a template. For example, I can use a ReportService to generate a printable inside a business process. I was hoping that we have in Creatio something like "EmailService" that processes an email template and returns the generated text.

Pavel Shkomov,

 

You need to use the script-task to send the email from the code directly. Please see this Academy article that describes how to form and send the email from the code (this article also have examples of implementations, please use the "Examples" tab at the top of the article).

Ignacio Alvarez,

 

there is another approach:

var macrosHelperClassFactory = ClassFactory.Get&lt;MacrosHelperV2&gt;(new ConstructorArgument("userConnection", UserConnection));
 
string emailTemplateCode = Get&lt;string&gt;("ResultEmailTemplatePlain");
string templateEntityName = Get&lt;string&gt;("ContactEntityName");
Guid templateEntityId = Get&lt;Guid&gt;("ContactRecordId");
 
var replacementResult = macrosHelperClassFactory.GetTextTemplate(emailTemplateCode, templateEntityName, templateEntityId);
Set&lt;string&gt;("ResultEmailTemplateHTML", replacementResult);
return true;

There should be also the following parameter values:

1) the code is ContactEntityName - Text (50 characters) data type ("Contact" value by default) - represents the object from which data for macros is selected

2) the code is ContactRecordId - Unique identifier data type - represents the record Id to get data for macroses

3) the code is ResultEmailTemplateHTML - Unlimited length text data type - contains the template with filled macroses

4) the code is ResultEmailTemplatePlain - Unlimited length text data type - contains the template without filled macroses

 

Also you need to add the following namespaces to the process usings:

Terrasoft.Configuration.Utils

Terrasoft.Core.Factories

 

You need to use the "Read data" process element and read specific email template (the object is "Message template") and you need only the "Body" column value. Then the read body of the template should be passed to the "ResultEmailTemplatePlain" parameter using the "Formula" process element.

 

As a result of the script-task process element you will get the formed email template body with filled macroses in the ResultEmailTemplateHTML parameter that can be then displayed for example using the autogenerated page.

Show all comments

Hi,

I want to use function that are not included in System library/package.

I need to add the following in order to use the functions.

using System.Linq;

I tried adding this to the script but got an error message: " Feature 'using declarations' is not available in C# 7.3. Please use language version 8.0 or greater."

Is there a way to add the 'System.Linq' somewhere?

Thanks,

Chani

 

Like 0

Like

1 comments

Hi Chani,

 

This error means that either the .Net Framework version in your server where the app is hosted is not 4.7.2 and higher or .Net Core version is not 3.1.301 and higher. Also you need to double-check that all the required components were enabled in the IIS settings.

 

Best regards,

Oscar

Show all comments

In the previous versions of Creatio, In the User Task element there was the Script where you could implement the task logic, as shown in the image below

In which part of the User Task Source code , in the 7.18 Version of Creatio, should I implement the same logic ? 

 

Like 0

Like

3 comments

Hello Petrika,

 

Thank you for your question!

 

You can read more on this here:

https://academy.creatio.com/docs/user/bpm_tools/process_elements_refere…

 

Kind regards,

Anastasiia

Anastasiia Lazurenko,

Thank you Anastasia for your quick reply. But this is a different approach. I am not asking about the Script Task, but about the User Task.Because i want to use my logic in different bussiness processes.

Dear Petrika,

 

This logic is still the same. Please refer to the screenshots below:

 

 

Kind regards,

Anastasiia

Show all comments

Hi,

I read collection of records using this script:

var entities = Get>("ReadDataUserTask2.ResultCompositeObjectList");

I want to loop through this list and set parameter with type contact to each object of the list.

The collection of records is a list of opportunityContact.

I tried converting each ICompositeObject to opportunityContact using this script:

foreach (var entity in entities)

{

 ...

    OpportunityContact contactInOpp = (OpportunityContact)entity;

    Set("contact",contactInOpp.Contact);

but OpportunityContact is not a known object.

How do I access the types of the tables (no need to add data to DB or search just get the type in order to convert)?

Thanks,

Chani

 

Like 0

Like

2 comments

Hi Chani,

 

Here is a working example of two cases: set the string parameter value from the process that reads the collection and also modify contacts massively in the script task based on the received collection.

 

Here is the screenshot of the main process:

and the screenshot of the sub-process:

The idea of the sub-process is to read the collection of 4 records and their emails, Ids and Names if to be more specific. Then the read values are passed to the main process as a collection and go to the main process parameters (see that the "OutputParameters" parameter has the value of "[#SubProcess that will read all the needed data from Contacts 1.OutputRecordCollection#]").

 

The script task itself calls the ProcessContactNames method that is specified in the main process "Methods" tab:

The listing of the code is below:

public void ProcessContactNames() {
	string result = "";
	var contactsList = Get&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("OutputParameters");
	foreach (ICompositeObject item in contactsList) {
				item.TryGetValue&lt;string&gt;("FullNameParameter", out string ContactName);
				item.TryGetValue&lt;string&gt;("EmailParameter", out string ContactEmail);
				item.TryGetValue&lt;Guid&gt;("IdParameter", out Guid ContactId);
				result = result + " " + ContactName + " " + ContactEmail + ", ";
				ContactName = "Oscar Dylan from process";
					var contactSchema = UserConnection.EntitySchemaManager.GetInstanceByName("Contact");
					var entity = contactSchema.CreateEntity(UserConnection);
						entity.FetchFromDB("Id", ContactId);
						entity.SetColumnValue("Name", ContactName);
						entity.Save();
			}
Set&lt;string&gt;("StringParameter", result);
}

Also add the following usings to your main process:

System.Data
System.Security
Terrasoft.Configuration

The idea here is to pass the collection of records from the "OutputParameters" main process parameter, process each record in the foreach cycle, compose the result string that then will be displayed on the autogenerated page to check if the process worked and also find each contact by its Id that was passed from the collection and set the name column value for each contact as "Oscar Dylan from process".

 

As a result the process worked perfectly:

and contact names were modified:

Please analyze the process and use the same approach on your side.

 

Best regards,

Oscar

Oscar Dylan,

Thank you. 

Will try that.

Show all comments

Hi everyone,

I have created a script task to create new records from a csv.

I am trying to implement a method to search the db for a matching record and then update it (in case it exists).

The second part (the 'else' part, it's working fine) 

Does anybody know how to filter and search a DB table? What am I getting wrong?

 

 

void saveLine(string line, int rowNumber){

    if(rowNumber!=0)

    {

        string lineFormatted = line.Replace("\"", "");

        string[] lineSplitted = lineFormatted.Split(',');

        var LRNMBL = lineSplitted[0];

        var LRRIGA = lineSplitted[1];

        var LRDTBL = lineSplitted[3];

        var LRCANA = lineSplitted[6];

        // Creation of query instance with "Contact" root schema. 

       

        // An EntitySchemaQuery instance that accesses the UsrTestFTPCall table of the database.

        var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "UsrVedniteTestate");

        

       

        // Adding columns to the query.

        esq.AddColumn("UsrLRNMBL");

        esq.AddColumn("UsrLRRIGA");

        esq.AddColumn("UsrLRDTBL");

        esq.AddColumn("UsrLRCANA");

        // Filter the query data. according to LRNMBL and 

        var esqFirstFilter = esq.createColumnFilterWithParameters(Terrasoft.ComparisonType.EQUAL,"UsrLRNMBL", LRNMBL);

        var esqSecondFilter = esq.createColumnFilterWithParameters(Terrasoft.ComparisonType.EQUAL,"UsrLRRIGA", LRRIGA);

        

        esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;

        

        esq.filters.add("esqFirstFilter", esqFirstFilter);

        //esq.Filters.Add(esqSecondFilter);

          

      

        // Get the result of the query.

        var entities = esq.GetEntityCollection(UserConnection);

        // If the data is received.

        if (entities.Count > 0)//Record exists in the db --> update

        {

           var recordToUpd = entities[0];

           recordToUpd.SetColumnValue("UsrLRNMBL", LRNMBL);

           recordToUpd.SetColumnValue("UsrLRRIGA", LRRIGA);

           recordToUpd.SetColumnValue("UsrLRDTBL", LRDTBL);

           recordToUpd.SetColumnValue("UsrLRCANA", LRCANA);

        }

        else 

        {

            //the record doesn't exist --> Create one

               var TestObj = UserConnection.EntitySchemaManager.GetInstanceByName("UsrTestFTPCall").CreateEntity(UserConnection);

            //access the data position and assign it to its column

            TestObj.SetDefColumnValues();

            //Associate new column values to old Col values

            TestObj.SetColumnValue("UsrName", rowNumber.ToString());

            TestObj.SetColumnValue("UsrLRNMBL", LRNMBL);//riferimento testata di vendita

            TestObj.SetColumnValue("UsrLRRIGA", LRRIGA);//riferimento riga all'interno della stessa vendita

            TestObj.SetColumnValue("UsrLRDTBL", LRDTBL);

            TestObj.SetColumnValue("UsrLRCANA", LRCANA);

            TestObj.Save();

           }

    }

}

 

Like 0

Like

4 comments

Hello,

I don't see anywhere in the code where you're saving the updates made to the entity in recordToUpd. Try adding the following to have it save the values in the database:

recordToUpd.UpdateInDB();

Ryan

Hello Federica,



Yes, try to add the method that Ryan recommended you. It will help to resolve the issue.



Best Regards,

Tetiana

Hi Ryan,

 

The problem is to access and filter records in the db.

That part of the script ain't working.

Hi Tetiana Bakai,

The main issue atm lays in the filtering and db-access part.

Show all comments