0

I am trying to summarize a JSON

var data = [
  {
    customerName: "Customer1",
    customerId: "1234",
    invoices: [
      {
        id: "647549",
        transactionId: "INV01",
        date: "10/12/2020",
        debit: 371.93,
        dueDate: "09/02/2021"
      }
    ],
    creditmemo: []
  },
  {
    customerName: "Customer5",
    customerId: "5678",
    invoices: [
      {
        id: "631109",
        transactionId: "INV05",
        date: "09/12/2020",
        debit: 206.92,
        dueDate: "08/02/2021"
      },
      {
        id: "664359",
        transactionId: "INV06",
        date: "11/12/2020",
        debit: 91.91,
        dueDate: "10/02/2021"
      }
    ],
    creditmemo: []
  }
];

I have tried several ways, the latest one:

//console.log(data.length);
var data2 = [];
for (let value in data) {
  console.log(data[value].customerName);
  //console.log(data[value]);
  var invoices = [];
  invoices.push(data[value].invoices[0]);
  //console.log(1);
  //console.log(customer);
  /* var max = new Date(
    Math.max.apply(
      null,
      customer.map(function (o) {
        var dateString = o.dueDate;
        var dateParts = dateString.split("/");
        var dateObject = new Date(
          +dateParts[2],
          dateParts[1] - 1,
          +dateParts[0]
        );
        return new Date(dateObject);
      })
    )
  );*/
  var result = [
    invoices.reduce((acc, n) => {
      for (var prop in n) {
        console.log("prop: " + prop);
        if (prop === "debit") {
          if (acc[prop]) {
            acc[prop] += n[prop];
            console.log("OK");
          } else {
            acc[prop] = n[prop];
          }
        } else if (prop === "dueDate") {
          //acc[prop] = max;
        } else {
          acc[prop] = n[prop];
        }
      }
      return acc;
    }, {})
  ];
  data2.push(result);
}
console.log(data2);

I would like to have the following result, sum all the debit of the invoices per customer, get the max date per customer (I didn't find a way to remove the empty property creditmemo

[
  {
    customerName: "Customer1",
    customerId: "1234",
    invoices: [
      {
        id: "647549",
        transactionId: "INV01",
        date: "10/12/2020",
        debit: 371.93,
        dueDate: "09/02/2021"
      }
    ]
  },
  {
    customerName: "Customer5",
    customerId: "5678",
    invoices: [
      {
        id: "631109-664359",
        transactionId: "INV05-INV06",
        date: "11/12/2020",
        debit: 298.83,
        dueDate: "08/02/2021"
      }
  }
];
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
Komagain
  • 378
  • 1
  • 10
  • what should `id` value be when a customer has more than two invoices ? Why have a string with the dash (`-`) separator, such as `transactionId: "INV05-INV06"`, instead an array of id values, such as `transactionIds:["INV05","INV06"]` – Richard Dec 20 '20 at 22:24
  • the system that will consume this file has only one descriptive field for the invoice, – Komagain Dec 21 '20 at 10:49

1 Answers1

0

It's a fairly straightforward map() of the data array, with a nested reduce() call to refactor the invoices array. The first element in the invoices array is passed as the initial accumulator and it is only refactored if there are multiple in the array. Since we are returning a new object on each map iteration we can simply omit the creditMemo property.

I agree with the commenter regarding storing multiple id properties in arrays rather than concatenated strings – both for later use and simplicity of refactoring.

const summary = data.map(({ customerName, customerId, invoices }) => {
  const debitSummary = invoices.reduce((acc, inv, i) => {
    if (i) {
      acc = {
        ...acc,
        id: acc.id + '-' + inv.id,
        transactionId: acc.transactionId + '-' + inv.transactionId,
        debit: acc.debit + inv.debit,
        date: new Date(inv.date) > new Date(acc.date) ? inv.date : acc.date,
      }
    }
    return acc;
  }, invoices[0]);
  return { customerName, customerId, invoices: [{...debitSummary}] };
});

console.log(summary);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script>
const data = [{ customerName: "Customer1", customerId: "1234", invoices: [{ id: "647549", transactionId: "INV01", date: "10/12/2020", debit: 371.93, dueDate: "09/02/2021" }], creditmemo: [] }, { customerName: "Customer5", customerId: "5678", invoices: [{ id: "631109", transactionId: "INV05", date: "09/12/2020", debit: 206.92, dueDate: "08/02/2021" }, { id: "664359", transactionId: "INV06", date: "11/12/2020", debit: 91.91, dueDate: "10/02/2021" }], creditmemo: [] }];
</script>
pilchard
  • 12,414
  • 5
  • 11
  • 23