如何使用 Dataweave 2.0 聚合这些数据?

How to aggregate this data using Dataweave 2.0?

取下面JSON。它是一个对象数组。

[
  {
    "objects": [
      {
        "saleItems": [
          {
            "itemID": 1,
            "saleItemType": "Sale",
            "productCode": "072",
            "legacyProductCode": "1071",
            "legacyCategoryCode": "1071",
            "categoryCode": "1071",
            "subCategoryCode": "101",
            "amount": 12,
            "originalAmount": 15,
            "netAmount": 10,
            "originalNetAmount": 12.5,
            "vat": 2.5,
            "unitVAT": 1,
            "vatRate": 20,
            "unitMeasure": "EA",
            "unitPrice": 15,
            "quantity": 1,
            "saleChannel": 0
          }
        ]
      }
    ]
  },
  {
    "objects": [
      {
        "saleItems": [
          {
            "itemID": 1,
            "saleItemType": "Sale",
            "productCode": "072",
            "legacyProductCode": "1071",
            "legacyCategoryCode": "1071",
            "categoryCode": "1071",
            "subCategoryCode": "101",
            "amount": 12,
            "originalAmount": 15,
            "netAmount": 10,
            "originalNetAmount": 12.5,
            "vat": 2.5,
            "unitVAT": 1,
            "vatRate": 20,
            "unitMeasure": "EA",
            "unitPrice": 15,
            "quantity": 1,
            "saleChannel": 0
          }
        ]
      }
    ]
  },
  {
    "objects": [
      {
        "saleItems": [
          {
            "itemID": 1,
            "saleItemType": "Sale",
            "productCode": "072",
            "legacyProductCode": "1071",
            "legacyCategoryCode": "1071",
            "categoryCode": "1071",
            "subCategoryCode": "101",
            "amount": 12,
            "originalAmount": 15,
            "netAmount": 10,
            "originalNetAmount": 12.5,
            "vat": 2.5,
            "unitVAT": 1,
            "vatRate": 20,
            "unitMeasure": "EA",
            "unitPrice": 15,
            "quantity": 1,
            "saleChannel": 0
          }
        ]
      }
    ]
  }
]

此数据的示例输出需要为:

{
  "sales": {
    "saleItems": [
      {
        "saleChannel": "1",
        "categoryCode": "1071",
        "productCode": "072",
        "salesAmountIncludingTax": 11.79,
        "salesAmountExcludingTax": 9.82,
        "discountAmountIncludingTax": 1.0,
        "discountAmountExcludingTax": 0.83,
        "salesQuantity": 10.0
      }
    ],
    "totalSalesAmountIncludingTax": 11.79,
    "totalSalesAmountExcludingTax": 9.82,
    "totalSalesQuantity": 10.0
  },
  "refunds": {
    "refundItems": [
      {
        "saleChannel": "1",
        "categoryCode": "1010",
        "productCode": "033",
        "refundAmountIncludingTax": 11.79,
        "refundAmountExcludingTax": 9.82,
        "discountAmountIncludingTax": 1.0,
        "discountAmountExcludingTax": 0.83,
        "refundQuantity": 10.0
      }
    ],
    "totalRefundAmountIncludingTax": 11.79,
    "totalRefundAmountExcludingTax": 9.82,
    "totalRefundQuantity": 10.0
  }
}

复杂性在于aggregation/totalling。例如:

在有效负载数组的每个元素中,必须存在基于值的值聚合。每个对象都包含 saleItems 对象数组。如果 saleChannel = 0 和 saleItemType = "Sale" 并且如果 productCode = "X"(以前没有见过)这意味着必须对每个 saleItem 的值进行“求和”,productCode = X.

示例:因此对于前 2 个对象,产品代码可能为“001”。这意味着必须合计这些值。第三个对象 productCode 可以是“002”,必须在输出的 saleItems 数组中创建一个新对象。

示例:(如果 saleItemType = "Refund",这对于退款也可能是相同的,其中 if 语句是基于的)

"sales": {
  "saleItems": [
    {
      productCode 001
      salesAmountIncludingTax: **The sum of "amount" field, if saleChannel = 0 && saleItemType = "Sale**
    },
    {
      productCode 002
    }
  ]
}

值的总和必须遵循以下逻辑:

if saleChannel = 0
    group by subCategoryCode
        salesAmountIncludingTax = sum(saleItems.amount where saleItemType="Sale")
        salesAmountExcludingTax = sum(saleItems.netAmount where saleItemType="Sale")
    
if saleChannel != 0
    group by productCode
        salesAmountIncludingTax = sum(saleItems.originalAmount where saleItemType="Sale")
        salesAmountExcludingTax = sum(saleItems.originalNetAmount where saleItemType="Sale")

如果我理解正确的话你需要做这样的事情:

%dw 2.0
output application/json

fun sumItems(itemsToSum, field1, field2) = do {
    var item = itemsToSum[0]
    var discounts = itemsToSum.priceAdjustments
    ---
    {
        "saleChannel": item.saleChannel,
        "categoryCode": item.categoryCode,
        "subCategoryCode": item.subCategoryCode,
        "productCode": item.productCode,
        "salesAmountIncludingTax": sum(itemsToSum[field1]),
        "salesAmountExcludingTax": sum(itemsToSum[field2]),
        "discountAmountIncludingTax": sum(discounts.amount default []),
        "discountAmountExcludingTax": sum(discounts.netAmount default []),
        "salesQuantity": sum(itemsToSum.quantity)
    }
}

var allItems       = flatten(payload..*saleItems default [])
var allSaleItems   = allItems filter ((item) -> item.saleItemType == "Sale")
var channel0       = allSaleItems filter ((item) -> item.saleChannel == 0)
var otherChannels  = allSaleItems filter ((item) -> item.saleChannel != 0)
var summedChannel0 = 
        channel0 
            groupBy ((item) -> item.subCategoryCode)
            pluck ((itemsToSum, groupName) -> do {
                sumItems(itemsToSum, "amount", "netAmount")
            })
var summedOtherChannels = 
        otherChannels 
            groupBy ((item) -> item.productCode)
            pluck ((itemsToSum, groupName) -> do {
                sumItems(itemsToSum, "originalAmount", "originalNetAmount")
            })
var saleItems = summedChannel0 ++ summedOtherChannels
---
{
    sales: {
        "saleItems": saleItems,
        "totalSalesAmountIncludingTax": sum(saleItems.salesAmountIncludingTax),
        "totalSalesAmountExcludingTax": sum(saleItems.salesAmountExcludingTax),
        "totalSalesQuantity": sum(saleItems.salesQuantity)
    }
}