const _ = require("lodash")
|
const dayjs = require("dayjs")
|
|
/////////////////////////////////////////////////////////////////////////
|
|
module.exports = {
|
alleAuswerten,
|
auswerten,
|
partitionDates,
|
}
|
|
/////////////////////////////////////////////////////////////////////////
|
|
/**
|
* Unterobjekte auswerten und LF kombinieren pro user
|
* @param {[usr_id,login,firstname,lastname,obj_id,item_id,item_obj_id,status,status_changed]} data
|
* @return {[usr_id,login,firstname,lastname,status,status_changed]}
|
*/
|
function alleAuswerten(data) {
|
const grouped = _.groupBy(data, "usr_id")
|
const ret = []
|
for (const items of Object.values(grouped)) {
|
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
|
}
|
|
/**
|
* 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 (!statusData.length) {
|
return 0
|
}
|
|
const maxDate = dayjs(_.max(statusData.map(it => it.status_changed)))
|
const {inside, outside} = partitionDates(maxDate, statusData)
|
|
// 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 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)
|
}
|