Files
tickte-system/src/lib/ticketTimes.js
T

75 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Spalte "Zeit" der Ticketliste: Arbeitszeit je Ticket, in Bloecken nachgeladen.
Nur Lesezugriffe. Eine Zelle ohne Ergebnis (laedt noch, Fehler, 0 min, abgeschnitten,
jenseits der ersten 200 Zeilen) zeigt immer "–", nie eine falsche Zahl. */
import { sumWorksheetMinutes } from './worksheetView'
import { stepLabel } from './timeSteps'
export const TIME_BLOCK = 100 // woids je Abfrage
export const TIME_QUERY_LIMIT = 5000 // Dokumente je Abfrage
export const TIME_MAX_ROWS = 200 // nur die ersten Zeilen bekommen eine Zeit
export const TIME_PARALLEL = 3 // gleichzeitige Abfragen
export function chunk(list, size) {
const out = []
for (let i = 0; i < list.length; i += size) out.push(list.slice(i, i + size))
return out
}
// Welche woids sind noch zu laden? Erste 200 Zeilen, ohne leere, doppelte und schon bekannte.
export function planTimeLoad(tickets, known = new Set()) {
const list = tickets || []
const seen = new Set()
const woids = []
for (const ticket of list.slice(0, TIME_MAX_ROWS)) {
const woid = String(ticket?.woid ?? '').trim()
if (!woid || seen.has(woid) || known.has(woid)) continue
seen.add(woid)
woids.push(woid)
}
return { blocks: chunk(woids, TIME_BLOCK), capped: list.length > TIME_MAX_ROWS }
}
// Minuten je woid eines Blocks. Wurde die Antwort abgeschnitten (Limit erreicht oder
// mehr Treffer als geliefert), ist keine Summe verlaesslich: null.
export function blockMinutes(woids, documents, total, limit = TIME_QUERY_LIMIT) {
const docs = documents || []
if (docs.length >= limit) return null
if (typeof total === 'number' && total > docs.length) return null
const byWoid = new Map()
for (const doc of docs) {
const key = String(doc?.woid ?? '').trim()
if (!byWoid.has(key)) byWoid.set(key, [])
byWoid.get(key).push(doc)
}
return Object.fromEntries(woids.map((woid) => [woid, sumWorksheetMinutes(byWoid.get(woid) || [])]))
}
// Worker-Pool: hoechstens `limit` gleichzeitig, Ergebnisse in Eingabereihenfolge, verwirft nie
export async function mapLimit(items, limit, fn) {
const results = new Array(items.length)
let next = 0
const worker = async () => {
while (next < items.length) {
const index = next
next += 1
try {
results[index] = { ok: true, value: await fn(items[index], index) }
} catch (error) {
results[index] = { ok: false, error }
}
}
}
await Promise.all(Array.from({ length: Math.min(Math.max(1, limit), items.length) }, worker))
return results
}
export function minutesCellText(ticket, index, byWoid) {
if (index >= TIME_MAX_ROWS) return '–'
const woid = String(ticket?.woid ?? '').trim()
if (!woid) return '–'
const minutes = byWoid?.get(woid)
if (typeof minutes !== 'number' || !(minutes > 0)) return '–'
return stepLabel(minutes)
}