feat(opportunities): letzten Phasenwechsel mit Benutzer und Zeit anzeigen

Neue Spalten stage_changed_at/stage_changed_by, gesetzt nur bei echtem
Phasenwechsel per PATCH. Der Dialog zeigt unter "Angelegt von" die Zeile
"Verschoben von ... am ... um ... in ...".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sascha Wolf
2026-10-01 11:29:00 +02:00
co-authored by Claude Opus 5.5
parent 5ba1ee1e0b
commit b9d6544b30
7 changed files with 62 additions and 9 deletions
+9
View File
@@ -91,11 +91,13 @@ const SELECT_OPPORTUNITIES = `
owner.color AS owner_color,
owner.avatar AS owner_avatar,
deleter.name AS deleted_by_name,
mover.name AS stage_changed_by_name,
(src.id IS NOT NULL AND src.deleted_at IS NULL) AS acquisition_available
FROM crm_opportunities o
LEFT JOIN crm_users creator ON creator.id = o.created_by
LEFT JOIN crm_users owner ON owner.id = o.owner_id
LEFT JOIN crm_users deleter ON deleter.id = o.deleted_by
LEFT JOIN crm_users mover ON mover.id = o.stage_changed_by
LEFT JOIN crm_acquisitions src ON src.id = o.acquisition_id
`;
@@ -434,6 +436,13 @@ router.patch('/:id', async (req, res, next) => {
fields.push('stage = ?');
values.push(req.body.stage);
// Wer hat wann verschoben - nur bei echtem Wechsel, sonst wuerde jedes
// Speichern im Dialog den Zeitpunkt nach vorn schieben.
if (req.body.stage !== existing.stage) {
fields.push('stage_changed_at = UTC_TIMESTAMP()', 'stage_changed_by = ?');
values.push(req.user.id);
}
/*
* Zeitpunkt des Gewinns mitschreiben. Der erste Wechsel nach 'Beauftragt'
* zaehlt; ein zweites Speichern derselben Phase darf das Datum nicht nach