From 594912b51673e0785b18c64b021f456eadc17d3f Mon Sep 17 00:00:00 2001
From: alex <alex@alexloehr.net>
Date: Thu, 08 Oct 2026 15:30:40 +0000
Subject: [PATCH] GS-2555

---
 lib/libLp.js |  125 +++++++++++++++++++++++++++--------------
 1 files changed, 81 insertions(+), 44 deletions(-)

diff --git a/lib/libLp.js b/lib/libLp.js
index f5eac83..36c2a05 100644
--- a/lib/libLp.js
+++ b/lib/libLp.js
@@ -1,9 +1,12 @@
 const _ = require("lodash")
+const dayjs = require("dayjs")
 
 /////////////////////////////////////////////////////////////////////////
 
 module.exports = {
-    alleAuswerten,
+   alleAuswerten,
+   auswerten,
+   partitionDates,
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -14,59 +17,93 @@
  * @return {[usr_id,firstname,lastname,status,status_changed]}
  */
 function alleAuswerten(data) {
-    const grouped = _.groupBy(data, "usr_id")
-    const ret = []
-    for (const items of Object.values(grouped)) {
-        // console.log(items)
-        if (!items.length) continue
-        const unterStatusse = items.map(it => it.status)
+   const grouped = _.groupBy(data, "usr_id")
+   const ret = []
+   for (const items of Object.values(grouped)) {
+      if (!items.length) continue
 
-        const newStatus = auswerten(unterStatusse)
-        const status_changed = _.max(items.map(u => u.status_changed))
+      // const unterStatusse = items.map(it => it.status)
+      // const newStatus = auswerten(unterStatusse)
+      // const status_changed = _.max(items.map(u => u.status_changed))
 
-        const {usr_id, login, firstname, lastname,} = items[0]
-        const newItem = {
-            usr_id, login, firstname, lastname, status: newStatus, status_changed
-        }
-        ret.push(newItem)
-    }
-    console.log(ret)
-    return ret
+      // TODO GS-2555 Datum berücksichtigen für die Auswertung
+      const statusData = items.map(({status_changed, status}) => ({status_changed, status}))
+      const newStatus = auswerten(statusData)
+      const status_changed = _.max(items.map(u => u.status_changed))
+
+      const {usr_id, login, firstname, lastname,} = items[0]
+      const newItem = {
+         usr_id, login, firstname, lastname, status: newStatus, status_changed
+      }
+      ret.push(newItem)
+   }
+   return ret
 }
 
-function auswerten(unterStatusse) {
-    // unter Status auswerten
-    // 0 = noch nicht bearbeitet
-    // 1 = in Bearbeitung
-    // 2 = bestanden
-    // 3 = nicht bestanden
+/**
+ * Neuen Status berechnen
+ * @param {{status,status_changed}[]} statusData
+ * @return {number}
+ */
+function auswerten(statusData) {
+   // unter Status auswerten
+   // 0 = noch nicht bearbeitet
+   // 1 = in Bearbeitung
+   // 2 = bestanden
+   // 3 = nicht bestanden
 
-    // Fall 1: keine Unterstatussse vorhanden -> 0
-    if (!unterStatusse.length) {
-        return 0
-    }
 
-    // Fall 2: eines nicht bestanden -> alles nicht bestanden // 0,1,2,3 -> 3
-    if (unterStatusse.some(u => u === 3)) {
-        return 3
-    }
+   // Fall 1: keine Unterstatussse vorhanden -> 0
+   if (!statusData.length) {
+      return 0
+   }
 
-    // Fall 3: alle statusse gleich -> status // 0,0,0 1,1,1 2,2,2 3,3,3
-    if (isAllSame(unterStatusse)) {
-        return unterStatusse[0]
-    }
+   const maxDate = dayjs(_.max(statusData.map(it => it.status_changed)))
+   const {inside, outside} = partitionDates(maxDate, statusData)
 
-    // Fall 4: wenn eines in Bearbeitung -> in Bearbeitung // 0,1,0 2,1,2
-    if (unterStatusse.some(u => u === 1)) {
-        return 1
-    }
+   // Fall 2: eines nicht bestanden -> alles nicht bestanden // 0,1,2,3 -> 3
+   // hier kommt es nicht darauf an ob noch Daten in outside sind
+   if (inside.map(it => it.status).some(u => u === 3)) {
+      return 3
+   }
 
-    // Fall 5: sonst 0
-    return 0
+   // Fall 3: alle statusse gleich -> status // 0,0,0 1,1,1 2,2,2 3,3,3
+   // wenn outside nicht leer ist -> in Bearbeitung
+   if (isAllSame(inside.map(it => it.status))) {
+      // wenn keine Einträge in outside vorhanden sind einfach den Status zurückgeben
+      if(!outside.length) return statusData[0].status
+      // ansonsten in Bearbeitung
+      return 1
+   }
+
+   // Fall 4: wenn eines in Bearbeitung -> in Bearbeitung // 0,1,0 2,1,2
+   if (inside.map(it=>it.status).some(u => u === 1 || u === 2)) {
+      return 1
+   }
+
+   // Fall 5: sonst 0
+   return 0
+}
+
+/**
+ * @param  {Date} maxDate
+ * @param {{status, status_changed}[]} items
+ */
+function partitionDates(maxDate, items) {
+   const [inside, outside] = _.partition(items, function (it) {
+      return isInBallpark(maxDate, it.status_changed)
+   })
+   return {inside, outside}
+}
+
+function isInBallpark(maxDate, date) {
+   const ballpark = {value: 1, unit: "month"}
+   const diff = maxDate.diff(date, ballpark.unit, true)
+   return diff <= ballpark.value
 }
 
 function isAllSame(items) {
-    if (!items.length) return false
-    const first = items[0]
-    return items.every(it => it === first)
+   if (!items.length) return false
+   const first = items[0]
+   return items.every(it => it === first)
 }

--
Gitblit v1.8.0