Unterstützung: Rechenregel und Abzug im Abo-Stundenkonto
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c4fab31603
commit
7c6b0c906b
5 files changed
+148
-5
No files matched your search
@@ -1,12 +1,13 @@
|
||||
import { config } from '../config.js'
|
||||
import { listDocuments, Query } from './appwriteAdmin.js'
|
||||
import { worksheetMinutes } from './worksheetMinutes.js'
|
||||
|
||||
/**
|
||||
* Abo-Stundenkonto eines Kunden.
|
||||
*
|
||||
* Gutschriften: je bezahlter Abo-Rechnung 60 min (Collection hourCredits), gueltig 12 Monate.
|
||||
* Verbrauch: Worksheets mit countsToPlan=true auf Tickets des Kunden, je Eintrag
|
||||
* auf 15 min aufgerundet.
|
||||
* Verbrauch: Worksheets mit countsToPlan=true auf Tickets des Kunden inkl. Unterstuetzung
|
||||
* (worksheetMinutes), je Eintrag auf 15 min aufgerundet.
|
||||
* Verrechnung: FIFO - die aelteste noch gueltige Gutschrift wird zuerst verbraucht.
|
||||
* Was kein Guthaben mehr findet, ist Mehraufwand (separat abzurechnen).
|
||||
* Vertragsende: Restguthaben verfaellt (siehe Abo-Bedingungen Ziff. 4).
|
||||
@@ -55,14 +56,16 @@ export async function listPlanUsage(customerId) {
|
||||
.filter((ws) => Number(ws.totalTime) > 0)
|
||||
.map((ws) => {
|
||||
const wo = byId.get(ws.workorderId) || {}
|
||||
const total = worksheetMinutes(ws)
|
||||
return {
|
||||
id: ws.$id,
|
||||
wsid: ws.wsid || '',
|
||||
woid: ws.woid || wo.woid || '',
|
||||
topic: wo.topic || wo.title || '',
|
||||
date: parseSheetDate(ws).toISOString(),
|
||||
rawMinutes: Number(ws.totalTime) || 0,
|
||||
minutes: roundUsage(ws.totalTime),
|
||||
rawMinutes: total,
|
||||
minutes: roundUsage(total),
|
||||
supportMinutes: total - (Number(ws.totalTime) || 0),
|
||||
details: String(ws.details || '').slice(0, 300),
|
||||
employee: ws.employeeName || ws.employeeShort || '',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Unterstuetzung bei Arbeitsblaettern (WOMS-Feld "supporters", JSON-Liste [{ employeeId, name, task }]).
|
||||
* Jede unterstuetzende Person bekommt die Haelfte der Arbeitszeit, aufgerundet auf 15 Minuten
|
||||
* (Abo-Bedingungen § 4). Gleiche Regel wie WOMS src/lib/support.js; die Minuten werden nie
|
||||
* gespeichert, sondern immer aus totalTime berechnet.
|
||||
*/
|
||||
|
||||
const STEP = 15
|
||||
const MAX_TASK = 200
|
||||
|
||||
export function supportMinutes(totalTime) {
|
||||
const total = Number(totalTime) || 0
|
||||
if (total <= 0) return 0
|
||||
return Math.ceil(total / 2 / STEP) * STEP
|
||||
}
|
||||
|
||||
/** Nie eine Exception: kaputte Werte ergeben [] (einmal gemeldet), kaputte Eintraege fallen weg. context z. B. die Worksheet-ID. */
|
||||
export function parseSupporters(raw, context) {
|
||||
let list = raw
|
||||
if (typeof raw === 'string') {
|
||||
if (!raw.trim()) return []
|
||||
try {
|
||||
list = JSON.parse(raw)
|
||||
} catch {
|
||||
console.warn('[unterstuetzung] supporters unlesbar', context ?? '')
|
||||
return []
|
||||
}
|
||||
}
|
||||
if (list == null) return []
|
||||
if (!Array.isArray(list)) {
|
||||
console.warn('[unterstuetzung] supporters unlesbar', context ?? '')
|
||||
return []
|
||||
}
|
||||
const seen = new Set()
|
||||
const result = []
|
||||
for (const entry of list) {
|
||||
if (!entry || typeof entry !== 'object') continue
|
||||
const employeeId = String(entry.employeeId || '').trim()
|
||||
const task = String(entry.task || '').trim().slice(0, MAX_TASK)
|
||||
if (!employeeId || !task || seen.has(employeeId)) continue
|
||||
seen.add(employeeId)
|
||||
result.push({ employeeId, name: String(entry.name || '').trim(), task })
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** Arbeitszeit des Blatts plus die Unterstuetzung aller Personen */
|
||||
export function worksheetMinutes(ws) {
|
||||
const base = Number(ws?.totalTime) || 0
|
||||
return base + parseSupporters(ws?.supporters, ws?.$id).length * supportMinutes(base)
|
||||
}
|
||||
|
||||
export function firstName(name) {
|
||||
return String(name || '').trim().split(/\s+/)[0] || ''
|
||||
}
|
||||
Reference in new issue
Block a user