rework internal order system
This commit is contained in:
@@ -407,6 +407,33 @@ class AusruestungsanfrageController {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Position delivery tracking
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
async updatePositionGeliefert(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const positionId = Number(req.params.positionId);
|
||||
const { geliefert } = req.body as { geliefert?: boolean };
|
||||
|
||||
if (typeof geliefert !== 'boolean') {
|
||||
res.status(400).json({ success: false, message: 'geliefert (boolean) ist erforderlich' });
|
||||
return;
|
||||
}
|
||||
|
||||
const position = await ausruestungsanfrageService.updatePositionGeliefert(positionId, geliefert);
|
||||
if (!position) {
|
||||
res.status(404).json({ success: false, message: 'Position nicht gefunden' });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json({ success: true, data: position });
|
||||
} catch (error) {
|
||||
logger.error('AusruestungsanfrageController.updatePositionGeliefert error', { error });
|
||||
res.status(500).json({ success: false, message: 'Lieferstatus konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Overview
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Add per-item delivery tracking to request positions
|
||||
ALTER TABLE ausruestung_anfrage_positionen
|
||||
ADD COLUMN IF NOT EXISTS geliefert BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -51,6 +51,12 @@ router.patch('/requests/:id', authenticate, ausruestungsanfrageController.update
|
||||
router.patch('/requests/:id/status', authenticate, requirePermission('ausruestungsanfrage:approve'), ausruestungsanfrageController.updateRequestStatus.bind(ausruestungsanfrageController));
|
||||
router.delete('/requests/:id', authenticate, requirePermission('ausruestungsanfrage:approve'), ausruestungsanfrageController.deleteRequest.bind(ausruestungsanfrageController));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Position delivery tracking
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
router.patch('/positionen/:positionId/geliefert', authenticate, requirePermission('ausruestungsanfrage:approve'), ausruestungsanfrageController.updatePositionGeliefert.bind(ausruestungsanfrageController));
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Linking requests to orders
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -575,6 +575,33 @@ async function updateRequest(
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePositionGeliefert(positionId: number, geliefert: boolean) {
|
||||
const result = await pool.query(
|
||||
`UPDATE ausruestung_anfrage_positionen SET geliefert = $1 WHERE id = $2 RETURNING *`,
|
||||
[geliefert, positionId],
|
||||
);
|
||||
const position = result.rows[0];
|
||||
if (!position) return null;
|
||||
|
||||
// Auto-complete: if all positions are geliefert, set anfrage status to 'erledigt'
|
||||
if (geliefert) {
|
||||
const check = await pool.query(
|
||||
`SELECT COUNT(*) FILTER (WHERE NOT geliefert)::int AS remaining
|
||||
FROM ausruestung_anfrage_positionen
|
||||
WHERE anfrage_id = $1`,
|
||||
[position.anfrage_id],
|
||||
);
|
||||
if (check.rows[0].remaining === 0) {
|
||||
await pool.query(
|
||||
`UPDATE ausruestung_anfragen SET status = 'erledigt', aktualisiert_am = NOW() WHERE id = $1`,
|
||||
[position.anfrage_id],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
async function updateRequestStatus(
|
||||
id: number,
|
||||
status: string,
|
||||
@@ -582,6 +609,7 @@ async function updateRequestStatus(
|
||||
bearbeitetVon?: string,
|
||||
) {
|
||||
// Use aktualisiert_am (always exists) + try bearbeitet_am (added in migration 050)
|
||||
let updated;
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`UPDATE ausruestung_anfragen
|
||||
@@ -594,7 +622,7 @@ async function updateRequestStatus(
|
||||
RETURNING *`,
|
||||
[status, adminNotizen || null, bearbeitetVon || null, id],
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
updated = result.rows[0] || null;
|
||||
} catch {
|
||||
// Fallback if bearbeitet_am column doesn't exist yet (migration 050 not run)
|
||||
const result = await pool.query(
|
||||
@@ -607,8 +635,20 @@ async function updateRequestStatus(
|
||||
RETURNING *`,
|
||||
[status, adminNotizen || null, bearbeitetVon || null, id],
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
updated = result.rows[0] || null;
|
||||
}
|
||||
|
||||
// When status changes to 'erledigt', mark all positions as geliefert
|
||||
if (status === 'erledigt') {
|
||||
try {
|
||||
await pool.query(
|
||||
`UPDATE ausruestung_anfrage_positionen SET geliefert = true WHERE anfrage_id = $1`,
|
||||
[id],
|
||||
);
|
||||
} catch { /* column may not exist yet */ }
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
async function deleteRequest(id: number) {
|
||||
@@ -716,6 +756,7 @@ export default {
|
||||
getRequests,
|
||||
getMyRequests,
|
||||
getRequestById,
|
||||
updatePositionGeliefert,
|
||||
createRequest,
|
||||
updateRequest,
|
||||
updateRequestStatus,
|
||||
|
||||
Reference in New Issue
Block a user