jsonmuledataweavemulesoftmule-esb

Transform the payload by grouping the fields in mule 4 dataweave


The below JSON Response containing collection which needs to be iterate and group according to the field serviceType.

Response:

{
    data:[
    {
            "jobCardNumber": "JC20026333",
            "serviceType": "RUNNING REPAIR",
            "partAmt": 1659.98,
            "labourAmt": 727.48,
            "totalAmt": 2387.46,
            "estPartAmt": 0.0,
            "estLabourAmt": 0.0,
            "estTotalAmt": 0.0,
            "partBasic": 1356.12,
            "partDiscount": null,
            "labourBasic": 616.5,
            "variant": "MARUTI WAGON R LXI BS4",
            "color": "SUPERIOR WHITE"
            },
            {
            "jobCardNumber": "JC20026456",
            "serviceType": "BODY REPAIR",
            "partAmt": 1659.98,
            "labourAmt": 727.48,
            "totalAmt": 2387.46,
            "estPartAmt": 0.0,
            "estLabourAmt": 0.0,
            "estTotalAmt": 0.0,
            "partBasic": 1356.12,
            "partDiscount": null,
            "labourBasic": 616.5,
            "variant": "MARUTI WAGON R LXI BS4",
            "color": "SUPERIOR WHITE"
            },
            {
            "jobCardNumber": "JC20026456",
            "serviceType": "RUNNING REPAIR",
            "partAmt": 1659.98,
            "labourAmt": 727.48,
            "totalAmt": 2387.46,
            "estPartAmt": 0.0,
            "estLabourAmt": 0.0,
            "estTotalAmt": 0.0,
            "partBasic": 1356.12,
            "partDiscount": null,
            "labourBasic": 616.5,
            "variant": "MARUTI WAGON R LXI BS4",
            "color": "SUPERIOR WHITE"
            }
            ]
        }

Each collection having field serviceType, I need to group and transform the data according to the type, meaning that, if service type is same then we need to group the related fields and create another collection of it called history.

The below JSON depicts the scenario, for service type RUNNING REPAIR, another collection has been created which groups all the properties related to RUNNING REPAIR

{
  "service_records": [
    {
      "service_type": "RUNNING REPAIR",
       totalAmt:2800"
      "history": [
        {
          "service_date": "08-07-22 23:17",
          "mileage": "23465",
          "jc_number": "JC22212345",
          "labour_amount": "600",
          "part_amount": "800",
          "total_amount": "1400",
        
        },
        {
          "service_date": "08-07-22 23:17",
          "mileage": "23465",
          "jc_number": "JC22212398",
          "labour_amount": "600",
          "part_amount": "800",
          "total_amount": "1400",
        
        }
        
      ]
    },
    {
      "service_type": "BODY REPAIR",
      "total_amount": "1400",
      "history": [
        {
          "service_date": "08-07-22 23:17",
          "mileage": "23465",
          "jc_number": "JC22212345",
          "labour_amount": "600",
          "part_amount": "800",
          "total_amount": "1400",
        }
      ],
       "WORKSHOP":{ //exclude body repair all other services will be count in workshop
         totalSumOfAllServices: 4774 //(running repair)
        }
    }
]
 
}

I did some workaround in dataweave playground but unable to group the fields according to the serviceType

%dw 2.0
output application/json
---
service_records: payload.data map (item, index) -> {
      service_type: item.serviceType,
      labour_amount: item.labourAmt,
      part_amount: item.partAmt,
      total_amount: item.totalAmt,
      is_expanded: false,
history:payload.data map(item,v)->{
          "service_date": "08-07-22 23:17",
          "service_type": item.serviceType,
          "model": item.model,
          "mileage": item.mileage,
          "jc_number": item.jobCardNumber,
          "labour_amount": item.labourAmt,
          "part_amount": item.partAmt,
          "total_amount": item.totalAmt
} 
}

https://developer.mulesoft.com/learn/dataweave/playground?projectMethod=GHRepo&repo=mulesoft%2Fdocs-dataweave&path=modules%2FROOT%2Fpages%2F_partials%2Fcookbook-dw%2Fmap-ex1


Solution

  • The groupBy function is what you need. You can use it to group by the serviceType of the input and it will give you output which will look something like this:

    {
      "RUNNING REPAIR": [
        {"jobCardNumber": "JC20026333", .....},
        {"jobCardNumber": "JC20026456", .....},
      ],
      "BODY REPAIR": [
        {"jobCardNumber": "JC20026456",....}
      ]
    }
    

    The above is the result of payload.data groupBy $.serviceType Which you can pluck and map to desired output

    %dw 2.0
    output application/json  
    ---
    {
      service_records: payload.data groupBy $.serviceType 
          pluck ((groupedValues, serviceType, index) -> {
                service_type: serviceType,
                model: groupedValues[0].variant, // mabe?
                totalAmt: sum(groupedValues.totalAmt),
                history: groupedValues map {
                      service_date: "", // not sure from where it is coming from it is not in the input that you shared
                      mileage: "", // not sure from where it is coming from it is not in the input that you shared
                      jc_number: $.jobCardNumber,
                      labour_amount: $.labourAmt,
                      part_amount: $.partAmt,
                      total_amount: $.totalAmt
                }
          })
    }