How to increment a counter inside a reduce function using dataweave - mule

I am trying to do a JSON to JSON transformation using dataweave (for an EDI 811 mapping). My requirement is for every VEH segment (having Vehicle information) inside an HL loop, I want to start a counter from 1 to number of Vehicle records.
My input format is -
[
{
"IDENTIFIER": "ABC",
"HOST_ID": "XYZ",
"BusinessKey": "11111",
"HL0": {
"HL0_STATE_ID": "22",
"HL0_RPT_SYS_ID": "ABCD",
"HL0_CO_NAIC": "11111"
},
"HL1": {
"HL1_NAIC_COMP_CODE": "111111",
"HL1_CO_ADDRESS": "AAAA BBBB CCCCC",
"HL1_CO_CITY": "MABCD",
"HL1_CO_STATE": "AB",
"HL1_CO_ZIP_9": "12345"
},
"Details": [
{
"HL4": {
"HL4_POLICY_NUM": "8767886857",
"HL4_TRAN_CODE_ALPHA": "JGJ",
"HL4_CYCLE_DATE_CC": "19",
"HL4_CYCLE_DATE_YYMMDD": "200511",
"HL4_STATE_CODE": "VV",
"HL4_STATE_REPORTING_ID": "0000",
"HL4_PRODUCT_CODE": "DD",
"HL4_SUB_PRODUCT_CODE": "",
"HL4_SENDER_ID": "",
"HL4_POLICY_TYPE": "V",
"HL4_PROTEUS_TRANSACTION": "00000",
"HL4_TRAN_SUB_TYPE_CODE": "",
"HL4_TRAN_DATE_CC": "00",
"HL4_TRAN_DATE_YYMMDD": "000000",
"HL4_TRAN_TIME": "00000000",
"HL4_POL_EFF_DATE_CC": "00",
"HL4_POL_EFF_DATE_YYMMDD": "000000",
"HL4_POL_EXP_DATE_CC": "00",
"HL4_POL_EXP_DATE_YYMMDD": "000000",
"HL4_PERSON_ORG_INDIC": "1",
"HL4_LIAB_INDIC": "",
"HL4_AGENT_CODE": {
"HL4_AGENT_PREFIX": "",
"HL4_PRODUCER_AGENT": "00000"
},
"HL4_CANCEL_EFF_DATE": {
"HL4_CANCEL_EFF_DATE_CC": "00",
"HL4_XCL_EFF_DATE_YYMMDD": "000000"
},
"HL4_DRV_NAME": {
"HL4_DRV_LAST_NAME": "DDDDDD",
"HL4_DRV_FIRST_NAME_MI": "PPPPP"
},
"HL4_DRV_ADDRESS": "KHHKHK HJHKHKH GGGGGG RD S",
"HL4_DRV_CITY": "IOHKHL",
"HL4_DRV_STATE": "MB",
"HL4_DRV_ZIP": "68686",
"HL4_DRV_DLN": "875758865",
"HL4_DRV_DLN_STATE": "BJ",
"HL4_DRV_DOB_NUM": {
"HL4_DRV_DOB_YYMMDD": "20",
"HL4_DRV_DOB_CC": "200525"
},
"HL4_DRV_SEX": "",
"HL4_VEH_EFF_DATE_NUM": {
"HL4_VEH_EFF_DATE_CC": "00",
"HL4_VEH_EFF_DATE_YYMMDD": "000000"
},
"HL4_VEH_EXP_DATE_NUM": {
"HL4_VEH_EXP_DATE_CC": "20",
"HL4_VEH_EXP_DATE_YYMMDD": "220423"
}
},
"HL5": [
{
"HL5_VEH_VIN": "1BJHFJBKHJK6876868",
"HL5_VEH_MAKE": "CDRJV",
"HL5_VEH_CC": "19",
"HL5_VEH_YY": "99"
},
{
"HL5_VEH_VIN": "1BVNVJH68686JHG979",
"HL5_VEH_MAKE": "JHGJGJG",
"HL5_VEH_CC": "19",
"HL5_VEH_YY": "92"
}
]
},
{
"HL4": {
"HL4_POLICY_NUM": "6877578787",
"HL4_TRAN_CODE_ALPHA": "ABC",
"HL4_CYCLE_DATE_CC": "20",
"HL4_CYCLE_DATE_YYMMDD": "210805",
"HL4_STATE_CODE": "30",
"HL4_STATE_REPORTING_ID": "0000",
"HL4_PRODUCT_CODE": "CA",
"HL4_SUB_PRODUCT_CODE": "",
"HL4_SENDER_ID": "",
"HL4_POLICY_TYPE": "V",
"HL4_PROTEUS_TRANSACTION": "00000",
"HL4_TRAN_SUB_TYPE_CODE": "",
"HL4_TRAN_DATE_CC": "00",
"HL4_TRAN_DATE_YYMMDD": "000000",
"HL4_TRAN_TIME": "00000000",
"HL4_POL_EFF_DATE_CC": "00",
"HL4_POL_EFF_DATE_YYMMDD": "000000",
"HL4_POL_EXP_DATE_CC": "00",
"HL4_POL_EXP_DATE_YYMMDD": "000000",
"HL4_PERSON_ORG_INDIC": "2",
"HL4_LIAB_INDIC": "",
"HL4_AGENT_CODE": {
"HL4_AGENT_PREFIX": "",
"HL4_PRODUCER_AGENT": "00000"
},
"HL4_CANCEL_EFF_DATE": {
"HL4_CANCEL_EFF_DATE_CC": "00",
"HL4_XCL_EFF_DATE_YYMMDD": "000000"
},
"HL4_DRV_NAME": {
"HL4_DRV_LAST_NAME": "EE SSSSSS LLC",
"HL4_DRV_FIRST_NAME_MI": ""
},
"HL4_DRV_ADDRESS": "6869800 CCCCCC DR",
"HL4_DRV_CITY": "JFJJFJG",
"HL4_DRV_STATE": "GK",
"HL4_DRV_ZIP": "868875",
"HL4_DRV_DLN": "77797968123",
"HL4_DRV_DLN_STATE": "NM",
"HL4_DRV_DOB_NUM": {
"HL4_DRV_DOB_YYMMDD": "20",
"HL4_DRV_DOB_CC": "210907"
},
"HL4_DRV_SEX": "",
"HL4_VEH_EFF_DATE_NUM": {
"HL4_VEH_EFF_DATE_CC": "20",
"HL4_VEH_EFF_DATE_YYMMDD": "220410"
},
"HL4_VEH_EXP_DATE_NUM": {
"HL4_VEH_EXP_DATE_CC": "00",
"HL4_VEH_EXP_DATE_YYMMDD": "000000"
}
},
"HL5": [
{
"HL5_VEH_VIN": "1GJHHKHGJGJGJG878",
"HL5_VEH_MAKE": "JGKJGJH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "15"
},
{
"HL5_VEH_VIN": "1JHGJGGKG97968687",
"HL5_VEH_MAKE": "GJJG",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "22"
},
{
"HL5_VEH_VIN": "186876BJHGJGJ7868",
"HL5_VEH_MAKE": "GJGKHKH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "20"
}
]
}
]
}
]
My Output format JSON is as below, the VEH segments are all mapped from HL5 records in the above JSON input. in VEH01, I want to map the index/occurrence of HL5 record, so if there are 3 HL5 records with the HL4, we will get HL-VEH loop 3 times, and the VEH01 should increment from '1' for first occurrence, '2' for second occurrence and '3' for 3rd occurrence, For the next HL4-HL5 records, VEH01 should again start from "1"-
{
"TransactionSets": {
"v003050": {
"811": [
{
"Group": {
"GS04": "..."
},
"Heading": {
"020_BIG": {
"BIG01": "...",
"BIG02": ".."
},
....
....
"Detail": {
"010_HL_Loop": [
{
"010_HL": {
"HL01": "1",
"HL03": "1",
"HL04": "1"
},
...
...
{
"010_HL": {
"HL01": "8",
"HL02": "7",
"HL03": "5",
"HL04": "0"
},
"020_LX_Loop": [
{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1, ---> This should be 1
"VEH02": "1BJHFJBKHJK6876868",
"VEH03": ..,
"VEH04": ..,
"VEH05": "..",
"VEH06": "CDRJV"
}
}
]
},
{
"010_HL": {
"HL01": "9",
"HL02": "7",
"HL03": "5",
"HL04": "0"
},
"020_LX_Loop": [
{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1, ---> This should be 2
"VEH02": "1BVNVJH68686JHG979",
"VEH03": ..,
"VEH04": ..,
"VEH05": "..",
"VEH06": "JHGJGJG"
}
}
]
},
...
...
...
"010_HL": {
"HL01": "11",
"HL02": "10",
"HL03": "5",
"HL04": "0"
},
"020_LX_Loop": [
{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1, ---> This should be 1
"VEH02": "1GJHHKHGJGJGJG878",
"VEH03": ..,
"VEH04": ..,
"VEH05": "..",
"VEH06": "JGKJGJH"
}
}
]
},
{
"010_HL": {
"HL01": "12",
"HL02": "10",
"HL03": "5",
"HL04": "0"
},
"020_LX_Loop": [
{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1, ---> This should be 2
"VEH02": "1JHGJGGKG97968687",
"VEH03": ..,
"VEH04": ..,
"VEH05": "..",
"VEH06": "GJJG"
}
}
]
},
{
"010_HL": {
"HL01": "13",
"HL02": "10",
"HL03": "5",
"HL04": "0"
},
"020_LX_Loop": [
{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1, ---> This should be 3
"VEH02": "186876BJHGJGJ7868",
"VEH03": ..,
"VEH04": .,
"VEH05": "..",
"VEH06": "GJGKHKH"
}
}
]
}
]
My mapping in dataweave is as below -
%dw 2.0
import * from dw::core::Strings
output application/json
fun toHL1(rec, HL1Hierarchy) = {
"010_HL": {
HL01: (HL1Hierarchy + 1) as String,
HL03: "1",
HL04: "1"
},
"110_NM1_Loop": {
"110_NM1": {
NM101: "..",
NM102: "..",
NM103: "...",
NM108: "..",
NM109: rec.HL1.HL1_NAIC_COMP_CODE,
}
},
"210_IT1_Loop": [{
"210_IT1": {
IT102: 1,
IT103: "..",
IT104: 0
},
"270_DTM": [{
DTM01: "368",
DTM02: rec.Details.HL4.HL4_CYCLE_DATE_YYMMDD[0] as Date {
format: "yyMMdd"
} default "000000",
DTM05: rec.Details.HL4.HL4_CYCLE_DATE_CC[0] as Number
}]
}]
}
//////********************** */
fun toOrder(rec, shipHierarchy) = {
"010_HL": {
HL01: (shipHierarchy + 1) as String,
HL02: "1",
HL03: "2",
HL04: "1"
},
"110_NM1_Loop": {
"110_NM1": {
NM101: "..",
NM102: "..",
NM103: "..",
}
}
}
//////************************ */
fun toPack(ship, cases, ordHierarchy, indexOfPacks) = {
"010_HL": {
HL01: (indexOfPacks + 1) as String,
HL02: ordHierarchy as String,
HL03: "4",
HL04: "1",
},
"110_NM1_Loop": {
"110_NM1": {
NM101: "..",
NM102: cases.HL4.HL4_PERSON_ORG_INDIC,
NM103: cases.HL4.HL4_DRV_NAME.HL4_DRV_LAST_NAME,
NM104: cases.HL4.HL4_DRV_NAME.HL4_DRV_FIRST_NAME_MI,
NM108: "..",
NM109: cases.HL4.HL4_DRV_DLN
},
"130_N3": [{
N301: cases.HL4.HL4_DRV_ADDRESS
}],
"140_N4": {
N401: cases.HL4.HL4_DRV_CITY,
N402: cases.HL4.HL4_DRV_STATE,
N403: cases.HL4.HL4_DRV_ZIP
}
},
"210_IT1_Loop": [{
"210_IT1": {
IT102: 1,
IT103: "..",
IT104: 0
},
"220_SI": [{
SI01: "..",
SI02: "..",
SI03: cases.HL4.HL4_TRAN_CODE_ALPHA
}],
"260_REF": [{
REF01: "IG",
REF02: cases.HL4.HL4_POLICY_NUM[0 to 7],
},
{
REF01: "XM",
REF02: cases.HL4.HL4_DRV_DLN_STATE,
},
{
REF01: "S3",
REF02: "V",
},
{
REF01: "DD",
REF03: cases.HL4.HL4_POLICY_NUM[8 to 8] default " " ++ cases.HL4.HL4_CYCLE_DATE_CC as String ++ cases.HL4.HL4_CYCLE_DATE_YYMMDD as String,
}],
"270_DTM": [{
DTM01: "222",
DTM02: cases.HL4.HL4_DRV_DOB_NUM.HL4_DRV_DOB_CC as Date {
format: "yyMMdd"
} default "000000",
DTM05: cases.HL4.HL4_DRV_DOB_NUM.HL4_DRV_DOB_YYMMDD as Number
},
{
DTM01: if (cases.HL4.HL4_TRAN_CODE_ALPHA == "...") "036" else "007",
DTM02: if (cases.HL4.HL4_TRAN_CODE_ALPHA == "...") cases.HL4.HL4_VEH_EXP_DATE_NUM.HL4_VEH_EXP_DATE_YYMMDD as Date { format: "yyMMdd" } default "000000" else cases.HL4.HL4_VEH_EFF_DATE_NUM.HL4_VEH_EFF_DATE_YYMMDD as Date { format: "yyMMdd" } default "000000",
DTM05: if (cases.HL4.HL4_TRAN_CODE_ALPHA == "...") cases.HL4.HL4_VEH_EXP_DATE_NUM.HL4_VEH_EXP_DATE_CC as Number else cases.HL4.HL4_VEH_EFF_DATE_NUM.HL4_VEH_EFF_DATE_CC as Number
}]
}]
}
///////************************ */
fun toItem(ship, recItems, packHierarchy, indexOfItems) = {
"010_HL": {
// HL01: (4) as String,
HL01: (indexOfItems + 1) as String,
HL02: packHierarchy as String,
HL03: "5",
HL04: "0"
// HL04: cases
},
"020_LX_Loop": [{
"020_LX": {
"LX01": 1
},
"025_VEH": {
"VEH01": 1,
"VEH02": recItems.HL5_VEH_VIN,
"VEH03": recItems.HL5_VEH_CC as Number,
"VEH04": recItems.HL5_VEH_YY as Number {format: "0000"},
"VEH05": "NA",
"VEH06": recItems.HL5_VEH_MAKE
}
}]
}
---
{
//Delimiters: "*>U~",
TransactionSets: {
v003050: {
"811": [{
Group: {
GS04: now() as Date {
format: "yyMMdd"
},
},
Heading: {
"020_BIG": {
BIG01: now() as Date {
format: "yyMMdd"
},
BIG02: "1",
},
"100_N1_Loop": [{
"100_N1": {
N101: "..",
N102: "...",
N103: "..",
N104: "..."
},
},
{
"100_N1": {
N101: "..",
N102: "...",
}
}]
},
Detail: {
"010_HL_Loop": payload reduce (ship, accShip=[]) -> do {
var shipUpd = accShip << toHL1(ship, sizeOf(accShip))
var HL1Hierarchy = sizeOf(shipUpd)
var itemHierarchy = sizeOf(shipUpd)
var ord = payload reduce (ship, accOrd = shipUpd) -> do {
var ordUpd = accOrd << toOrder(ship, HL1Hierarchy)
var ordHierarchy = sizeOf(ordUpd)
var pack = flatten(payload.Details) reduce (cases, accPkg = ordUpd) -> do {
var packUpd = accPkg << toPack(ship, cases, ordHierarchy, sizeOf(accPkg))
var packHierarchy = sizeOf(packUpd)
var items = cases.HL5 reduce (recItems, accItems = packUpd) ->
accItems << toItem(ship, recItems, packHierarchy, sizeOf(accItems))
---
items
}
---
pack
}
---
ord
}
},
Summary: {
"010_TDS": {
TDS01: 1
},
"110_CTT": {
CTT01: sizeOf(flatten(payload.Details).HL5)
}
}
}]
}
}
}
Can someone please help with the increment and resetting of the counter for VEH01 for every H4-H5 loop.

If you are using reduce then the input is an array. You can use map() to add the index to each element of the array, then use as needed.
Since the transformation of the question is too complex to attempt to modify I'll make an educated guess to make a simple example:
%dw 2.0
output application/json
---
payload.HL5 map (($) ++ {index: $$ + 1})
Input:
{
"HL5": [
{
"HL5_VEH_VIN": "1GJHHKHGJGJGJG878",
"HL5_VEH_MAKE": "JGKJGJH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "15"
},
{
"HL5_VEH_VIN": "1JHGJGGKG97968687",
"HL5_VEH_MAKE": "GJJG",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "22"
},
{
"HL5_VEH_VIN": "186876BJHGJGJ7868",
"HL5_VEH_MAKE": "GJGKHKH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "20"
}
]
}
Output:
[
{
"HL5_VEH_VIN": "1GJHHKHGJGJGJG878",
"HL5_VEH_MAKE": "JGKJGJH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "15",
"index": 1
},
{
"HL5_VEH_VIN": "1JHGJGGKG97968687",
"HL5_VEH_MAKE": "GJJG",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "22",
"index": 2
},
{
"HL5_VEH_VIN": "186876BJHGJGJ7868",
"HL5_VEH_MAKE": "GJGKHKH",
"HL5_VEH_CC": "20",
"HL5_VEH_YY": "20",
"index": 3
}
]
You need to identify at which point you need to apply the transformation and use the added index attribute. Maybe in between this expression: var items = cases.HL5 /* here? */ reduce ...

Related

Parsing Dynamic response in Karate

I want to verify the value of "RequestedName" in the following response, where the keys for different drugs is dynamic:
{
"requestId": "c826bee1-610e-4dee-b998-1fe4f8c15a1b",
"requestSource": "",
"responseSource": "client",
"status": 200,
"responseCodes": [
{
"code": "S00001",
"message": "Success.",
"params": {
"entity": ""
}
}
],
"context": null,
"payload": {
"0113ccf86ba79b698b8e7a8fb9effc4b": {
"RequestedName": "paracetamol",
"SearchKey": "0113ccf86ba79b698b8e7a8fb9effc4b",
"Name": "Genexa Acetaminophen Extra Strength",
"PrescribableName": "",
"ProductCodes": [
"69676-0059"
],
"DosageForm": "Tablet, coated",
"Route": "Oral",
"Approved": false,
"UnApproved": false,
"Generic": false,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "500",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"0349fa4ea29da419c46745bc7e2a6c07": {
"RequestedName": "paracetamol",
"SearchKey": "0349fa4ea29da419c46745bc7e2a6c07",
"Name": "Pain Reliever",
"PrescribableName": "",
"ProductCodes": [
"70677-0168"
],
"DosageForm": "Tablet, extended release",
"Route": "Oral",
"Approved": true,
"UnApproved": false,
"Generic": true,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "650",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"060cfbde5d82d947c56aac304c136fd3": {
"RequestedName": "paracetamol",
"SearchKey": "060cfbde5d82d947c56aac304c136fd3",
"Name": "Betr Pain Relief",
"PrescribableName": "Acetaminophen 500 mg Oral Tablet",
"ProductCodes": [
"80267-0484"
],
"DosageForm": "Tablet",
"Route": "Oral",
"Approved": false,
"UnApproved": false,
"Generic": false,
"Allergen": false,
"Vaccine": false,
"Strength": {
"Number": "500",
"Unit": "mg/1"
},
"Purposes": {},
"SideEffects": {}
},
"0950fcbac262c1c1d3a9e6630615a5f9": {
"RequestedName": "paracetamol",
"SearchKey": "0950fcbac262c1c1d3a9e6630615a5f9",
"Name": "Acetaminophen",
I tired this:
* def list = []
* def fun = function(k, v){ karate.appendTo('list', { key: k, val: v } )}
* karate.forEach(response, fun)
* def keys = $list[?(#.val.payload.RequestedName==drugName)].key
but not working, getting error as below:
def keys = $list[?(#.val.payload.RequestedName==drugName)].key
Failed to parse filter: [?(#.val.payload.RequestedName==drugName)], error on position: 32, char: d
testsuite/GetDrugs.feature:20
Here is the approach you can use:
* def response =
"""
{
dynamicKey1: {
fixedKey: 'fixedValue1',
dataKey: 'dataValue2'
},
dynamicKey2: {
fixedKey: 'fixedValue2',
dataKey: 'dataValue2'
}
}
"""
* def keys = []
* def fun = function(k, v){ if (v.fixedKey == 'fixedValue2') keys.push(k) }
* karate.forEach(response, fun)
* match keys == ['dynamicKey2']

Unable to access data in Postgres query where clause

I am dealing with the following JSON in a Postgres database column called steps in a table called tCampaign :
[
{
"name":"Step 1",
"stepReference":"01e9f7c0-bc79-11eb-ab6f-2fa1cb676e38",
"rewardConditions": [
{
"conditionDefinitions": [
{
"instanceId":"01805260-0818-4e99-e5b1-5820d1b133cd",
"type":"registration",
"properties": null,
"name": "Registration"
},
{
"instanceId":"01e115c3-5e56-437a-5d13-6c04281e9588",
"type":"optIn",
"properties": null,
"name":"Opt In"
}
],
"rewardDefinitions":[
{
"instanceId":"01c82190-1d56-44f9-474a-513732302e28",
"type":"sportsReward",
"properties": {"activation": {"type": "onReward"}, "betFlavour": "SPORTS", "channels": ["__use_campaign_restrictions__"], "expiry": {"offset": {"days": "02", "hours": "00", "minutes": "00", "seconds": "00"}, "type": "relative"}, "inRunning": "-", "maxReward": {"USD": "1"}, "minimumOdds": "", "oddsInput": {"minimumOdds": {"american": "", "european": ""}}, "retail": "offBetBuild", "returnStakeOnPayout": "false"},
"name":"Freebet",
"calculator":{"type":"fixed","value":"100"}
}
]
}
]
},
{
"name" : "Step 2",
"stepReference" : "01daa4a0-bc79-11eb-ab6f-2fa1cb676e38",
"rewardConditions": [
{
"conditionDefinitions": [
{
"instanceId" : "01fb15ae-01d0-49e1-966a-8ff438e9a191",
"type" : "genericSportsBet",
"properties" : {"betFlavour": "SPORTS", "betTrackEventThreshold": "10", "betTypes": [ "SGL" ], "builderBetOption": "ALL", "channels": [ "__use_campaign_restrictions__" ], "currencyThresholdMap": { "USD": "1" }, "eventHierarchySelection": { "categories": [], "classes": [], "events": [], "marketTemplates": [], "markets": [ "5824" ], "retrobetEventIds": [ "1200" ], "selections": [], "selectionsMarket": [], "types": [] }, "eventHierarchySelectionUI": { "markets": [ { "id": 5824, "mapping": [], "name": "Match Result", "parentId": 1200, "parentParentId": 5, "path": [ "Category: |England|", "Class: |England Premier League|", "Type: |GK Team K| |vs| |GK Team L|" ], "selectionMapper": false, "settled": "N", "startTime": "2021-05-31 11:15:00", "status": "A" } ] }, "inRunning": "-", "legTypes": [ "WIN" ], "metOnSettlement": false, "minOdds": "", "oddsInput": { "minOdds": { "american": "", "european": "" } }, "priceTypes": [ "LP" ]},
"name" : "Sports Bet"
}
],
"rewardDefinitions":[
{
"instanceId" : "0110eb70-44f9-4d57-40bb-09ff4169136c",
"type" : "sportsReward",
"properties" : {"activation": {"type": "onReward"}, "betFlavour": "SPORTS", "channels": ["__use_campaign_restrictions__"], "expiry": {"offset": {"days": "02", "hours": "00", "minutes": "00", "seconds": "00"}, "type": "relative"}, "inRunning": "-", "maxReward": {"USD": "2"}, "minimumOdds": "", "oddsInput": {"minimumOdds": {"american": "", "european": ""}}, "retail": "offBetBuild", "returnStakeOnPayout": "false"},
"name" : "Freebet",
"calculator" : {"type":"fixed","value":"100"}
}
]
}
]
}
]
and have written the following query to extract properties from conditionDefinitions :
select conditionDefinitions->'properties' as properties from tcampaign cmp
LEFT JOIN LATERAL json_array_elements(steps) singleStep ON true
LEFT JOIN LATERAL json_array_elements(singleStep->'rewardConditions') rewardConditions on TRUE
LEFT JOIN LATERAL json_array_elements(rewardConditions->'conditionDefinitions') conditionDefinitions on TRUE
where properties is not null ;
but I get the following error :
ERROR: column "properties" does not exist
LINE 5: where properties is null ;
If I remove the where clause the query runs fine. Why do I not have access to properties in the where clause? Because I can see results coming back if I remove the WHERE clause, so the query does have results

Kotlin - Merge two data class

Data class
data class A(
var data: List<Data>
) {
data class Data(
var key: String,
var count: Long = 0,
var sub: List<Data>? = null
)
}
A class data values expressed in json.
[
{
"data": [
{
"key": "ALLOGENE THERAPEUTICS",
"count": 47,
"sub": [
{
"key": "N",
"count": 46,
"sub": [
{
"key": "S1",
"count": 1
},
{
"key": "S2",
"count": 13
}
]
},
{
"key": "B+",
"count": 1,
"sub": [
{
"key": "S1",
"count": 2
},
{
"key": "S2",
"count": 1
}
]
}
]
},
{
"key": "CELLECTIS",
"count": 5,
"sub": [
{
"key": "B+",
"count": 2,
"sub": [
{
"key": "S1",
"count": 3
},
{
"key": "S2",
"count": 5
}
]
},
{
"key": "B",
"count": 2,
"sub": [
{
"key": "S1",
"count": 6
},
{
"key": "S2",
"count": 1
}
]
},
{
"key": "N",
"count": 1,
"sub": [
{
"key": "S1",
"count": 8
},
{
"key": "S2",
"count": 4
}
]
}
]
},
{
"key": "PFIZER",
"count": 5,
"sub": [
{
"key": "N",
"count": 5,
"sub": [
{
"key": "S1",
"count": 83
},
{
"key": "S2",
"count": 1
}
]
}
]
}
]
}
]
I would like to combine elements with key values of "ALLOGENE THERAPEUTICS" and "CELECTIS" and replace the key value with "STUB".
When the elements are combined, all the "count" values must be combined.
And elements that are not there must be added.
Therefore, the results should be as follows.
[
{
"data": [
{
"key": "STUB",
"count": 52, // "ALLOGENE THERAPEUTICS"(47) + "CELECTIS"(5) = 52
"sub": [
{
"key": "N",
"count": 47, // 46 + 1
"sub": [
{
"key": "S1",
"count": 9
},
{
"key": "S2",
"count": 17
}
]
},
{
"key": "B+",
"count": 3,
"sub": [
{
"key": "S1",
"count": 5
},
{
"key": "S2",
"count": 6
}
]
},
{
"key": "B",
"count": 5,
"sub": [
{
"key": "S1",
"count": 11
},
{
"key": "S2",
"count": 7
}
]
}
]
},
{
"key": "PFIZER",
"count": 5,
"sub": [
{
"key": "N",
"count": 5,
"sub": [
{
"key": "S1",
"count": 83
},
{
"key": "S2",
"count": 1
}
]
}
]
}
]
}
]
How can I code the work neatly with Kotlin?
For reference, the values of the data class are expressed as json, and the result value must be data class.
This is the progress so far:
create a function for Data that creates a merged copy
data class Data(
var key: String,
var count: Long = 0,
var sub: List<Data> = emptyList()
) {
fun mergedWith(other: Data): Data {
return copy(
count = count + other.count,
sub = sub + other.sub
)
}
}
fold the consolidation list into a single data item and add them back together.
val consolidatedKeys = listOf("ALLOGENE THERAPEUTICS", "CELECTIS")
val (consolidatedValues, nonconsolidatedValues) = a.data.partition { it.key in consolidatedKeys }
val consolidatedData = when {
consolidatedValues.isEmpty() -> emptyList()
else -> listOf(consolidatedValues.fold(A.Data("STUB", 0), A.Data::mergedWith))
}
val result = A(consolidatedData + nonconsolidatedValues)
And combine the sub-elements.
consolidatedData.forEach { x ->
x.sub
.groupBy { group -> group.key }
.map { A.Data(it.key, it.value.sumOf { c -> c.count }) }
}
This is the current situation.
In this way, elements with depth of 2 will work normally, but elements with depth of 3 will not be added.
For example, up to "N" below STUB is combined, but "S1" and "S2" below "N" are not combined.
Therefore, the current result is output in this way.
[
{
"data": [
{
"key": "STUB",
"count": 52, <--------- WORK FINE
"sub": [
{
"key": "N",
"count": 47, <--------- WORK FINE
"sub": [] <--------- EMPTY !!
},
{
"key": "B+",
"count": 3, <--------- WORK FINE
"sub": [] <--------- EMPTY !!
},
{
"key": "B",
"count": 5, <--------- WORK FINE
"sub": [] <--------- EMPTY !!
}
]
},
{
"key": "PFIZER",
"count": 5,
"sub": [
{
"key": "N",
"count": 5,
"sub": [
{
"key": "S1",
"count": 83
},
{
"key": "S2",
"count": 1
}
]
}
]
}
]
}
]
How can all the sub-elements be combined and implemented?
First break down your problem. You can create a function for Data that creates a merged copy:
fun mergedWith(other: Data): Data {
return copy(
count = count + other.count,
sub = when {
sub == null && other.sub == null -> null
else -> sub.orEmpty() + other.sub.orEmpty()
}
)
}
I recommend if possible that you use a non-nullable List for your sub parameter, and use emptyList() when there's nothing in it. This makes it simpler since there aren't two different ways to represent a lack of items and you won't have to deal with nullability:
data class Data(
var key: String,
var count: Long = 0,
var sub: List<Data> = emptyList()
) {
fun mergedWith(other: Data): Data {
return copy(
count = count + other.count,
sub = sub + other.sub
)
}
}
Then you can split your list into ones that you want to consolidate vs. the rest. Then fold the consolidation list into a single data item and add them back together.
val consolidatedKeys = listOf("ALLOGENE THERAPEUTICS", "CELECTIS")
val (consolidatedValues, nonconsolidatedValues) = a.data.partition { it.key in consolidatedKeys }
val consolidatedData = when {
consolidatedValues.isEmpty() -> emptyList()
else -> listOf(consolidatedValues.fold(A.Data("STUB", 0), A.Data::mergedWith))
}
val result = A(consolidatedData + nonconsolidatedValues)

How to check a particular value on basis of condition in karate

Goal: Match the check value is correct for 123S and 123O response in API
First check the value on this location x.details[0].user.school.name[0].codeable.text if it is 123S then check if x.details[0].data.check value is abc
Then check if the value on this location x.details[1].user.school.name[0].codeable.text is 123O then check if x.details[1].data.check is xyz
The response in array inter changes it is not mandatory first element is 123S sometime API returns 123O as first array response.
Sample JSON.
{
"type": "1",
"array": 2,
"details": [
{
"path": "path",
"user": {
"school": {
"name": [
{
"value": "this is school",
"codeable": {
"details": [
{
"hello": "yty",
"condition": "check1"
}
],
"text": "123S"
}
}
]
},
"sample": "test1",
"id": "22222"
},
"data": {
"check": "abc"
}
},
{
"path": "path",
"user": {
"school": {
"name": [
{
"value": "this is school",
"codeable": {
"details": [
{
"hello": "def",
"condition": "check2"
}
],
"text": "123O"
}
}
]
},
"sample": "test",
"id": "11111"
},
"data": {
"check": "xyz"
}
}
]
}
How I did in Postman but how to replicate same in Karate?
var jsonData = pm.response.json();
pm.test("Body matches string", function () {
for(var i=0;i<jsonData.details.length;i++){
if(jsonData.details[i].user.school.name[0].codeable.text == '123S')
{
pm.expect(jsonData.details[i].data.check).to.equal('abc');
}
if(jsonData.details[i].user.school.name[0].codeable.text == '123O')
{
pm.expect(jsonData.details[i].data.check).to.equal('xyz');
}
}
});
2 lines. And this takes care of any number of combinations of lookup values :)
* def lookup = { '123S': 'abc', '123O': 'xyz' }
* match each response.details contains { data: { check: '#(lookup[_$.user.school.name[0].codeable.text])' } }

How can I define jsonPath for given json?

{
"name": "ninja",
"contry": "India",
"Account": [
{
"id": "123",
"orgId": 223,
"investment": [
{
"invetmentId": "111",
"name": "India tech",
"performance": [
{
"id": "123",
"performanceSet": [
{
"amount": "231",
"currency": "USD"
},
{
"amount": "250",
"currency": "IND"
}
]
}
]
}
]
}
]
}
So I have to select the amount where the currency is USD?
And I tried it as "$.Account..investment.performance..performanceSet.amount[?(#.currency=~/.*USD/)]"
This JsonPath should work:
$..performanceSet[?(#.currency == "USD")].amount
Tested on:
{
"name":"ninja",
"contry":"India",
"Account":[
{
"id":"123",
"orgId":223,
"investment":[
{
"invetmentId":"111",
"name":"India tech",
"performance":[
{
"id":"123",
"performanceSet":[
{
"amount":"231",
"currency":"USD"
},
{
"amount":"250",
"currency":"IND"
}
]
}
]
},
{
"invetmentId":"112",
"name":"India tech 2",
"performance":[
{
"id":"124",
"performanceSet":[
{
"amount":"235",
"currency":"USD"
},
{
"amount":"250",
"currency":"IND"
}
]
}
]
}
]
}
]
}
which returns:
[
"231",
"235"
]
A good way to try it out is this site: https://jsonpath.com/
Read the docs: https://github.com/intuit/karate#jsonpath-filters
* def temp = $..performanceSet[?(#.currency=='USD')]
* match temp[0].amount == '231'
You can try it this way
$.Account..investment.performance..performanceSet.amount[?(#.currency=~/.*USD/)]