|
|
|
|
@@ -153,6 +153,7 @@ async function getOrders(filters?: { status?: string; lieferant_id?: number; bes
|
|
|
|
|
`SELECT b.*,
|
|
|
|
|
l.name AS lieferant_name,
|
|
|
|
|
COALESCE(u.name, u.preferred_username, u.email) AS besteller_name,
|
|
|
|
|
COALESCE(mu.name, mu.preferred_username, mu.email) AS mitglied_name,
|
|
|
|
|
COALESCE(pos.total_cost, 0) AS total_cost,
|
|
|
|
|
COALESCE(pos.items_count, 0) AS items_count,
|
|
|
|
|
COALESCE(pos.total_received, 0) AS total_received,
|
|
|
|
|
@@ -160,6 +161,7 @@ async function getOrders(filters?: { status?: string; lieferant_id?: number; bes
|
|
|
|
|
FROM bestellungen b
|
|
|
|
|
LEFT JOIN lieferanten l ON l.id = b.lieferant_id
|
|
|
|
|
LEFT JOIN users u ON u.id = b.erstellt_von
|
|
|
|
|
LEFT JOIN users mu ON mu.id = b.mitglied_id
|
|
|
|
|
LEFT JOIN LATERAL (
|
|
|
|
|
SELECT SUM(einzelpreis * menge) AS total_cost,
|
|
|
|
|
COUNT(*) AS items_count,
|
|
|
|
|
@@ -191,11 +193,16 @@ async function getOrderById(id: number) {
|
|
|
|
|
COALESCE(u.name, u.preferred_username, u.email) AS besteller_name,
|
|
|
|
|
u.email AS besteller_email,
|
|
|
|
|
COALESCE(mp.telefon_mobil, mp.telefon_privat) AS besteller_telefon,
|
|
|
|
|
mp.dienstgrad AS besteller_dienstgrad
|
|
|
|
|
mp.dienstgrad AS besteller_dienstgrad,
|
|
|
|
|
mu.id AS mitglied_id,
|
|
|
|
|
COALESCE(mu.name, mu.preferred_username, mu.email) AS mitglied_name,
|
|
|
|
|
mmp.dienstgrad AS mitglied_dienstgrad
|
|
|
|
|
FROM bestellungen b
|
|
|
|
|
LEFT JOIN lieferanten l ON l.id = b.lieferant_id
|
|
|
|
|
LEFT JOIN users u ON u.id = COALESCE(b.besteller_id, b.erstellt_von)
|
|
|
|
|
LEFT JOIN mitglieder_profile mp ON mp.user_id = COALESCE(b.besteller_id, b.erstellt_von)
|
|
|
|
|
LEFT JOIN users mu ON mu.id = b.mitglied_id
|
|
|
|
|
LEFT JOIN mitglieder_profile mmp ON mmp.user_id = b.mitglied_id
|
|
|
|
|
WHERE b.id = $1`,
|
|
|
|
|
[id]
|
|
|
|
|
);
|
|
|
|
|
@@ -227,7 +234,7 @@ async function getOrderById(id: number) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function createOrder(data: { bezeichnung: string; lieferant_id?: number; besteller_id?: string; notizen?: string; budget?: number; steuersatz?: number; positionen?: Array<{ bezeichnung: string; menge: number; einheit?: string }> }, userId: string) {
|
|
|
|
|
async function createOrder(data: { bezeichnung: string; lieferant_id?: number; besteller_id?: string; mitglied_id?: string; notizen?: string; budget?: number; steuersatz?: number; positionen?: Array<{ bezeichnung: string; menge: number; einheit?: string }> }, userId: string) {
|
|
|
|
|
const client = await pool.connect();
|
|
|
|
|
try {
|
|
|
|
|
await client.query('BEGIN');
|
|
|
|
|
@@ -242,10 +249,10 @@ async function createOrder(data: { bezeichnung: string; lieferant_id?: number; b
|
|
|
|
|
|
|
|
|
|
const bestellerId = data.besteller_id && data.besteller_id.trim() ? data.besteller_id.trim() : null;
|
|
|
|
|
const result = await client.query(
|
|
|
|
|
`INSERT INTO bestellungen (bezeichnung, lieferant_id, besteller_id, notizen, budget, steuersatz, laufende_nummer, erstellt_von)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
|
|
|
`INSERT INTO bestellungen (bezeichnung, lieferant_id, besteller_id, notizen, budget, steuersatz, mitglied_id, laufende_nummer, erstellt_von)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
|
|
|
RETURNING *`,
|
|
|
|
|
[data.bezeichnung, data.lieferant_id || null, bestellerId, data.notizen || null, data.budget || null, data.steuersatz ?? 20, laufendeNummer, userId]
|
|
|
|
|
[data.bezeichnung, data.lieferant_id || null, bestellerId, data.notizen || null, data.budget || null, data.steuersatz ?? 20, data.mitglied_id || null, laufendeNummer, userId]
|
|
|
|
|
);
|
|
|
|
|
const order = result.rows[0];
|
|
|
|
|
|
|
|
|
|
@@ -271,7 +278,7 @@ async function createOrder(data: { bezeichnung: string; lieferant_id?: number; b
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function updateOrder(id: number, data: { bezeichnung?: string; lieferant_id?: number; besteller_id?: string | null; notizen?: string; budget?: number; status?: string; steuersatz?: number }, userId: string) {
|
|
|
|
|
async function updateOrder(id: number, data: { bezeichnung?: string; lieferant_id?: number; besteller_id?: string | null; notizen?: string; budget?: number; status?: string; steuersatz?: number; mitglied_id?: string | null }, userId: string) {
|
|
|
|
|
try {
|
|
|
|
|
// Check current order for status change detection
|
|
|
|
|
const current = await pool.query(`SELECT * FROM bestellungen WHERE id = $1`, [id]);
|
|
|
|
|
@@ -303,10 +310,11 @@ async function updateOrder(id: number, data: { bezeichnung?: string; lieferant_i
|
|
|
|
|
bestellt_am = $7,
|
|
|
|
|
abgeschlossen_am = $8,
|
|
|
|
|
steuersatz = COALESCE($9, steuersatz),
|
|
|
|
|
mitglied_id = CASE WHEN $10::text IS NOT NULL AND $10::text != '' THEN $10::uuid ELSE mitglied_id END,
|
|
|
|
|
aktualisiert_am = NOW()
|
|
|
|
|
WHERE id = $10
|
|
|
|
|
WHERE id = $11
|
|
|
|
|
RETURNING *`,
|
|
|
|
|
[data.bezeichnung, data.lieferant_id, data.besteller_id ?? null, data.notizen, data.budget, data.status, bestellt_am, abgeschlossen_am, data.steuersatz, id]
|
|
|
|
|
[data.bezeichnung, data.lieferant_id, data.besteller_id ?? null, data.notizen, data.budget, data.status, bestellt_am, abgeschlossen_am, data.steuersatz, data.mitglied_id ?? null, id]
|
|
|
|
|
);
|
|
|
|
|
if (result.rows.length === 0) return null;
|
|
|
|
|
|
|
|
|
|
@@ -317,6 +325,7 @@ async function updateOrder(id: number, data: { bezeichnung?: string; lieferant_i
|
|
|
|
|
if (data.status && data.status !== oldStatus) changes.push(`Status: ${oldStatus} → ${data.status}`);
|
|
|
|
|
if (data.budget) changes.push(`Budget geändert`);
|
|
|
|
|
if (data.steuersatz != null) changes.push(`Steuersatz: ${data.steuersatz}%`);
|
|
|
|
|
if (data.mitglied_id) changes.push('Mitglied geändert');
|
|
|
|
|
|
|
|
|
|
await logAction(id, 'Bestellung aktualisiert', changes.join(', ') || 'Bestellung bearbeitet', userId);
|
|
|
|
|
return result.rows[0];
|
|
|
|
|
|