Hello,



I would like create multiple buttons that call a business process. Due to the number of buttons in my page, I would like to create a single button click method. This method would receive a parameter that would tell it which button was called. The parameter would then determine which field would be read.



My button method should look something like this:

 onButtonClick: function(clickedButton){
				var recordId = this.get("Id");
                var readField = "Error"; //This value should change later, will show error otherwise
 
                switch(clickedButton){
                    case "Button1":
                        readField = this.get("Field1");
                        break;
                    case "Button2":
                        readField = this.get("Field2");
                        break;
                    /*More Cases
                    .
                    .
                    .
                    */
                   default:
                    console.log(readField);
                    break;
                }
 
                var config = {
                    sysProcessName: "UsrBpToCall",
                	parameters: {
						CurrentRecordId: recordId,
						ReadField: readField,
 
					}
				};
                ProcessModuleUtilities.executeProcess(config);
}

I assume the parameter would appear in the diff section, but I do not know how to implement this functionality.



I appreciate your help!

 

Kind Regards,

Firas



 

Like 1

Like

3 comments
Best reply

Hello Firas,

If you add a tag to each button it will get passed as the fourth parameter to the click handler. 

For example:

{
	"operation": "insert",
	"parentName": "Detail",
	"propertyName": "tools",
	"name": "MyButton1",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": "Send selected invoice",
		"click": {"bindTo": "onMyButtonClick"},
		"tag": "MyButton1"
	}
}

Then you can retrieve the tag in the click function handler like this: 

onMyButtonClick: function(p1, p2, p3, tag) {
    console.log(tag);
}

Ryan

Hello Firas,

If you add a tag to each button it will get passed as the fourth parameter to the click handler. 

For example:

{
	"operation": "insert",
	"parentName": "Detail",
	"propertyName": "tools",
	"name": "MyButton1",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": "Send selected invoice",
		"click": {"bindTo": "onMyButtonClick"},
		"tag": "MyButton1"
	}
}

Then you can retrieve the tag in the click function handler like this: 

onMyButtonClick: function(p1, p2, p3, tag) {
    console.log(tag);
}

Ryan

Ryan Farley,



the solution works perfectly. Thank you.



I have a follow-up question if you do not mind. Does the tag being passed as the fourth argument mean that button click methods can take up to 4 arguments?  If that is the case how can one proceed if they were to pass more than one argument and populate p1 through p3? 



Thank you again, your Community responses and articles have been very helpful.



Firas

Hello,

 

Not sure about passing 4 arguments to the click event, I've been using the tag property only to pass the parameter needed. In your case you can bind the click-handler method to several buttons and specify different tags for it so the click-handler method could understand what to do according to the button tag.

Show all comments

I'm trying to Creating command Run process in command Line 

but i faced an issue the Keyword doesn't open to chooses Run process in studio module

Like 0

Like

1 comments

Hello,



Unfortunately, there is no way to run the process by the command line for now. 

 

We've registered it in our R&D team backlog for consideration and implementation in future application releases. Thank you for helping us to improve our product. 



Best regards,

Bogdan

Show all comments

I want to put button beside the group. Is the structure of groups and details different?

Like 0

Like

2 comments

I was only able to put the button inside the ControlGroup, but not in the "tools" container since ControlGroups have no "tools" container (like standard details). The result was as follows:

It seems that its impossible to put the button beside the group, but it's possible to put it inside the group using the code like below:

{
				"operation": "insert",
				"name": "ContactCategoriesControlGroup",
				"parentName": "GeneralInfoTab",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.CONTROL_GROUP,
					"caption": {"bindTo": "Resources.Strings.ContactCategoriesControlGroupCaption"},
					"items": []
				},
				"index": 0
			},
			{
				"operation": "insert",
				"name": "ContactCategoriesControlGroupButton",
				"parentName": "ContactCategoriesControlGroup",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"caption": {bindTo: "Resources.Strings.ContactCategoriesControlGroupButtonCaption"},
					"style": Terrasoft.controls.ButtonEnums.style.BLUE
				}
			},
			{
				"operation": "insert",
				"name": "ContactCategoriesControlGroupContainer",
				"parentName": "ContactCategoriesControlGroup",
				"propertyName": "items",
				"values": {
					"itemType": Terrasoft.ViewItemType.GRID_LAYOUT,
					"items": []
				}
			},
			{
				"operation": "insert",
				"name": "RelatedContact",
				"parentName": "ContactCategoriesControlGroupContainer",
				"propertyName": "items",
				"values": {
					"bindTo": "UsrContact",
					"layout": {
						"column": 0,
						"row": 0,
						"colSpan": 12
					}
				}
			},

So either use this approach or add a button to the "Actions" menu or to the top of the page.

 

Best regards,

Oscar

Oscar Dylan,

 

I think for group and detail have the same environment. but apparently not.

Thanks for the answer Oscar!

Show all comments

При попытке добавления блока с пользовательским кодом возникает ошибка

An attempt to add a script task causes an error

System.InvalidCastException: Specified cast is not valid.
   at Terrasoft.Core.Process.ProcessModel.GetParameterValue[T](FoundParameterData result)
   at Terrasoft.Core.Process.Process1MethodsWrapper.ScriptTask1Execute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessScriptTask.InternalExecute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)

Сам код в блоке выглядит так: 

The code itself looks as following:

double result = Get<double>("amount") * Get<float>("rate") / Get<int>("division");
Set("result", result);
return true;

У меня нет опыта работы с BPMN, поэтому я не знаю, где именно я ошибся. Всё, что делают формулы - это запись данных из справочника в параметры процесса.

Заранее спасибо!

I'm totally new to BPMN so I have no idea where the error may be. The formulas only save lookup values into process parameters. 

Thanks in advance!

File attachments
Like 0

Like

2 comments

By the way, if there is a list of data type matches for decimal values (as I understood, float does not match all of them), I would really appreciate a link.

Кстати, если существует список соответствий типов данных для дробных значений (как я понял, float подходит не для всех), я был бы очень благодарен за ссылку.

Я нашёл необходимый тип данных, им оказался decimal. Вопрос можно закрыть

Вот ссылка на перечнь соответствующих типов:

Элемент процесса [Задание-сценарий] | Creatio Academy (terrasoft.ru)

I've found the necessary data type, it turned out to be decimal.

Above there is a link to a list of data type matches

Show all comments

hi all 

first of all i have 2 sections (Returns - Events) , and i have customized contacts section and by adding detail in it with these specs

"

- Add a new “Returns” tab.

- Add the following elements on the “Returns” tab

- The “Return requests” detail with the list of requests initiated by the current contact.

 - The “Total ticket return amount” metric

"

 

after that  i need to do this next detail 

 - Create a new “Tickets” detail without creating a new section. (done)

- The detail must contain the following fields:

 “Owner” (a contact). (done)

 “Ticket cost”.  (done)

 “Event”. (done)

“Return type”. (done)

 

 - The detail must be displayed on the page of return request and the user must be able to specify tickets from the current request on the detail.

- Set up the detail object: 

-The detail must inherit permissions from the return request.

- The records on the detail must be deleted automatically if the request is deleted

 

the last 4 points i don't know how i do them ? 

Help 

 

thanks

 

Like 1

Like

2 comments
Best reply

Ibrahim, 

If i understood you correctly: 



1. The detail must be displayed on the page of return request and the user must be able to specify tickets from the current request on the detail. 



Add Lookup field "Returns" (in my case it's going to be "Account") to the object of your detail. In [Data Source -> Lookup] select "Returns"



Then, when you're adding the detail to the page please set following settings: 



2.- Set up the detail object: 

-The detail must inherit permissions from the return request. 




After you've added lookup column "Returns", scroll down to "Access Rights" and select "Returns" in the field( see screenshot, in my case the column looks  up Account section, so it's " account")



3.
 - The records on the detail must be deleted automatically if the request is deleted



Select your lookup column (in my case it's Account) and select "Delete objects from current object with this value. 

That way, when the return is deleted, all the tickets associated to that return will also be deleted 





Best Regards,

Yurii. 

Ibrahim, 

If i understood you correctly: 



1. The detail must be displayed on the page of return request and the user must be able to specify tickets from the current request on the detail. 



Add Lookup field "Returns" (in my case it's going to be "Account") to the object of your detail. In [Data Source -> Lookup] select "Returns"



Then, when you're adding the detail to the page please set following settings: 



2.- Set up the detail object: 

-The detail must inherit permissions from the return request. 




After you've added lookup column "Returns", scroll down to "Access Rights" and select "Returns" in the field( see screenshot, in my case the column looks  up Account section, so it's " account")



3.
 - The records on the detail must be deleted automatically if the request is deleted



Select your lookup column (in my case it's Account) and select "Delete objects from current object with this value. 

That way, when the return is deleted, all the tickets associated to that return will also be deleted 





Best Regards,

Yurii. 

Yurii Sokil,

thank you 

Show all comments

I'm trying to create virtual column lookup. But, the result is the lookup view by default open with Selection Window, in other side I want to change to list.

 

How to implement this functionality?

Like 0

Like

4 comments
Best reply

Hi Ahmad,

You can add "isSimpleLookup" to the virtual lookup attribute to make it a drop-down instead of a popup lookup window.

Example:

"TypeLookup": {
    dataValueType: Terrasoft.DataValueType.LOOKUP,
    isSimpleLookup: true,
    referenceSchemaName: "AccountType"
}

Ryan

Hi Ahmad,

 

please refer to this link where the same question is explained

 

https://community.creatio.com/questions/convert-comboboxedit-gridlist-o…

 

P.S. It will be much easier to create lookups and choose the required view in Lookup Settings. Please check the example below :

 

 

Best Regards, 

 

Bogdan L.

 

Hi Ahmad,

You can add "isSimpleLookup" to the virtual lookup attribute to make it a drop-down instead of a popup lookup window.

Example:

"TypeLookup": {
    dataValueType: Terrasoft.DataValueType.LOOKUP,
    isSimpleLookup: true,
    referenceSchemaName: "AccountType"
}

Ryan

Ryan Farley,

Thank you Ryan, this is what I was looking for.

Bogdan Lesyk,

Hello Bogdan, I actually created a virtual column. So i can't change the configuration through page setup.

Show all comments

Hi,

how can I change the code in client modules and add my own? I am still a beginner and it would be cool if someone could help me understand how to work with modules in Creatio. In general, I have a task: I need to figure out how to change the title on the "contacts" page. I need to understand how to change the name (here it is Aссom)

Like 0

Like

3 comments

Hello!

 

The title of the record can be changed on the record page itself:

 

More detailed information about section records like accounts and contacts can be found in the Accounts and contacts Academy article. 

 

If you require any additional assistance on the Creatio system workflow, you can contact our Info Department at info@creatio.com. We will be happy to support you. 

 

Best regards,

Olga. 

Olga Avis,

thanks for the answer! I have one more: how can i modify the code in custom creatio packages? For example, I want to change the base code to mine

Hello Adam, 

 

Please take a look at the Getting started with the development Academy article and its sub-articles:

If you would like to know more about the specifications of the Creatio system, you can refer to the Creatio Training features like e-learning courses, guided learning, webinars, etc. 

 

Kind regards, 

Olga. 

Show all comments

Hi Community,

In chart is is possible to add/remove series dynamically based on section filter 

 

Like 0

Like

1 comments

Hello Fulgen,

As for now there is no possible to achieve this task since if there are no records returned based on filtering conditions - the serie appears on dashboard anyway and returns 0. We do already have the request to modify this logic registered to our R&D team and this problem is in "Accepted" status. I will also inform our R&D team about this question so to raise the priority of the problem.

Thank you for helping us to make our application better!

Best regards,

Oscar

Show all comments

Hi Team

I created a Node.js script to upload attachments using FileApiService.

Here is my script:

var axios = require('axios');

var fs = require('fs');

establish_connection();

 

async function establish_connection()

{

        axios.post('https://company_name.bpmonline.com/ServiceModel/AuthService.svc/Login',

        {

            "UserName":"xxxxxxx",

            "UserPassword":"xxxxxxxxxxx"

            

        }).then (function (response){

            console.log('Imported credentials cookie from BPM Online!')

            c=response.headers['set-cookie']

            var bpm_loader=c[0]

            bpm_loader = bpm_loader.replace('BPMLOADER=','')

            bpm_loader=bpm_loader.split(';')[0]

            var aspx_auth=c[1]

            aspx_auth = aspx_auth.replace('.ASPXAUTH=','')

            aspx_auth=aspx_auth.split(';')[0]

            var bpm_csrf=c[2]

            bpm_csrf = bpm_csrf.replace('BPMCSRF=','')

            bpm_csrf=bpm_csrf.split(';')[0]

            var user_name=c[3]

            user_name = user_name.replace('UserName=','')

            user_name=user_name.split(';')[0]

            var auth = 'BPMLOADER='+bpm_loader+'; .ASPXAUTH='+aspx_auth+'; BPMCSRF='+bpm_csrf+'; UserName='+user_name+';';

            console.log('Authentication Successful!')

            upload_attachments(auth,bpm_csrf)

        }).catch(error => {

            console.log(error)

        })

}

async function upload_attachments(auth,bpm_csrf) {

  let myPdf = fs.readFileSync("./file_name.pdf");

  let myData = myPdf.toString("base64");

 

  let myBody = {

    Name: "test.pdf",

    Data: myData,

    TypeId: '529bc2f8-0ee0-df11-971b-001d60e938c6',//This indicates that the type of the attachment is file

    Version: "1",

    Usr_reference_column_id: 'xxxxxguid_of_the_record_xxxxxxxx'

  };

 

  let options = {

    method: "POST",

    url: 'https://company_name.bpmonline.com/0/rest/FileApiService/Upload',

    headers: {

        "fileapi14998570381414":"",

      "cache-control": "no-cache",

      "Accept-Encoding": "gzip, deflate",

      "Cache-Control": "no-cache",

      Accept: "*/*",

      "Content-Type": "application/json;odata=verbose",

      Cookie:auth,

      BPMCSRF:bpm_csrf,

      "entitySchemaName":"Usr_id_of_the_file_section"

    },

    body: myBody,

    json: true

  };

 

  request(options, function(error, response, body) {

    if(!error)

    {

        console.log('Success!')

        console.log(response)

    }

    else

    {

        console.log('Failed!')

        console.log(error)

    }

  });

}

 

References: 

1. https://community.bpmonline.com/questions/sending-blob-file-node

2. https://community.bpmonline.com/questions/upload-files-case

3. https://community.bpmonline.com/questions/how-upload-attachments-odata

4. https://community.terrasoft.ru/questions/realizacia-peredaci-pdf-dokumenta-po-protokolu-odata-s-ispolzovaniem-http-zaprosov

5. https://community.terrasoft.ru/questions/fileapiservice-zagruzka-dokumenta-v-faily-i-primecania-crm-sistemy

 

I am able to establish connection (Authorization is successful) and getting SUCCESS for the attachment. But in the response, I am receiving 'Request Error'.

 

Questions:

1. Is my URL correct?

2. Is the way I specified file section name correct?

3. Do I need to add/delete/change my request body?

4. Do I need to create a MODULE in ADVANCED SETTINGS?

 

NOTE: I am using BPM'Online Studio.

Like 0

Like

1 comments

It's hard to say how it should be done on Node.js. However, there is an easy way to find if your request is correct. Please install "telerik fiddler" and catch the request that you send to bpm'online. For example, send file.jpg. Then open bpm'online and add the same file for example to a contact. Catch the request with fiddler too. Then compare those two requests. Your task is to create a functionality that will send exactly the same request. 

If you need an example on JS, please put a break point into the "upload" method in the ConfigurationFileApi module (in a browser) and add a file to a contact. You'll see how bpm'online generates the request. Please try to do the same on Node.js. 

Show all comments
Question

Hi All

I am trying to insert attachments through OData. Here is my query:

URL: https://.bpmonline.com/0/ServiceModel/EntityDataService.svc/UsrCollecti…

HEADER:

'Content-Type': 'application/atom+xml;type=entry'

Cookie:

BPMCSRF:

'Accept':'application/atom+xml;type=entry'

XML BODY:

<?xml version="1.0" encoding="utf-8"?>

        

            

                

                    test_file.csv

                    3bd0cdb7-89f5-458f-b713-ad54ece97b4d

                    529bc2f8-0ee0-df11-971b-001d60e938c6

                

            

        

NOTE: Name, UsrAWPLogisticsPlanId and TypeId are the fields in my file section.

 

The above query successfully uploads a blank CSV.  Now here are my questions:

1. How can I read a local file and pass it though the XML body (the way I am passing Name, TypeId and UsrAWPLogisticsPlanId)? - So that I can upload real data instead of a blank file

2. Where is the attachment data stored? Whats the format?

 

NOTE: We use BPM'Online studio.

Like 0

Like

1 comments

Dear Nikhil,

Unfortunately, there is no possibility to upload files via Odata protocol on current system version. Please feel free to use FileApiService for uploading a file. Please find an example of how to call the service in the “ConfigurationFileApi” module while adding the file on “Attachments and notes” detail.

Please note that all files are saved in the database in the appropriate table. For example, files from the “Attachments and notes” tab from the Contact section are saved in the “ContactFile” table and have the object name “Contact attachment”. Please note that the column with data of the file has name “Data” and type “varbinary(max)”.

For more detailed assistance, please contact technical support.

Best regards,

Norton

Show all comments