0

I have below array of object:

const lineItems = [
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 5,
    "shippedQty": 10,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "1",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 40,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 4,
    "shippedQty": 20,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 5,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "3",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 10,
    "quantityUOM": "Unit",
    "receivedQty": 10,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  }
];

Expecting the output:

[
  {
    "lineNumber": "0",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 50,
    "quantityUOM": "Unit",
    "batchNumber": "LO123678",
    "receivedQty": 9,
    "shippedQty": 30,
    "itemCode": "Packagetest1"
  },
  {
    "lineNumber": "2",
    "item": "1496",
    "itemDesc": "wertyuiasdfghj",
    "qualityReceiptHold": "N",
    "quantity": 20,
    "quantityUOM": "Unit",
    "receivedQty": 15,
    "shippedQty": 60,
    "itemCode": "Packagetest1"
  }
]

the sum of properties like quantity, receivedQty and shippedQty based on grouping of batchNumber and item value. In first two grouped by batchNumber and item but last two line items grouped by item value only.

groupedVariantLineItems() {
    let result = [];
    
    for( let i = 0; i < this.variantLineItems.length; i++ ) {
      let isExists = false;
      for( let j=0; j<result.length; j++ ) {
        if( typeof this.variantLineItems[i].batchNumber != "undefined" && result[j].batchNumber == this.variantLineItems[i].batchNumber && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        } else if( typeof this.variantLineItems[i].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].item ) {
          isExists = true;
          result[j].quantity+= (this.variantLineItems[i].quantity!= undefined) ? Number(this.variantLineItems[i].quantity) : 0;
          result[j].shippedQty += (this.variantLineItems[i].shippedQty != undefined) ? Number(this.variantLineItems[i].shippedQty) : 0;
          result[j].receivedQty += (this.variantLineItems[i].receivedQty != undefined) ? Number(this.variantLineItems[i].receivedQty) : 0;

          result[j].quantity= ( isNaN(result[j].quantity) ) ? 0 : result[j].quantity;
          result[j].shippedQty = ( isNaN(result[j].shippedQty) ) ? 0 : result[j].shippedQty;
          result[j].receivedQty = ( isNaN(result[j].receivedQty) ) ? 0 : result[j].receivedQty;
          break;
        }
      }

      if( !isExists ) {
        result.push( this.variantLineItems[i] );
      }
    }

    return result;
  }

the above code given the correct output for first two line items which have batchNumber, but not correct for last two.

2
  • Is it enough to check if batchNumber property exists and group by it, and if not, then group by item property? Commented Feb 9, 2021 at 9:30
  • No, I did that and created a new object, but again it didn't worked. Thanks @Nermin for acknowledged Commented Feb 9, 2021 at 9:32

3 Answers 3

2

Doesn't this work for you?

const lineItems = [{
  "lineNumber": "0",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 5,
  "shippedQty": 10,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "1",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 40,
  "quantityUOM": "Unit",
  "batchNumber": "LO123678",
  "receivedQty": 4,
  "shippedQty": 20,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "2",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 5,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
},
{
  "lineNumber": "3",
  "item": "1496",
  "itemDesc": "wertyuiasdfghj",
  "qualityReceiptHold": "N",
  "quantity": 10,
  "quantityUOM": "Unit",
  "receivedQty": 10,
  "shippedQty": 30,
  "itemCode": "Packagetest1"
}
]

const sumMap = new Map()

for (entry of lineItems) {
  if (entry.batchNumber) {
    const batchAcc = sumMap.get(entry.batchNumber)

    if (batchAcc) {
      batchAcc.quantity += entry.quantity
      batchAcc.shippedQty += entry.shippedQty
      batchAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.batchNumber, entry)
    }
  } else {
    const itemAcc = sumMap.get(entry.item)

    if (itemAcc) {
      itemAcc.quantity += entry.quantity
      itemAcc.shippedQty += entry.shippedQty
      itemAcc.receivedQty += entry.receivedQty
    } else {
      sumMap.set(entry.item, entry)
    }
  }
}

const arr = Array.from(sumMap, ([, value]) => value)

console.log(arr)

I'll make a cleaner version in my next edit.

Simpler version:

const properties = ['quantity', 'shippedQty', 'receivedQty']
const sumMap = new Map()

lineItems.forEach(entry => {
  const groupBy = entry.batchNumber ? entry.batchNumber : entry.item
  const acc = sumMap.get(groupBy)

  if (acc) {
    properties.forEach(property => acc[property] += entry[property])
  } else {
    sumMap.set(groupBy, entry)
  }
})

const arr = [...sumMap].map(([, value]) => value)

console.log(arr)
Sign up to request clarification or add additional context in comments.

Comments

0
var stats = {quantity: 0};
lineItems.filter((line) => typeof line.batchNumber !== 'undefined').forEach((line) => stats.quantity += line.quantity);
console.log(stats); // {quantity: 50}

2 Comments

expecting output JSON array
you can retrieve whatever you want under forEach iterator, the filter iterator plays the role of where condition where you can add your conditions (undefined, .. etc)
0

The else if condition should be as below:

} else if( typeof this.variantLineItems[i].batchNumber == "undefined" && typeof result[j].batchNumber == "undefined" && result[j].item == this.variantLineItems[i].item ) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.