JOLT: Merge a field into nested object - jolt

I'm new to JOLT. I have this json object
{
"query_time": "2021-20-25 12:10:12.000",
"locations": [
{
"id": 1,
"places": {
"city": "Edmonton",
"address": "example address 1"
}
},
{
"id": 2,
"places": {
"city": "Winnipeg",
"address": "example address 2"
}
}
]
}
Now I want to transform it into this:
[
{
"id": 1,
"city": "Edmonton",
"address": "example address 1"
},
{
"id": 2,
"city": "Winnipeg",
"address": "example address 2"
}
]
Please help me define a JOLT spec to do this transformation.
Thank you.

You can collect the elements nested in the places key by using "*" wildcard while looking up the values of id elements by going one level up through use of #(1,id) within a shift transformation spec such as
[
{
"operation": "shift",
"spec": {
"locations": {
"*": {
"places": {
"#(1,id)": "[&2].id",
"*": "[&2].&"
}
}
}
}
}
]

Related

Jolt : Add key in sub object

Input
{
"id": 1,
"name": "Sample name",
"attributes": {
"age": 10
}
}
Output
{
"id": 1,
"attributes": {
"name": "Sample name",
"age": 10
}
}
I want to carry out this transformation. I tried with the below spec
[
{
"operation": "shift",
"spec": {
"*": "&",
"name": "attributes.&"
}
}
]
But this changes attributes field into an array. What should be the right spec used here?
The following spec would work
[
{
"operation": "shift",
"spec": {
"*": "&",
"name": "attributes.&",
"attributes": {
"*": "attributes.&"
}
}
}
]

In Netsuite REST, how do I assign an item location to an item line in a sales order?

I'm using Netsuite's Postman collection (which takes care of the Oauth1 stuff), and am POSTing to this endpoint:
{{proto}}://{{host}}/rest/platform/{{version}}/record/salesorder
... and the body is something like this:
{
"customForm": "999",
"entity": {
"id": "1111"
},
"department": {
"id": "2222"
},
"subsidiary": {
"id": "33"
},
"otherRefNum": "TEST-PO",
"location": {
"id": "444"
},
"item": {
"items": [
{
"item": { "id": "555555" },
"inventorylocation": { "id": "444" },
"price": { "id": "-1" },
"grossAmt": 999,
"quantity": 1
}
]
}
}
I'm trying to assign a location on the item level. The above request creates a sales order ok (without the line-level location assignment) if I remove the inventorylocation line, but with that in there, I get this error: Unknown reference or subrecord field inventorylocation in request body.
Netsuite's REST API documentation is here:
https://system.netsuite.com/help/helpcenter/en_US/APIs/REST_API_Browser/record/v1/2019.2/index.html#tag-salesorder
I have also tried substituting location and moving the fields around a bit, without success. (either the salesorder is created without a line-level location assignment, or I get an error similar to the above error.
Any ideas?
From the documentation you linked, it appears that the field id you need is inventorylocation rather than itemlocation.
salesorder-itemElement
...
giftCertRecipientName Recipient Name: string
id [Missing Label:id]: string
inventorydetail: salesorder-item-inventorydetail
inventorylocation: location
inventorysubsidiary: subsidiary
isClosed Closed: boolean
...
Based on the documentation for a salesOrder-itemElement, it looks like that key is correct.
Have you tried the "location": "{ID}" variation?
In LedgerSync it looks like the request for creating an invoice results in this body:
{
"entity": "309",
"location": "1",
"sublist": {
"items": [
{
"amount": 12345,
"description": "Test Line Item FLURYAOLJLFADYGR-1"
},
{
"amount": 12345,
"description": "Test Line Item FLURYAOLUFUTBYJD-2"
}
]
}
}
There also is a salesOrder-item-inventorydetail object that also contains a location. Perhaps you could use that one like so:
{
"customForm": "999",
"entity": {
"id": "1111"
},
"department": {
"id": "2222"
},
"subsidiary": {
"id": "33"
},
"otherRefNum": "TEST-PO",
"location": {
"id": "444"
},
"item": {
"items": [
{
"item": { "id": "555555" },
"inventorydetail": {
"location": "444"
},
"price": { "id": "-1" },
"grossAmt": 999,
"quantity": 1
}
]
}
}

Add array inside object with same key in jolt spec

I would like to move the recommendations array by row_id key inside the investors with the same row_id
Original Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA"
},
{
"row_id": 2,
"name": "BBBB"
}
],
"recommendations": [
{
"row_id": "1",
"title": "ABC"
},
{
"row_id": "2",
"title": "CDE"
}
]
}
I've tried a lot of specs at https://jolt-demo.appspot.com with no success
Specs tried...
[{
"operation": "shift",
"spec": {
"investors": {
"*": "investors[]"
},
"recommendations": {
"#": "recommendations[]"
}
}
}]
Desired Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA",
"recommendations":[{
"row_id": "1",
"title": "ABC"
}]
},
{
"row_id": 2,
"name": "BBBB",
"recommendations":[{
"row_id": "2",
"title": "CDE"
}]
}
]
}
This can be done in two stage shift
First shift groups everything based on row_id.
(I'd suggest running the first shift of its own to see what the output is)
Second shift uses that grouped output and formats results.
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"row_id": {
"*": {
"#2": "&.&4"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"investors": "investors.[#2]",
"recommendations": "investors.[#2].recommendations[]"
}
}
}
]

Combining two arrays and transformation using Jolt

I am having a tough time using Jolt mapping trying to transform the input to the necessary form
Input JSON
{
"data": [
{
"name": "Alcohol",
"collection_id": 123,
"properties": [
{
"name": "Tax",
"property_id": "00001"
},
{
"name": "Expenditure",
"property_id": "00002"
}
],
"attributes": [
{
"name": "alcohol_tax",
"attribute_id": "00011"
},
{
"name": "alcohol_expenditure",
"attribute_id": "00022"
}
]
}
]
}
Output JSON
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [{
"property_name": "Tax",
"property_id": "00001",
"attribute_id": "00011"
},
{
"property_name": "Expenditure",
"property_id": "00002",
"attribute_id": "00022"
}
]
}
]
I have tried a couple of ways to combine the arrays using a few rules but with little success.
One of the rules
[{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "&1.name",
"collection_id": "&1.collection_id",
"attributes": {
"*": {
"attribute_id": "&1.attribute_id[]"
}
},
"properties": {
"*": {
"name": "&1.myname[]",
"property_id": "&1.property_id[]"
}
}
}
}
}
}]
is adding all the attributes and properties to all the collections.I do not know why this happens as I thought &1.property_id[] would only add items in that particular collection to the array and not all collections. Any help/clues on why this is happening would be truly appreciated.
See solution below:
[0] creates the wrapping array
[&1] uses the position of the respective arrays so the results are combined in details the important part is wrapping square brackets so its treated as array rather than literal.
[
{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "[0].name",
"collection_id": "[0].collection_id",
"attributes": {
"*": {
"attribute_id": "[0].details.[&1].attribute_id"
}
},
"properties": {
"*": {
"name": "[0].details.[&1].name",
"property_id": "[0].details.[&1].property_id"
}
}
}
}
}
}
]
Produces the following:
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [
{
"attribute_id": "00011",
"name": "Tax",
"property_id": "00001"
},
{
"attribute_id": "00022",
"name": "Expenditure",
"property_id": "00002"
}
]
}
]

I have a simple json file that I'm trying to transform using jolt and having trouble with it since I'm very new to jolt

Here's what I want to do:
1. Concatenate first and last name with name
2. Change id to employeeID and add prefix with employee ID: emp_id
3. If department is equal to sales, than department should be "SL"
4. If department is equal to sales, than department should be "RET"
Here's my input:
{
"employees": [{
"f_name": "tom",`
"l_name": "smith",
"id": "100",
"department": "sales",
"company": "ABC Intelligence"
},
{
"f_name": "john",
"l_name": "doe",
"id": "102",
"department": "returns",
"company": "ABC Intelligence"
}, {
"f_name": "jane",
"l_name": "doe",
"id": "103",
"department": "sales",
"company": "ABC Intelligence"
}
]
}
specs:
[{
"operation": "shift",
"spec": {
"employees": {
"*": {
"name": "=concat(#(1,f_name),' ',#(1,l_name))"
}
}
}
},
{
"operation": "remove",
"spec": {
"employees": {
"*": {
"f_name": "",
"l_name": ""
}
}
}
}
]
desired output:
{
"employees": [
{
"name": "tom smith",
"employeeID": "emp_100",
"department": "SL",
"company": "ABC Intelligence"
},
{
"name": "john doe",
"employeeID": "emp_102",
"department": "RET",
"company": "ABC Intelligence"
},
{
"name": "jane doe",
"employeeID": "emp_103",
"department": "SL",
"company": "ABC Intelligence"
}
]
}
I was able to get the first rule but still struggling with the others. Any help would be appreciated
Spec
[
{
"operation": "modify-default-beta",
"spec": {
// add the mapping of department name to code, so we can use it later
"deptMap": {
"sales": "SL",
"returns": "RET"
},
"employees": {
"*": {
// build the fullName from the first and last names
"name": "=concat(#(1,f_name),' ',#(1,l_name))",
// build the employeeID
"employeeID": "=concat(emp_,#(1,id))"
}
}
}
},
{
"operation": "shift",
"spec": {
"employees": {
"*": { // employees arrays
// pass name, company, and employeeID thru
"name": "employees[&1].name",
"company": "employees[&1].company",
"employeeID": "employees[&1].employeeID",
// lookup the deparment code
"department": {
"*": { // value of dept
// got up 5 levels, come back down the deptMap
"#(4,deptMap.&)": "employees[&3].department"
}
}
}
}
}
}
]