1

I am trying to summarize a JSON,I have tried several example from Stack Overflow How to get max of in array of objects How to make a foreach of an object in javascript? but none of the tries have been successful.

   Sale: [
  {
     saleID: "2",
     timeStamp: "2021-01-08T17:50:28+00:00",
     discountPercent: "0",
     completed: "true",
     archived: "false",
     voided: "false",
     enablePromotions: "true",
     isTaxInclusive: "true",
     createTime: "2021-01-08T17:49:53+00:00",
     updateTime: "2021-01-08T17:50:29+00:00",
     completeTime: "2021-01-08T17:50:28+00:00",
     referenceNumber: "",
     referenceNumberSource: "",
     tax1Rate: "0.2",
     tax2Rate: "0",
     change: "0",
     receiptPreference: "printed",
     displayableSubtotal: "500",
     ticketNumber: "220000000002",
     calcDiscount: "0",
     calcTotal: "500",
     calcSubtotal: "416.67",
     calcTaxable: "416.67",
     calcNonTaxable: "0",
     calcAvgCost: "0",
     calcFIFOCost: "0",
     calcTax1: "83.33",
     calcTax2: "0",
     calcPayments: "500",
     total: "500",
     totalDue: "500",
     displayableTotal: "500",
     balance: "0",
     customerID: "0",
     discountID: "0",
     employeeID: "1",
     quoteID: "0",
     registerID: "1",
     shipToID: "0",
     shopID: "1",
     taxCategoryID: "1",
     taxTotal: "83.33"
  },
  {
     saleID: "3",
     timeStamp: "2021-01-08T17:53:18+00:00",
     discountPercent: "0",
     completed: "false",
     archived: "false",
     voided: "false",
     enablePromotions: "true",
     isTaxInclusive: "true",
     createTime: "2021-01-08T17:53:18+00:00",
     updateTime: "2021-01-08T17:53:18+00:00",
     referenceNumber: "",
     referenceNumberSource: "",
     tax1Rate: "0.2",
     tax2Rate: "0",
     change: "0",
     receiptPreference: "printed",
     displayableSubtotal: "0",
     ticketNumber: "220000000003",
     calcDiscount: "0",
     calcTotal: "0",
     calcSubtotal: "0",
     calcTaxable: "0",
     calcNonTaxable: "0",
     calcAvgCost: "0",
     calcFIFOCost: "0",
     calcTax1: "0",
     calcTax2: "0",
     calcPayments: "0",
     total: "0",
     totalDue: "0",
     displayableTotal: "0",
     balance: "0",
     customerID: "0",
     discountID: "0",
     employeeID: "1",
     quoteID: "0",
     registerID: "1",
     shipToID: "0",
     shopID: "1",
     taxCategoryID: "1",
     taxTotal: "0"
  },
  {
     saleID: "5",
     timeStamp: "2021-01-08T17:54:43+00:00",
     discountPercent: "0",
     completed: "false",
     archived: "false",
     voided: "false",
     enablePromotions: "true",
     isTaxInclusive: "true",
     createTime: "2021-01-08T17:54:43+00:00",
     updateTime: "2021-01-08T17:54:43+00:00",
     referenceNumber: "",
     referenceNumberSource: "",
     tax1Rate: "0.2",
     tax2Rate: "0",
     change: "0",
     receiptPreference: "printed",
     displayableSubtotal: "0",
     ticketNumber: "220000000005",
     calcDiscount: "0",
     calcTotal: "0",
     calcSubtotal: "0",
     calcTaxable: "0",
     calcNonTaxable: "0",
     calcAvgCost: "0",
     calcFIFOCost: "0",
     calcTax1: "0",
     calcTax2: "0",
     calcPayments: "0",
     total: "0",
     totalDue: "0",
     displayableTotal: "0",
     balance: "0",
     customerID: "0",
     discountID: "0",
     employeeID: "1",
     quoteID: "0",
     registerID: "1",
     shipToID: "0",
     shopID: "1",
     taxCategoryID: "1",
     taxTotal: "0"
  },
  {
     saleID: "6",
     timeStamp: "2021-01-24T18:49:27+00:00",
     discountPercent: "0",
     completed: "true",
     archived: "false",
     voided: "false",
     enablePromotions: "true",
     isTaxInclusive: "true",
     createTime: "2021-01-24T18:48:30+00:00",
     updateTime: "2021-01-24T18:49:28+00:00",
     completeTime: "2021-01-24T18:49:27+00:00",
     referenceNumber: "",
     referenceNumberSource: "",
     tax1Rate: "0.2",
     tax2Rate: "0",
     change: "0",
     receiptPreference: "printed",
     displayableSubtotal: "316.69",
     ticketNumber: "220000000006",
     calcDiscount: "0",
     calcTotal: "316.69",
     calcSubtotal: "263.91",
     calcTaxable: "263.91",
     calcNonTaxable: "0",
     calcAvgCost: "0",
     calcFIFOCost: "0",
     calcTax1: "52.78",
     calcTax2: "0",
     calcPayments: "316.69",
     total: "316.69",
     totalDue: "316.69",
     displayableTotal: "316.69",
     balance: "0",
     customerID: "0",
     discountID: "0",
     employeeID: "1",
     quoteID: "0",
     registerID: "1",
     shipToID: "0",
     shopID: "1",
     taxCategoryID: "1",
     taxTotal: "52.78"
  }]

I have tried several ways, the latest one:

      const debitSummary = sales.reduce((acc, inv, i) => {
   // console.log("inside reduce");
    if (i) {
      //  if (parseFloat(inv.calcTotal>0)){ // invoice
      acc = {
        //...acc,
        ticketNumber: acc.ticketNumber + ',' + inv.ticketNumber,
        registerID: inv.registerID > acc.registerID ? inv.registerID : acc.registerID,
        calcTotal: parseFloat(acc.calcTotal) + parseFloat(inv.calcTotal),
        timeStamp: formatDate(inv.timeStamp) > formatDate(acc.timeStamp) ? formatDate(inv.timeStamp) : formatDate(acc.timeStamp),
      }
      // }
    }
    return acc;
  },sales[0] );

But impossible to achieve the goal:

  • sum of calcTotal,
  • sum of total,
  • array of saleID,
  • array of ticketNumber,
  • with a break by registerID and day of timeStamp:
[{
    calcTotal: "500",
    registerID: "1",
    saleID: {
      "2",
      "3",
      "5"
    },
    ticketNumber: {
      "220000000002",
      "220000000003",
      "220000000005"
    },
    timeStamp: "2021-01-08",
    total: "500"
  },
  {
    calcTotal: "316.69",
    registerID: "1",
    saleID: "6",
    ticketNumber: {
      "220000000006"
    },
    timeStamp: "2021-01-24",
    total: "316.69"
  }
]
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Montana
  • 13
  • 2
  • Welcome to SO! You can make your question more answerable by removing some of the irrelevant fields and simplifying the data. It's not obvious to me what you're grouping on to create this final array. Is it both register id and timestamp? If so, can you show the expected output when there are multiple register ids? What aspect of the timestamp is relevant to forming a different bucket in the grouping logic? Week? Day? Thanks. – ggorlen Jan 24 '21 at 21:00
  • Your desired output is invalid; `saleID` and `ticketNumber` must be arrays (indicated using square brackets `[ ... ]`), not objects (indicated using curly brackets `{ ... }`). – Heretic Monkey Jan 24 '21 at 21:06
  • @HereticMonkey, you are right, I was not clear, both solutions are fine. – Montana Jan 25 '21 at 08:06

2 Answers2

1

You could take an object with date part of the timestamp as key and get the values from the object as result.

const
    sale = [{ saleID: "2", timeStamp: "2021-01-08T17:50:28+00:00", discountPercent: "0", completed: "true", archived: "false", voided: "false", enablePromotions: "true", isTaxInclusive: "true", createTime: "2021-01-08T17:49:53+00:00", updateTime: "2021-01-08T17:50:29+00:00", completeTime: "2021-01-08T17:50:28+00:00", referenceNumber: "", referenceNumberSource: "", tax1Rate: "0.2", tax2Rate: "0", change: "0", receiptPreference: "printed", displayableSubtotal: "500", ticketNumber: "220000000002", calcDiscount: "0", calcTotal: "500", calcSubtotal: "416.67", calcTaxable: "416.67", calcNonTaxable: "0", calcAvgCost: "0", calcFIFOCost: "0", calcTax1: "83.33", calcTax2: "0", calcPayments: "500", total: "500", totalDue: "500", displayableTotal: "500", balance: "0", customerID: "0", discountID: "0", employeeID: "1", quoteID: "0", registerID: "1", shipToID: "0", shopID: "1", taxCategoryID: "1", taxTotal: "83.33" }, { saleID: "3", timeStamp: "2021-01-08T17:53:18+00:00", discountPercent: "0", completed: "false", archived: "false", voided: "false", enablePromotions: "true", isTaxInclusive: "true", createTime: "2021-01-08T17:53:18+00:00", updateTime: "2021-01-08T17:53:18+00:00", referenceNumber: "", referenceNumberSource: "", tax1Rate: "0.2", tax2Rate: "0", change: "0", receiptPreference: "printed", displayableSubtotal: "0", ticketNumber: "220000000003", calcDiscount: "0", calcTotal: "0", calcSubtotal: "0", calcTaxable: "0", calcNonTaxable: "0", calcAvgCost: "0", calcFIFOCost: "0", calcTax1: "0", calcTax2: "0", calcPayments: "0", total: "0", totalDue: "0", displayableTotal: "0", balance: "0", customerID: "0", discountID: "0", employeeID: "1", quoteID: "0", registerID: "1", shipToID: "0", shopID: "1", taxCategoryID: "1", taxTotal: "0" }, { saleID: "5", timeStamp: "2021-01-08T17:54:43+00:00", discountPercent: "0", completed: "false", archived: "false", voided: "false", enablePromotions: "true", isTaxInclusive: "true", createTime: "2021-01-08T17:54:43+00:00", updateTime: "2021-01-08T17:54:43+00:00", referenceNumber: "", referenceNumberSource: "", tax1Rate: "0.2", tax2Rate: "0", change: "0", receiptPreference: "printed", displayableSubtotal: "0", ticketNumber: "220000000005", calcDiscount: "0", calcTotal: "0", calcSubtotal: "0", calcTaxable: "0", calcNonTaxable: "0", calcAvgCost: "0", calcFIFOCost: "0", calcTax1: "0", calcTax2: "0", calcPayments: "0", total: "0", totalDue: "0", displayableTotal: "0", balance: "0", customerID: "0", discountID: "0", employeeID: "1", quoteID: "0", registerID: "1", shipToID: "0", shopID: "1", taxCategoryID: "1", taxTotal: "0" }, { saleID: "6", timeStamp: "2021-01-24T18:49:27+00:00", discountPercent: "0", completed: "true", archived: "false", voided: "false", enablePromotions: "true", isTaxInclusive: "true", createTime: "2021-01-24T18:48:30+00:00", updateTime: "2021-01-24T18:49:28+00:00", completeTime: "2021-01-24T18:49:27+00:00", referenceNumber: "", referenceNumberSource: "", tax1Rate: "0.2", tax2Rate: "0", change: "0", receiptPreference: "printed", displayableSubtotal: "316.69", ticketNumber: "220000000006", calcDiscount: "0", calcTotal: "316.69", calcSubtotal: "263.91", calcTaxable: "263.91", calcNonTaxable: "0", calcAvgCost: "0", calcFIFOCost: "0", calcTax1: "52.78", calcTax2: "0", calcPayments: "316.69", total: "316.69", totalDue: "316.69", displayableTotal: "316.69", balance: "0", customerID: "0", discountID: "0", employeeID: "1", quoteID: "0", registerID: "1", shipToID: "0", shopID: "1", taxCategoryID: "1", taxTotal: "52.78" }],
    result = Object.values(sale.reduce((r, o) => {
        const timeStamp = o.timeStamp.slice(0, 10);
        r[timeStamp] ??= { timeStamp, registerID: o.registerID, ticketNumber: [], saleID: [], calcTotal: 0, total: 0 };
        ['calcTotal', 'total'].forEach(k => r[timeStamp][k] += +o[k]);
        ['saleID', 'ticketNumber'].forEach(k => r[timeStamp][k].push(o[k]));
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • @NinaSholtz, it works, thanks, can you explain the following code: r[timeStamp] ??= { timeStamp, registerID: o.registerID, ticketNumber: [], saleID: [], calcTotal: 0, total: 0 }; specifically ** ??= ** – Montana Jan 25 '21 at 08:11
  • it is the (new) [logical nullish assignment `??=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment) operator. – Nina Scholz Jan 25 '21 at 08:16
  • Thank you, I have adapted it to work in my environment: `acc[timeStamp] = acc[timeStamp] ? acc[timeStamp]:{ timeStamp, registerID: curr.registerID, ticketNumber: [], saleID: [], calcTotal: 0, total: 0 };` – Montana Jan 25 '21 at 08:47
  • you could shrink it to `acc[timeStamp] = acc[timeStamp] || { timeStamp, registerID: curr.registerID, ticketNumber: [], saleID: [], calcTotal: 0, total: 0 };` – Nina Scholz Jan 25 '21 at 08:48
0
j = [
    {
       saleID: "2",
       timeStamp: "2021-01-08T17:50:28+00:00",
       discountPercent: "0",
       completed: "true",
       archived: "false",
       voided: "false",
       enablePromotions: "true",
       isTaxInclusive: "true",
       createTime: "2021-01-08T17:49:53+00:00",
       updateTime: "2021-01-08T17:50:29+00:00",
       completeTime: "2021-01-08T17:50:28+00:00",
       referenceNumber: "",
       referenceNumberSource: "",
       tax1Rate: "0.2",
       tax2Rate: "0",
       change: "0",
       receiptPreference: "printed",
       displayableSubtotal: "500",
       ticketNumber: "220000000002",
       calcDiscount: "0",
       calcTotal: "500",
       calcSubtotal: "416.67",
       calcTaxable: "416.67",
       calcNonTaxable: "0",
       calcAvgCost: "0",
       calcFIFOCost: "0",
       calcTax1: "83.33",
       calcTax2: "0",
       calcPayments: "500",
       total: "500",
       totalDue: "500",
       displayableTotal: "500",
       balance: "0",
       customerID: "0",
       discountID: "0",
       employeeID: "1",
       quoteID: "0",
       registerID: "1",
       shipToID: "0",
       shopID: "1",
       taxCategoryID: "1",
       taxTotal: "83.33"
    },
    {
       saleID: "3",
       timeStamp: "2021-01-08T17:53:18+00:00",
       discountPercent: "0",
       completed: "false",
       archived: "false",
       voided: "false",
       enablePromotions: "true",
       isTaxInclusive: "true",
       createTime: "2021-01-08T17:53:18+00:00",
       updateTime: "2021-01-08T17:53:18+00:00",
       referenceNumber: "",
       referenceNumberSource: "",
       tax1Rate: "0.2",
       tax2Rate: "0",
       change: "0",
       receiptPreference: "printed",
       displayableSubtotal: "0",
       ticketNumber: "220000000003",
       calcDiscount: "0",
       calcTotal: "0",
       calcSubtotal: "0",
       calcTaxable: "0",
       calcNonTaxable: "0",
       calcAvgCost: "0",
       calcFIFOCost: "0",
       calcTax1: "0",
       calcTax2: "0",
       calcPayments: "0",
       total: "0",
       totalDue: "0",
       displayableTotal: "0",
       balance: "0",
       customerID: "0",
       discountID: "0",
       employeeID: "1",
       quoteID: "0",
       registerID: "1",
       shipToID: "0",
       shopID: "1",
       taxCategoryID: "1",
       taxTotal: "0"
    },
    {
       saleID: "5",
       timeStamp: "2021-01-08T17:54:43+00:00",
       discountPercent: "0",
       completed: "false",
       archived: "false",
       voided: "false",
       enablePromotions: "true",
       isTaxInclusive: "true",
       createTime: "2021-01-08T17:54:43+00:00",
       updateTime: "2021-01-08T17:54:43+00:00",
       referenceNumber: "",
       referenceNumberSource: "",
       tax1Rate: "0.2",
       tax2Rate: "0",
       change: "0",
       receiptPreference: "printed",
       displayableSubtotal: "0",
       ticketNumber: "220000000005",
       calcDiscount: "0",
       calcTotal: "0",
       calcSubtotal: "0",
       calcTaxable: "0",
       calcNonTaxable: "0",
       calcAvgCost: "0",
       calcFIFOCost: "0",
       calcTax1: "0",
       calcTax2: "0",
       calcPayments: "0",
       total: "0",
       totalDue: "0",
       displayableTotal: "0",
       balance: "0",
       customerID: "0",
       discountID: "0",
       employeeID: "1",
       quoteID: "0",
       registerID: "1",
       shipToID: "0",
       shopID: "1",
       taxCategoryID: "1",
       taxTotal: "0"
    },
    {
       saleID: "6",
       timeStamp: "2021-01-24T18:49:27+00:00",
       discountPercent: "0",
       completed: "true",
       archived: "false",
       voided: "false",
       enablePromotions: "true",
       isTaxInclusive: "true",
       createTime: "2021-01-24T18:48:30+00:00",
       updateTime: "2021-01-24T18:49:28+00:00",
       completeTime: "2021-01-24T18:49:27+00:00",
       referenceNumber: "",
       referenceNumberSource: "",
       tax1Rate: "0.2",
       tax2Rate: "0",
       change: "0",
       receiptPreference: "printed",
       displayableSubtotal: "316.69",
       ticketNumber: "220000000006",
       calcDiscount: "0",
       calcTotal: "316.69",
       calcSubtotal: "263.91",
       calcTaxable: "263.91",
       calcNonTaxable: "0",
       calcAvgCost: "0",
       calcFIFOCost: "0",
       calcTax1: "52.78",
       calcTax2: "0",
       calcPayments: "316.69",
       total: "316.69",
       totalDue: "316.69",
       displayableTotal: "316.69",
       balance: "0",
       customerID: "0",
       discountID: "0",
       employeeID: "1",
       quoteID: "0",
       registerID: "1",
       shipToID: "0",
       shopID: "1",
       taxCategoryID: "1",
       taxTotal: "52.78"
    }];
    result = j.reduce((r, { registerID,timeStamp, ...object }) => {
        var temp = r.find(o => o.registerID === registerID && (new Date(o.timeStamp)).toLocaleDateString() === (new Date(timeStamp)).toLocaleDateString());
        if (!temp) r.push(temp = { calcTotal: "0", registerID,timeStamp: (new Date(timeStamp)).toLocaleDateString(), saleID: [], ticketNumber: [], total: "0" });
        temp.saleID.push(object.saleID);
        temp.ticketNumber.push(object.ticketNumber);
        temp.calcTotal = (parseInt(temp.calcTotal) + parseInt(object.calcTotal)).toString();
        temp.total = (parseInt(temp.total) + parseInt(object.total)).toString();

        return r;
    }, []);
    
console.log(result);
Mohammad Mirsafaei
  • 954
  • 1
  • 5
  • 16
  • this doesn't group by date and registerId. – Montana Jan 25 '21 at 08:05
  • but this is output I get : `[{"calcTotal":"500","registerID":"1","timeStamp":"1/8/2021","saleID":["2","3","5"],"ticketNumber":["220000000002","220000000003","220000000005"],"total":"500"},{"calcTotal":"316","registerID":"1","timeStamp":"1/24/2021","saleID":["6"],"ticketNumber":["220000000006"],"total":"316"}]` – Mohammad Mirsafaei Jan 25 '21 at 08:19
  • this is what I got: `[{ calcTotal: "500", registerID: "1", saleID: ["2"], ticketNumber: ["220000000002"], timeStamp: "08/01/2021", total: "500" }, { calcTotal: "0", registerID: "1", saleID: ["3"], ticketNumber: ["220000000003"], timeStamp: "08/01/2021", total: "0" }, { calcTotal: "0", registerID: "1", saleID: ["5"], ticketNumber: ["220000000005"], timeStamp: "08/01/2021", total: "0" }, { calcTotal: "316", registerID: "1", saleID: ["6"], ticketNumber: ["220000000006"], timeStamp: "24/01/2021", total: "316" }]` – Montana Jan 25 '21 at 08:48