Hi Team,

We want to retrieve a specific record by Id along with all the related elements (eg - Retrieve Account A with all of its related Contacts). 

What we already know:

We can retrieve the account record itself along with related records that are linked with lookupfields, like the PrimaryContact

 

Account(0001111-1111-1111-1111-111111231123)?$expand=PrimaryContact($select=Name)

This works, but it returns only one contact, the primary one.

 

Instead, we need an embedded list of contacts, like

{
    "@odata.context": myurl.creatio.com/0/odata/$metadata#Account(PrimaryContact(Name))/$entity,
    "Id": "22222-222222-2222-222222-22222207ba6",
    "Name": "somename",
    "OwnerId": "111111-11111-11111-11111-1111111",
    "CreatedOn": "2022-11-16T21:11:57.214167Z",
    "Contacts“ : [
{object}, {object}
]
}

Given the first URL in the response, we expected that all NavigationProperties would behave the same:

But this collection:

Is not accessible. If we call for :

Account(0002204c-d255-46c0-bea6-0f32e2e07ba6)?$expand=ContactCollectionByAccount

 

We get this error in return:

{
    "error": {
        "code": "",
        "message": "An error has occurred."
    }
}

If we use other expand values, we retrieve meaningful errors like „Could not find a property named xy“, but this error is not self explaining. How can we return an object with an embedded list of children? I know that in this example we also could ask for a list of Contacts filtered by their account, but we cannot do that in all scenarios we have in mind.

Thank you

Petrika

Like 3

Like

1 comments

Hello Petrika,

 

This property cannot be used to retrieve all contacts related to the account and can be used in filtration only. To retrieve related contacts you need to perform the GET query to the Contact object with the correspondent AccountId filter. Using this approach you will be able to get contacts needed.

Show all comments

Hi Team,



We are using an OOTB Webservice section to call the (GET) REST API endpoint and the response collection is captured in the "Response Parameter" of that web service. The response has a nested collection of data.

 

We are currently using the Script task to read the response data of a web service. Now it is required to get into the nested data set further and any insight on this would be helpful.



STEP 1: Web service Response

 

STEP 2: Script task to read web service response

var deliveries = Get<ICompositeObjectList<ICompositeObject>>("WebService1.Output_Out");
foreach(var delivery in deliveries){
//Delivery is again a nested data
//need to loop through the delivery (has parent record info and array of child record details)
}
 

Webservice Output:

{
   "output":[
      {
         "challan":[
            {
               "delivery_number":"DEL-251-253423",
               "delivery_id":1151109,
               "lines":[
                  {
                     "order_number":2011010049349,
                     "item_code":"RT3060-002GRL",
                     "grade":"A"
                  },
                  {
                     "order_number":2011010049359,
                     "item_code":"RT3062-002GRL",
                     "grade":"A"
                  }
               ]
            },
            {
               "delivery_number":"DEL-251-253430",
               "delivery_id":1151109,
               "lines":[
                  {
                     "order_number":2011010049369,
                     "item_code":"RT3060-002GRL",
                     "grade":"B"
                  },
                  {
                     "order_number":2011010049379,
                     "item_code":"RT3062-002GRL",
                     "grade":"B"
                  }
               ]
            }
         ]
      }
   ]
}



Need to traverse through the nested collection and one of the properties in the collection of values is array too {like section record information & Child record information} and then insert them into CRM table (Parent and child). Insight for processing this data set would be helpful.

 

 

 

Best Regards,

Bhoobalan Palanivelu.

Like 0

Like

3 comments
Best reply

Hello,

In order to process the collection inside a collection, you need to do the following:

1) In the process, create a new parameter and add values to it from the web server response:

 

 

2) In your script task, you need to proceed this parameter and get values from it.

Dmytro Vovchenko,



Thanks for the information shared.

We were able to achieve processing the multiple nested collection through the below script and insert the Parent/Child collection sequentially.

 

List&lt;object&gt; deliveryItem = new List&lt;object&gt;();
List&lt;object&gt; lineItem = new List&lt;object&gt;();
var serviceOut = Get&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("Output");
 
foreach(ICompositeObject chall in serviceOut){
	if(chall.TryGetValue&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("Challan" , out ICompositeObjectList&lt;ICompositeObject&gt; curChallan)){
		foreach(ICompositeObject _challan1 in curChallan){
				curChallan1.TryGetValue&lt;string&gt;("Driver_contact_no" , out string Driver_contact_no); 
				deliveryItem.Add(Driver_contact_no);
 
				if(_challan1.TryGetValue&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("Lines" , out ICompositeObjectList&lt;ICompositeObject&gt; curLines)){
					foreach(ICompositeObject _Lines1 in curLines){
							_Lines1.TryGetValue&lt;decimal&gt;("Secondary_quantity_ctn" , out decimal Secondary_quantity_ctn); 
							lineItem.Add(Secondary_quantity_ctn);
				}	
			}
		}
	}
}

 

Also, we can utilize this without performing the Step 1 of Creating Nested Parameter Collection in Parameters of Business Process. Since the Web-Service already has the response parameter of same. But the parameter name from Webservice is always with a suffix _OUT





Iteration of Composite object collection is done through by following the Type<> in below Interface

ICompositeObjectList<TObject>

Interface ICompositeObject


 

 

 



BR,

Bhoobalan Palanivelu.

Show all comments

Hi Community!!!

I used built in web service configuration to configure an integration with third party app.

The JSON that third party app receives looks like this:

{

  "url": "https://test",

  "events": ["a","b"]

}



The configuration for the events parameter into web service is as shown in the image below:

My issue is when I try to call this Web Service/Method from a Business Process. I cannot send the correct values for the events parameter. I tried several options for example: read a lookup values, create list or collection in a script task, etc. but I couldn't achive the goal.

The image below shows how the parameter is requested on the business process:

 

Below I show the trace with an example of the values I try to pass to the paramter:



"Parameter": "Events",

            "Value": {

                "Before execution": [

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

 

Any recomendation?

Regards.

 

 

 

 

Like 0

Like

3 comments

Hello,

You can send  your values using a collection.

The values of collection parameters of a [ Call web service ] process element can be mapped to the nested parameters of another collection of a [ Read data ] or [ Call web service ] process element .Additionally, each item of the collection can be mapped to an individual subprocess instance in the [ Subprocess ] element.



 

You can find more detailed information on the academy website:

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

Cherednichenko Nikita,

Thank you! I tried it but the result is something like this:

 

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

                ],

The expected value is 

[invitee.created","invitee.canceled"]

 

How can I achive this?

Regards.

Hello,

The code

[

                    {

                        "Name": "invitee.created"

                    },

                    {

                        "Name": "invitee.canceled"

                    }

],

Is seen like : [{"Name": "invitee.created"}, {"Name": "invitee.canceled"}].

But, in your case, I believe you can use the parameter value "Collection of values"

 

Show all comments

Hi everyone, 

I am setting up a Business process in order to create new records in a custom section. The data is stored in a List returned by a method. 

How can I loop through the collection and create new entities based on the values I need?

Like 2

Like

1 comments

Problem solved by moving the code block inside of a function called in the method that loops through the collection. 

Show all comments

Hi,

Let's say that I use a script task to get a request from a third party application and that request sends creatio a json with arrays.

 

What I need to do is to insert that data into some tables.

 

Can I pass the array to a collection parameter and then use it in my business process or do I need to insert the data via sql in the script task?

 

Thanks,

Raz

Like 0

Like

1 comments

Hi Raz, 

 

In fact, an array will work almost the same as a collection, so it doesn't make any sense to pass array into collection, but in this case you need to read this json data and then pass it through the collection for your further actions.

 

Please check out some practical examples of how to read and update data in script task: 

 



https://community.creatio.com/questions/use-script-task-update-column-r…

 

https://community.creatio.com/questions/use-collection-parameter-script…

 

https://community.creatio.com/articles/solved-code-how-send-http-post-r…

 

 

Regards, 

 

Bogdan L.

 

 

Show all comments

Hi,

 

Does the ODATA Web services mechanism supports collections?

meaning, using a post request with a json that includes arrays?

 

Thanks,

Raz

Like 0

Like

4 comments
Best reply

Hi Raz, 

 

Unfortunately we don't have practical examples of such implementation.

 

{

 "id": 1234,

"status": "ABC",

"Line_Items": [ {"prod_id":1111,"quantity":10},{"prod_id":2222,"quantity":20}],

"Order_Lines": [],

"Coupon_LInes": []

}

 

Most likely this code will not work, because Line_Items, Order_Lines and etc. will be perceived by the system like "field". 

 

You may create one order, in response you will get it's "Id" and then with using batch you may add  couple records in your details.

 

Best Regards, 

 

Bogdan L.

Hi Raz,

 

For this kind of requests OData has Butch. 

 

Please follow the link to check the details of how to work with it: 

 

https://academy.creatio.com/docs/developer/integrations_and_api/data_se…

 

Best Regards, 

 

Bogdan L.

Bogdan Lesyk,

Hi Bogdan,

 

Thank you for your response and article.

I didn't understand how the batch requests solves my scenaro.

I'll elaborate:

 

I have a woocommerce website that needs to update creatio every time there is a new order.

 

The woocommerce json looks like this:

{

 "id": 1234,

"status": "ABC",

"Line_Items": [ {"prod_id":1111,"quantity":10},{"prod_id":2222,"quantity":20}],

"Order_Lines": [],

"Coupon_LInes": []

}

 

As you can see one Json includes all the order data.

 

In Creatio for each array, like Line_Items, Order_Lines and etc, we have a detail connected to the order section.

 

Is there a way to use the ODATA Web services mechanism in such a way that the woocommerce website can update all the relevant sections and details?

 

Thanks,

Raz

 

Hi Raz, 

 

Unfortunately we don't have practical examples of such implementation.

 

{

 "id": 1234,

"status": "ABC",

"Line_Items": [ {"prod_id":1111,"quantity":10},{"prod_id":2222,"quantity":20}],

"Order_Lines": [],

"Coupon_LInes": []

}

 

Most likely this code will not work, because Line_Items, Order_Lines and etc. will be perceived by the system like "field". 

 

You may create one order, in response you will get it's "Id" and then with using batch you may add  couple records in your details.

 

Best Regards, 

 

Bogdan L.

Bogdan Lesyk,

Thank you for your response

Show all comments

Hi Community,

 

I have this situation where I need to excute some process through client side. While executing this process I want to pass a collection of ids to one of the process parameters. These ids are the Quotes that I multi-selected in the image bellow.

Pressing the  "Merge Quote" button will execute the following code.

This code will create a new collection with all the ids selected before and send them to my process. The next image shows the collection created.

I want to know which type of data should I use for my parameter in my process for this type of collection, where can I learn more about these types of collections and its methods and how can I access its values with the various process tasks?

 

For tests purposes I want to display one of the ids using a "Open Popup Window". 

 

Thanks in Advance.

 

Best Regards,

Pedro Pinheiro.

Like 1

Like

1 comments

Hello Pedro,

 

Creatio works with collections if it's needed to process such data but not to display it. You can pass items to sub_process or web_service elements or perform some script_task over it. Please refer to https://academy.creatio.com/docs/user/bpm_tools/business_process_setup/process_collections where this process is described.

 

In case if you want to work with the result of your script that returns a collection as described in your example,  you need to write it in a text string with ";" separator for Id's and then - split it on the next step to parse Id's and reflect them where you want.

 

Best regards,

Bogdan

Show all comments

Hi,

For a few weeks I struggled with sending a HTTP POST Request to a third party application via script task.

I have a collection object that needs to be sent via the web service and eventually catch the response and use the data inside process parameters.

 

Here you can find the code for doing that using a JSON object.

 

string x_param = Get("x_process_param");

string y_param = Get("y_process_param");

string z_param = Get("z_process_param");



var ProductLines = Get>("ReadDataUserTask6.ResultCompositeObjectList");

var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://url/api/v1/Documents/?token="+x_param);

httpWebRequest.ContentType = "application/json";

httpWebRequest.Method = "POST";

int ProductLineIndex = 0;

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))

using (JsonTextWriter writer = new JsonTextWriter(streamWriter))

{

    JObject InvoiceJSon = new JObject (

                            new JProperty("y",y_param),

                            new JProperty("z",z_param));

                            

    JArray JProductLinesArray = new JArray();

    foreach(var ProductLine in ProductLines) {

        

        var ProductName = "";

        decimal Qty;

        decimal UnitPrice;

        

        ProductLine.TryGetValue("Name", out ProductName);

        ProductLine.TryGetValue("Quantity", out Qty);

        ProductLine.TryGetValue("Price", out UnitPrice);

        

        JProductLinesArray.Add(new JObject(

            new JProperty("ChargeVAT","true"),

            new JProperty("Number",++ProductLineIndex),

            new JProperty("ProductName",ProductName),

            new JProperty("Qty",Qty),

            new JProperty("Rate",1),

            new JProperty("UnitPrice",UnitPrice),

            new JProperty("VATRate",17)));

    }                        

    

    InvoiceJSon.Add(new JProperty("DocumentLines",JProductLinesArray));

    

    InvoiceJSon.WriteTo(writer);

    

}



var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();

using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))

{

    var result = streamReader.ReadToEnd();

    var LinkToPdf = JObject.Parse(result)["LinkToPdf"].ToString();

    var CaspitDocNum = JObject.Parse(result)["Number"].ToString();

    

    Set("DocLinkToPdf",LinkToPdf);

    Set("FinanceDocId",DocNum);

}

return true;

 

Furthermore, I attached a screenshot with the methods that I'm using in the process

 

Hope it helps.

 

Have fun :)

Good luck

 

Like 1

Like

Share

2 comments

Hi!

 

Thank you for contacting us! 

 

Could you please provide us with additional screenshots of the issue appeared to understand the case better?

 

Regards, 

Anastasiia

Anastasiia Markina,

Hi Anastasiia,



There is no issue. I struggled with this issue and I solved it.



The above code is my collaboration to the community :)

 

Hope it helps devs with the same issue.

 

Best Regards,

Raz

Show all comments

Hi,

I'm using Orders and Order Items section with a 1:N relationship. On the Order Item I maintain a re-order date for that specific item. When the Current Date equals the Re-Order Date I want to send emails to customers for all the records where this condition applies.

The email should contain Order Item details but also information from the Parent Order, the associated Account and the Contact associated with the Order.

Below is the workflow as I have it so far. I'm unsure how to read the associated data from the Orders, Account and Contacts related to the initial collection of records of Order Items and then how to use all of it to send one email per Order to the Primary Email of the Account and Cc to the contact on the Order. The email body should include the Product Name from Order Item, Order Number and Date. 

Thanks for your help.

 

 

 

 

 

  

 

 

Like 0

Like

2 comments

Unfortunately, it's not possible to send an email to a collection of users in a business process. The functionality is planned by the bpm'online development team.

Ad for now, please try to check the marketing campaigns and trigger mass mailings functionality. It might help.

https://academy.bpmonline.com/documents/marketing/7-15/campaigns-section#HT_section_campaigns

https://academy.bpmonline.com/documents/marketing/7-15/email-section#HT_section_email

One option I just made use of is Tags.  You can read an object, with or without a tag, then either send the email or tag the object and send the email, then delete the tag and cycle around, or just cycle around.

Let's say you have not tagged anything yet:

1. Read the first item from an object where a tag does not exist, and it meets your other filter criteria.  The Tag needs to exist as an option, so you would need to manually create the tag, or tag a record once (so the tag exists) and untag it.

2. XOR condition that the ID from step 1 is !=Guid.Empty.  Default flow is to end or go somewhere else.

3. Tag that record (insert a section record tag, for example Contact Section Record Tag).  This will denote that the object has the tag and will not be read again in step 1.

4. Send the email.

(You could probably switch steps 3 and 4 as desired)

5. Cycle back around to step 1 and read the next item where the tag does not exist.

OR you can do the opposite, where in step 1 you are searching for records that are already tagged, then you later delete the tag before cycling back around to search again.

Hope this helps!

Chris

 

Show all comments