Verbessere die Verarbeitung von Zeiteinträgen und integriere Zeitkorrekturen in die Logik zur Erstellung von Arbeitsblöcken
All checks were successful
Deploy production / deploy (push) Successful in 52s
All checks were successful
Deploy production / deploy (push) Successful in 52s
This commit is contained in:
@@ -1283,18 +1283,74 @@ class TimeEntryService {
|
||||
const weekEnd = new Date(year, month, day + daysToMonday + (weekOffset * 7) + 6);
|
||||
weekEnd.setHours(23, 59, 59, 999);
|
||||
|
||||
// Hole alle Worklog-Einträge für diese Woche
|
||||
const pairs = await worklogRepository.findPairsByUserInDateRange(uid, weekStart, weekEnd);
|
||||
|
||||
// Hole auch alle einzelnen Einträge für Pausen
|
||||
const allEntries = await worklogRepository.findByDateRange(uid, weekStart, weekEnd);
|
||||
|
||||
// Hole Timefix-Einträge für alle Worklog-IDs
|
||||
const allWorklogIds = [...new Set([
|
||||
...pairs.map(p => p.id),
|
||||
...allEntries.map(e => e.id)
|
||||
])];
|
||||
const allWorklogIds = [...new Set(allEntries.map(e => e.id))];
|
||||
const timefixMap = await worklogRepository.getTimefixesByWorklogIds(allWorklogIds);
|
||||
|
||||
// Arbeitsblöcke aus den effektiven Aktionen bilden. Eine Zeitkorrektur
|
||||
// kann nicht nur den Zeitpunkt, sondern auch den Aktionstyp ändern (z. B.
|
||||
// „Pause beginnen“ zu „Arbeit beenden“). Die Repository-Paarbildung kennt
|
||||
// nur die Original-Aktion und würde einen solchen Block als laufend lassen.
|
||||
const getAction = (entry) => {
|
||||
const fixes = timefixMap.get(entry.id);
|
||||
if (fixes?.length) return fixes[fixes.length - 1].fix_type;
|
||||
|
||||
let state = entry.state;
|
||||
if (typeof state === 'string') {
|
||||
try {
|
||||
state = JSON.parse(state);
|
||||
} catch (_) {
|
||||
// Der String ist bereits die Aktion.
|
||||
}
|
||||
}
|
||||
return state?.action || state;
|
||||
};
|
||||
|
||||
const getEffectiveTime = (entry) => {
|
||||
const fixes = timefixMap.get(entry.id);
|
||||
const fix = fixes?.[fixes.length - 1];
|
||||
if (!fix) return entry.tstamp;
|
||||
return typeof fix.fix_date_time === 'string'
|
||||
? fix.fix_date_time.replace(' ', 'T') + 'Z'
|
||||
: fix.fix_date_time;
|
||||
};
|
||||
|
||||
const pairs = [];
|
||||
const openWorkEntries = new Map();
|
||||
[...allEntries]
|
||||
.sort((a, b) => new Date(getEffectiveTime(a)) - new Date(getEffectiveTime(b)))
|
||||
.forEach(entry => {
|
||||
const action = getAction(entry);
|
||||
if (action === 'start work') {
|
||||
openWorkEntries.set(String(entry.id), entry);
|
||||
} else if (action === 'stop work' && entry.relatedTo_id) {
|
||||
const startEntry = openWorkEntries.get(String(entry.relatedTo_id));
|
||||
if (startEntry) {
|
||||
pairs.push({
|
||||
id: startEntry.id,
|
||||
end_id: entry.id,
|
||||
start_time: startEntry.tstamp,
|
||||
end_time: entry.tstamp,
|
||||
start_state: startEntry.state,
|
||||
end_state: entry.state
|
||||
});
|
||||
openWorkEntries.delete(String(entry.relatedTo_id));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
openWorkEntries.forEach(startEntry => {
|
||||
pairs.push({
|
||||
id: startEntry.id,
|
||||
start_time: startEntry.tstamp,
|
||||
end_time: null,
|
||||
start_state: startEntry.state,
|
||||
end_state: null
|
||||
});
|
||||
});
|
||||
|
||||
// Hole Vacation-Einträge für diese Woche
|
||||
const vacations = await worklogRepository.getVacationsByUserInDateRange(uid, weekStart, weekEnd);
|
||||
|
||||
Reference in New Issue
Block a user