rework internal order system
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
-- Migration 050: Add missing columns to ausruestung_anfragen
|
||||
-- These columns are referenced by the service code but were never created
|
||||
|
||||
ALTER TABLE ausruestung_anfragen ADD COLUMN IF NOT EXISTS bearbeitet_am TIMESTAMPTZ;
|
||||
ALTER TABLE ausruestung_anfragen ADD COLUMN IF NOT EXISTS bestell_nummer INT;
|
||||
ALTER TABLE ausruestung_anfragen ADD COLUMN IF NOT EXISTS bestell_jahr INT;
|
||||
|
||||
-- Backfill bestell_nummer for existing rows
|
||||
DO $$
|
||||
DECLARE
|
||||
yr INT;
|
||||
rec RECORD;
|
||||
nr INT;
|
||||
BEGIN
|
||||
FOR yr IN SELECT DISTINCT EXTRACT(YEAR FROM erstellt_am)::int FROM ausruestung_anfragen LOOP
|
||||
nr := 0;
|
||||
FOR rec IN SELECT id FROM ausruestung_anfragen WHERE EXTRACT(YEAR FROM erstellt_am)::int = yr AND bestell_nummer IS NULL ORDER BY erstellt_am LOOP
|
||||
nr := nr + 1;
|
||||
UPDATE ausruestung_anfragen SET bestell_nummer = nr, bestell_jahr = yr WHERE id = rec.id;
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
END $$;
|
||||
@@ -393,21 +393,36 @@ async function createRequest(
|
||||
await client.query('BEGIN');
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const maxResult = await client.query(
|
||||
`SELECT COALESCE(MAX(bestell_nummer), 0) + 1 AS next_nr
|
||||
FROM ausruestung_anfragen
|
||||
WHERE bestell_jahr = $1`,
|
||||
[currentYear],
|
||||
);
|
||||
const nextNr = maxResult.rows[0].next_nr;
|
||||
|
||||
const anfrageResult = await client.query(
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung, bestell_nummer, bestell_jahr)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *`,
|
||||
[userId, notizen || null, bezeichnung || null, nextNr, currentYear],
|
||||
);
|
||||
const anfrage = anfrageResult.rows[0];
|
||||
// Try with bestell_nummer/bestell_jahr (migration 050), fallback without
|
||||
let anfrage: Record<string, unknown>;
|
||||
try {
|
||||
await client.query('SAVEPOINT sp_bestell_nr');
|
||||
const maxResult = await client.query(
|
||||
`SELECT COALESCE(MAX(bestell_nummer), 0) + 1 AS next_nr
|
||||
FROM ausruestung_anfragen
|
||||
WHERE bestell_jahr = $1`,
|
||||
[currentYear],
|
||||
);
|
||||
const nextNr = maxResult.rows[0].next_nr;
|
||||
const anfrageResult = await client.query(
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung, bestell_nummer, bestell_jahr)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *`,
|
||||
[userId, notizen || null, bezeichnung || null, nextNr, currentYear],
|
||||
);
|
||||
await client.query('RELEASE SAVEPOINT sp_bestell_nr');
|
||||
anfrage = anfrageResult.rows[0];
|
||||
} catch {
|
||||
await client.query('ROLLBACK TO SAVEPOINT sp_bestell_nr');
|
||||
const anfrageResult = await client.query(
|
||||
`INSERT INTO ausruestung_anfragen (anfrager_id, notizen, bezeichnung)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING *`,
|
||||
[userId, notizen || null, bezeichnung || null],
|
||||
);
|
||||
anfrage = anfrageResult.rows[0];
|
||||
}
|
||||
|
||||
for (const item of items) {
|
||||
let itemBezeichnung = item.bezeichnung;
|
||||
@@ -566,17 +581,34 @@ async function updateRequestStatus(
|
||||
adminNotizen?: string,
|
||||
bearbeitetVon?: string,
|
||||
) {
|
||||
const result = await pool.query(
|
||||
`UPDATE ausruestung_anfragen
|
||||
SET status = $1,
|
||||
admin_notizen = COALESCE($2, admin_notizen),
|
||||
bearbeitet_von = COALESCE($3, bearbeitet_von),
|
||||
bearbeitet_am = NOW()
|
||||
WHERE id = $4
|
||||
RETURNING *`,
|
||||
[status, adminNotizen || null, bearbeitetVon || null, id],
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
// Use aktualisiert_am (always exists) + try bearbeitet_am (added in migration 050)
|
||||
try {
|
||||
const result = await pool.query(
|
||||
`UPDATE ausruestung_anfragen
|
||||
SET status = $1,
|
||||
admin_notizen = COALESCE($2, admin_notizen),
|
||||
bearbeitet_von = COALESCE($3, bearbeitet_von),
|
||||
bearbeitet_am = NOW(),
|
||||
aktualisiert_am = NOW()
|
||||
WHERE id = $4
|
||||
RETURNING *`,
|
||||
[status, adminNotizen || null, bearbeitetVon || null, id],
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
} catch {
|
||||
// Fallback if bearbeitet_am column doesn't exist yet (migration 050 not run)
|
||||
const result = await pool.query(
|
||||
`UPDATE ausruestung_anfragen
|
||||
SET status = $1,
|
||||
admin_notizen = COALESCE($2, admin_notizen),
|
||||
bearbeitet_von = COALESCE($3, bearbeitet_von),
|
||||
aktualisiert_am = NOW()
|
||||
WHERE id = $4
|
||||
RETURNING *`,
|
||||
[status, adminNotizen || null, bearbeitetVon || null, id],
|
||||
);
|
||||
return result.rows[0] || null;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRequest(id: number) {
|
||||
|
||||
@@ -134,8 +134,10 @@ class CleanupService {
|
||||
}
|
||||
const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM bestellungen');
|
||||
const count = rows[0].count;
|
||||
// Delete related linking tables first, then main table
|
||||
await pool.query('DELETE FROM ausruestung_anfrage_bestellung WHERE bestellung_id IN (SELECT id FROM bestellungen)');
|
||||
await pool.query('TRUNCATE bestellungen CASCADE');
|
||||
await pool.query('ALTER SEQUENCE bestellungen_id_seq RESTART WITH 1');
|
||||
try { await pool.query('ALTER SEQUENCE bestellungen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
|
||||
logger.info(`Cleanup: truncated bestellungen (${count} rows) and reset sequence`);
|
||||
return { count, deleted: true };
|
||||
}
|
||||
@@ -147,8 +149,10 @@ class CleanupService {
|
||||
}
|
||||
const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM ausruestung_anfragen');
|
||||
const count = rows[0].count;
|
||||
// Delete linking table first
|
||||
await pool.query('DELETE FROM ausruestung_anfrage_bestellung WHERE anfrage_id IN (SELECT id FROM ausruestung_anfragen)');
|
||||
await pool.query('TRUNCATE ausruestung_anfragen CASCADE');
|
||||
await pool.query('ALTER SEQUENCE ausruestung_anfragen_id_seq RESTART WITH 1');
|
||||
try { await pool.query('ALTER SEQUENCE ausruestung_anfragen_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
|
||||
logger.info(`Cleanup: truncated ausruestung_anfragen (${count} rows) and reset sequence`);
|
||||
return { count, deleted: true };
|
||||
}
|
||||
@@ -161,7 +165,7 @@ class CleanupService {
|
||||
const { rows } = await pool.query('SELECT COUNT(*)::int AS count FROM issues');
|
||||
const count = rows[0].count;
|
||||
await pool.query('TRUNCATE issues CASCADE');
|
||||
await pool.query('ALTER SEQUENCE issues_id_seq RESTART WITH 1');
|
||||
try { await pool.query('ALTER SEQUENCE issues_id_seq RESTART WITH 1'); } catch { /* sequence may not exist */ }
|
||||
logger.info(`Cleanup: truncated issues (${count} rows) and reset sequence`);
|
||||
return { count, deleted: true };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user