0

The possible values for applicableOn field are already known but they are not limited to clothes and bags like given in this sample input. Also, there can be multiple elements in purchases array with the same applicableOn type and the sum of all those values should be calculated together.

Input:

{
  "primary": {
    "domainAttributes": {
      "email": "[email protected]",
      "name": "rach",
      "age": "28"
    },
    "meta": {
      "isEntity": true
    },
    "type": "somevalue",
    "purchases": [
      {
        "domainAttributes": {
          "email": "[email protected]",
          "id": "1",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "[email protected]",
              "name": "rach",
              "id": "1",
              "value": "5",
              "applicableOn": "CLOTHES"
            },
            "meta": null,
            "type": "some other value"
          }
        ]
      },
      {
        "domainAttributes": {
          "email": "[email protected]",
          "taxRateEntityId": "2",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "[email protected]",
              "name": "rach",
              "id": "2",
              "value": "7",
              "applicableOn": "BAGS"
            },
            "type": "some other value"
          }
        ]
      }
    ]
  }
}

Expected output:

{
  "email" : "[email protected]",
  "name" : "rach",
  "age" : "28",
  "purchaseSum" : [{"sum":"5", "applicableOn": "CLOTHES"}, {"sum": "7", "applicableOn": "BAGS"}],
  "purchase" : [ {
    "value" : "5",
    "id" : "1",
    "applicableOn" : "CLOTHES"
  }, {
    "value" : "7",
    "id" : "2",
    "applicableOn" : "BAGS"
  } ]
}

I have this spec currently but it calculates the sum of all values in purchaseValues without checking applicableType and also the format of purchase is slightly different than expected:

  [
    {
      "operation": "shift",
      "spec": {
        "primary": {
          "domainAttributes": {
            "email": "email",
            "name": "name",
            "age": "age"
          },
          "purchases": {
            "*": {
              "purchaseValue": {
                "*": {
                  "domainAttributes": {
                    "value": "purchases[].value",
                    "id": "purchases[].id",
                    "applicableOn": "purchases[].applicableOn"
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "operation": "shift",
      "spec": {
        "email": "email",
        "name": "name",
        "age": "age",
        "purchases": {
          "*": {
            "value": "purchaseSum[]",
            "@": "purchase[]"
          }
        }
      }
    },
    {
      "operation": "modify-overwrite-beta",
      "spec": {
        "purchaseSum": "=intSum(@(1,purchaseSum))"
      }
    },
    {
      "operation": "shift",
      "spec": {
        "email": "email",
        "name": "name",
        "age": "age",
        "purchaseSum": "purchaseSum",
        "purchase": "purchase"
      }
    }
  ]

The current output I'm seeing with the above spec is:

{
  "email" : "[email protected]",
  "name" : "rach",
  "age" : "28",
  "purchaseSum" : 12,
  "purchase" : [ {
    "value" : "5"
  }, {
    "id" : "1"
  }, {
    "applicableOn" : "CLOTHES"
  }, {
    "value" : "7"
  }, {
    "id" : "2"
  }, {
    "applicableOn" : "BAGS"
  } ]
}

Input with single purchase:

{
  "primary": {
    "domainAttributes": {
      "email": "[email protected]",
      "name": "rach",
      "age": "28"
    },
    "meta": {
      "isEntity": true
    },
    "type": "somevalue",
    "purchases": [
      {
        "domainAttributes": {
          "email": "[email protected]",
          "id": "1",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "[email protected]",
              "name": "rach",
              "id": "1",
              "value": "5",
              "applicableOn": "CLOTHES"
            },
            "meta": null,
            "type": "some other value"
          }
        ]
      }
    ]
  }
}
0

2 Answers 2

1

Also since this looks more like querying the data than re structuring it, you can keep it short and sweet using JSLT:

import "http://jslt.schibsted.com/2018/experimental" as exp

    //1- construct the primary info
    let primary = .primary.domainAttributes | {*:. }
    
    //2- construct the purchase list info
    let purchases = .primary.purchases | { "purchase": flatten([ for (.) [for (.purchaseValue) 
                                                    {
                                                      "id":.domainAttributes.id,
                                                      "value": .domainAttributes.value,
                                                      "applicableOn": .domainAttributes.applicableOn
                                                    }
                                                   ]
                                          ])}
    
    //3- group by applicableOn using group by function
    let groupByApplicableOn = exp:group-by($purchases.purchase, .applicableOn, number(.value))
    
    
    //4- merge all sets together in one json object
    $purchases + {"purchaseSum":[for($groupByApplicableOn ) {"Sum":sum(.values),"applicableOn":.key} ] }  + $primary 
0

The below spec should be dynamic enough to allow any type of applicableOn and any number of items per purchases.

[
  {
    "operation": "shift",
    "spec": {
      "primary": {
        "domainAttributes": {
          "*": "&"
        },
        "purchases": {
          "*": {
            "purchaseValue": {
              "*": {
                "domainAttributes": {
                  "value": "Totals.@(1,applicableOn)[]",
                  "@": "purchase[]"
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "Totals": {
        "*": "=intSum"
      }
    }
  },

  {
    "operation": "shift",
    "spec": {
      "*": "&",
      "purchase": {
        "*": {
          "id|value|applicableOn": "&2[&1].&"
        }
      },
      "Totals": {
        "*": {
          "@": "purchaseSum[#2].sum",
          "$": "purchaseSum[#2].applicableOn"
        }
      }
    }
  }
]
4
  • Looks like this works only if there are a minimum of two purchases. what seem to be missing?
    – Rachana
    Commented Jul 11 at 20:39
  • this should work on any number as long as the schema doesnt change . Can you provide the input where its not working Commented Jul 11 at 20:53
  • Edited my question to include the input with single purchase. See how this spec doesnt return purchase in the output.
    – Rachana
    Commented Jul 11 at 20:59
  • yeah I think the first transformation I need to bucket the value of the index into the purchase array as "@":"purchase[]" and not "@":"purchase". The change is applied in my post above and should fix the problem. Commented Jul 11 at 21:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.