Unterstützung: eigene Zeilen und Gesamtzeit in den Projektdetails
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7c6b0c906b
commit
7da4452bbd
8 files changed
+136
-8
No files matched your search
@@ -3,7 +3,7 @@ import { config } from '../config.js'
|
||||
import { getDocument, listDocuments, Query } from '../services/appwriteAdmin.js'
|
||||
import { getSessionCustomerId, requireSession } from '../middleware/session.js'
|
||||
import { getProjectGitInsights, getProjectFileOverview } from '../services/projectInsights.js'
|
||||
import { customerChanges, customerOrder, customerWorkEntries } from '../services/customerProjectView.js'
|
||||
import { customerChanges, customerOrder, customerWorkEntries, workTotalMinutes } from '../services/customerProjectView.js'
|
||||
|
||||
const router = Router()
|
||||
|
||||
@@ -86,13 +86,15 @@ router.get('/:id/work', requireSession, loadOwnProject, async (req, res) => {
|
||||
return res.json({ order: null, entries: [] })
|
||||
}
|
||||
|
||||
// Alle Blaetter, damit "Arbeitszeit gesamt" stimmt; lange Listen klappt der Browser zu (PD_ENTRIES_SHOWN)
|
||||
const worksheets = await listDocuments(config.collections.worksheets, [
|
||||
Query.equal('workorderId', project.ticketId),
|
||||
Query.orderDesc('$createdAt'),
|
||||
Query.limit(50),
|
||||
Query.limit(5000),
|
||||
]).catch(() => [])
|
||||
|
||||
return res.json({ order, entries: customerWorkEntries(worksheets, { includeUpdates: false }) })
|
||||
const entries = customerWorkEntries(worksheets, { includeUpdates: false })
|
||||
return res.json({ order, entries, totalMinutes: workTotalMinutes(entries) })
|
||||
} catch (err) {
|
||||
return res.status(500).json({ error: err.message || 'Arbeiten konnten nicht geladen werden' })
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { config } from '../config.js'
|
||||
import { listDocuments, Query } from './appwriteAdmin.js'
|
||||
import { worksheetMinutes } from './worksheetMinutes.js'
|
||||
|
||||
/**
|
||||
* Tickets + zugehoerige Worksheets eines Kunden ("was wurde gemacht").
|
||||
@@ -40,6 +41,9 @@ export async function getCustomerActivity(customerId, { ticketLimit = 25, exclud
|
||||
serviceType: ws.serviceType || '',
|
||||
newStatus: ws.newStatus || '',
|
||||
totalTime: ws.totalTime || '',
|
||||
// Unterstuetzung (WOMS): Rohliste fuer customerWorkEntries, Summe fuer die Admin-Zeile
|
||||
supporters: ws.supporters || '',
|
||||
supportMinutes: worksheetMinutes(ws) - (Number(ws.totalTime) || 0),
|
||||
date: ws.endDate || ws.startDate || '',
|
||||
details: ws.details || '',
|
||||
isGit: ws.serviceType === 'GIT',
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* Admin-Ansichten nutzen weiter die Rohdaten.
|
||||
*/
|
||||
|
||||
import { parseSupporters, supportMinutes, firstName } from './worksheetMinutes.js'
|
||||
|
||||
const GENERIC_UPDATE = 'Website aktualisiert'
|
||||
|
||||
/* --------------------------------------------------------------- Commits --- */
|
||||
@@ -204,15 +206,20 @@ function customerWorkEntry(sheet, { includeUpdates }) {
|
||||
const [kind, label] = WORK_KINDS[type] || OTHER_WORK
|
||||
const date = isoDay(sheet.date || sheet.endDate || sheet.startDate)
|
||||
const minutes = Number(sheet.totalTime) || 0
|
||||
// Unterstuetzung: eigene Zeilen, je Person die Haelfte der Arbeitszeit (aufgerundet auf 15 min)
|
||||
const supports = parseSupporters(sheet.supporters, sheet.$id)
|
||||
.map((s) => ({ name: firstName(s.name), task: s.task, minutes: supportMinutes(minutes) }))
|
||||
.filter((s) => s.minutes > 0)
|
||||
const withSupports = (entry) => (supports.length ? { ...entry, supports } : entry)
|
||||
|
||||
if (isGit) {
|
||||
// In den Projektdetails stehen die Aenderungen schon unter "Letzte Änderungen";
|
||||
// dort zaehlt ein Push nur, wenn Arbeitszeit nachgetragen wurde
|
||||
if (!includeUpdates && !minutes) return null
|
||||
const changes = changesFromPushDetails(sheet.details)
|
||||
return changes.length ? { kind, label, date, minutes, changes } : null
|
||||
return changes.length ? withSupports({ kind, label, date, minutes, changes }) : null
|
||||
}
|
||||
return { kind, label, date, minutes, person: String(sheet.employeeName || '').trim(), text: String(sheet.details || '').trim() }
|
||||
return withSupports({ kind, label, date, minutes, person: String(sheet.employeeName || '').trim(), text: String(sheet.details || '').trim() })
|
||||
}
|
||||
|
||||
/** Worksheets (roh aus Appwrite oder aus getCustomerActivity) -> Eintraege fuer den Kunden. */
|
||||
@@ -225,9 +232,18 @@ export function customerWorkEntries(sheets = [], { includeUpdates = true } = {})
|
||||
if (entry.kind === 'update' && prev?.kind === 'update' && prev.date === entry.date) {
|
||||
prev.minutes += entry.minutes
|
||||
prev.changes.push(...entry.changes.filter((change) => !prev.changes.includes(change)))
|
||||
if (entry.supports) prev.supports = [...(prev.supports || []), ...entry.supports]
|
||||
continue
|
||||
}
|
||||
entries.push(entry)
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
/** Arbeitszeit gesamt fuer den Projektkopf: alle Schritte inkl. Unterstuetzung */
|
||||
export function workTotalMinutes(entries = []) {
|
||||
return entries.reduce(
|
||||
(sum, e) => sum + (Number(e.minutes) || 0) + (e.supports || []).reduce((s, x) => s + (Number(x.minutes) || 0), 0),
|
||||
0
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user