Search code examples
jsonjolt

What is jolt conversion spec for the given input and output


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": "rach@gmail.com",
      "name": "rach",
      "age": "28"
    },
    "meta": {
      "isEntity": true
    },
    "type": "somevalue",
    "purchases": [
      {
        "domainAttributes": {
          "email": "rach@gmail.com",
          "id": "1",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "rach@gmail.com",
              "name": "rach",
              "id": "1",
              "value": "5",
              "applicableOn": "CLOTHES"
            },
            "meta": null,
            "type": "some other value"
          }
        ]
      },
      {
        "domainAttributes": {
          "email": "rach@gmail.com",
          "taxRateEntityId": "2",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "rach@gmail.com",
              "name": "rach",
              "id": "2",
              "value": "7",
              "applicableOn": "BAGS"
            },
            "type": "some other value"
          }
        ]
      }
    ]
  }
}

Expected output:

{
  "email" : "rach@gmail.com",
  "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" : "rach@gmail.com",
  "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": "rach@gmail.com",
      "name": "rach",
      "age": "28"
    },
    "meta": {
      "isEntity": true
    },
    "type": "somevalue",
    "purchases": [
      {
        "domainAttributes": {
          "email": "rach@gmail.com",
          "id": "1",
          "age": "28"
        },
        "type": "somevalue",
        "purchaseValue": [
          {
            "domainAttributes": {
              "email": "rach@gmail.com",
              "name": "rach",
              "id": "1",
              "value": "5",
              "applicableOn": "CLOTHES"
            },
            "meta": null,
            "type": "some other value"
          }
        ]
      }
    ]
  }
}

Solution

  • 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"
            }
          }
        }
      }
    ]