Files
Holzleitner---Backend--aktu…/tool/seed_demo_data.sh
Dennis Nemec 6a9b5872e1 Backend-Arbeitsstand: ERP-Sync, Lieferlebenszyklus, Reports + config.toml
Bringt das Backend vom initialen Skeleton auf den aktuellen Arbeitsstand
(Clean Architecture: domain → application → infrastructure → api).

Wesentliche Bereiche:
- ERP-Anbindung (MSSQL-Pull der Touren, Import-Scheduler, Rückschreiben)
- Lieferlebenszyklus: Scan/Hold/Cancel/Complete, Gutschriften, Notizen,
  Bild-Anhänge, Unterschriften, PDF-Lieferreport → DOCUframe
- Stammdaten: Kunden, Artikel, Lager, Zahlungsarten, Services
- Keycloak-JWT-Gate + Fahrer-Provisionierung via Admin-API
- Admin-API-Key-Gate (X-Admin-Api-Key) für Maschinen-Endpunkte

Jüngste Änderungen dieser Session:
- Belegspezifische Kontaktdaten: alle ERP-Adressen (Beleg-/Liefer-/
  Rechnungsadresse, Ansprechpartner, Kundenstamm) mit Telefon/Mobil/
  E-Mail werden gesynct (Migration 0029, MSSQL-Query, TourDetails)
- Konfiguration von .env (envy/dotenvy) auf config.toml (toml/serde)
  umgestellt; Vorlage config.example.toml, Pfad via HOLZLEITNER_CONFIG

Nicht im Repo (per .gitignore): config.toml (Secrets), data/ (Laufzeit-/
Kundendaten), demo.mp4, .claude/, variocontrol-ai/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:52:58 +02:00

300 lines
17 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
#
# Setzt die Test-DB auf einen realistischen Holzleitner-Datenstand:
# 8 Elektrogeräte-Lieferungen für Personalnummer 1001, Mix aus Standard-
# und Filial-Items.
#
# Im Gegensatz zu `reset_test_tour.sh` (nur Item-Status zurücksetzen)
# baut dieses Skript Stammdaten + Lieferungen komplett neu auf. Idempotent:
# vorhandene Test-Touren der Accounts 1001/1002 werden gelöscht (CASCADE
# räumt deliveries / items / scan_audit / notes mit), Customer- und
# Article-Stamm wird ersetzt.
#
# Tour-Datum:
# * ohne Argument → heute (CURRENT_DATE)
# * mit Datum YYYY-MM-DD → genau dieser Tag
#
# Aufruf:
# ./tool/seed_demo_data.sh # Tour für heute
# ./tool/seed_demo_data.sh 2026-06-01 # Tour für ein bestimmtes Datum
# TOUR_DATE=2026-06-01 ./tool/seed_demo_data.sh # alternativ via Env
set -euo pipefail
CONTAINER="${CONTAINER:-holzleitner-postgres}"
DB_USER="${DB_USER:-holzleitner}"
DB_NAME="${DB_NAME:-holzleitner}"
# Datum aus erstem Argument oder TOUR_DATE-Env. Leer = heute.
TOUR_DATE="${1:-${TOUR_DATE:-}}"
if [ -n "$TOUR_DATE" ]; then
if ! [[ "$TOUR_DATE" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
echo "✗ Ungültiges Datum '$TOUR_DATE'. Erwartet: YYYY-MM-DD." >&2
exit 1
fi
# SQL-Literal — der Wert ist durch die Regex oben auf reine Ziffern/Bindestriche
# beschränkt, daher kein Injection-Risiko.
TOUR_DATE_EXPR="DATE '$TOUR_DATE'"
DATE_LABEL="$TOUR_DATE"
else
TOUR_DATE_EXPR="CURRENT_DATE"
DATE_LABEL="heute"
fi
if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
echo "✗ Container '$CONTAINER' läuft nicht. Starte docker compose up -d." >&2
exit 1
fi
echo "→ Seed Demo-Daten (8 Elektrogeräte-Lieferungen, PN 1001, Tour-Datum: $DATE_LABEL) …"
docker exec -i "$CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -v ON_ERROR_STOP=1 -q \
-v tour_date_expr="$TOUR_DATE_EXPR" <<'SQL'
BEGIN;
-- ── 1. Alte Test-Daten räumen ────────────────────────────────────────
-- Tours mit CASCADE räumt deliveries → delivery_items → scan_audit ab.
DELETE FROM tours WHERE account_id IN (1001, 1002);
-- Existierende Test-Customer und Custom-Artikel wegwerfen — sie können
-- jetzt sauber durch realistische Daten ersetzt werden.
DELETE FROM customers
WHERE erp_customer_id BETWEEN 4700 AND 5200;
DELETE FROM articles
WHERE article_number IN (
'BRETT-200','PALETTE-EUR','FRACHT-PAUSCH','NEU-BALKEN',
'KS-EXP-200','WM-BOS-7K','TR-SIE-8K','SP-MIE-CL',
'BO-AEG-PY','MW-SAM-23','ST-GAG-IN','DH-MIE-AC'
);
-- ── 2. Elektrogeräte-Stamm ───────────────────────────────────────────
-- Default-Warehouse setzen wir nur dort, wo das Backend-Schema das
-- semantisch erwartet (Lager-Hint im ERP). Die *tatsächliche* Lager-
-- Zuordnung pro Lieferposition kommt unten in delivery_items.warehouse_id.
INSERT INTO articles (id, article_number, name, scannable, default_warehouse_id) VALUES
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa001', 'KS-EXP-200', 'Kühl-Gefrierkombi Exquisit 200L', true, '11111111-1111-1111-1111-111111111111'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa002', 'WM-BOS-7K', 'Waschmaschine Bosch WAU28T70 7kg', true, '11111111-1111-1111-1111-111111111111'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa003', 'TR-SIE-8K', 'Wärmepumpentrockner Siemens iQ500 8kg', true, '11111111-1111-1111-1111-111111111111'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa004', 'SP-MIE-CL', 'Geschirrspüler Miele G5210 Classic', true, '11111111-1111-1111-1111-111111111111'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa005', 'BO-AEG-PY', 'Einbau-Backofen AEG Pyrolyse', true, '11111111-1111-1111-1111-111111111112'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa006', 'MW-SAM-23', 'Mikrowelle Samsung MS23K3513 23L', true, '11111111-1111-1111-1111-111111111111'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa007', 'ST-GAG-IN', 'Induktions-Standherd Gaggenau CI491', true, '11111111-1111-1111-1111-111111111112'),
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa008', 'DH-MIE-AC', 'Dunstabzugshaube Miele PUR98W', true, '11111111-1111-1111-1111-111111111111');
-- ── 3. Kunden (BGL-Region) ───────────────────────────────────────────
INSERT INTO customers (id, erp_customer_id, name, street, house_number, postal_code, city, country) VALUES
('cccccccc-cccc-cccc-cccc-ccccccccc001', 5101, 'Familie Bauer', 'Marktplatz', '5', '83435', 'Bad Reichenhall', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc002', 5102, 'Familie Hofer', 'Ludwigstraße', '12', '83435', 'Bad Reichenhall', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc003', 5103, 'Familie Steiner', 'Bahnhofstraße', '8', '83454', 'Anger', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc004', 5104, 'Familie Mayr', 'Hauptstraße', '22', '83471', 'Berchtesgaden', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc005', 5105, 'Familie Wagner', 'Wittelsbacherstraße', '3', '83435', 'Bad Reichenhall', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc006', 5106, 'Familie Berger', 'Salzburger Straße', '45', '83454', 'Anger', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc007', 5107, 'Familie Huber', 'Reichenhaller Straße', '10', '83483', 'Bischofswiesen', 'Deutschland'),
('cccccccc-cccc-cccc-cccc-ccccccccc008', 5108, 'Familie Lechner', 'Maximilianstraße', '15', '83435', 'Bad Reichenhall', 'Deutschland');
-- Ansprechpartner — eine Person pro Familie, primär als Telefon-Anker.
INSERT INTO customer_contacts (id, customer_id, name, phone, email) VALUES
('dddddddd-dddd-dddd-dddd-ddddddddd001', 'cccccccc-cccc-cccc-cccc-ccccccccc001', 'Martin Bauer', '+49 8651 12345', NULL),
('dddddddd-dddd-dddd-dddd-ddddddddd002', 'cccccccc-cccc-cccc-cccc-ccccccccc002', 'Anna Hofer', '+49 8651 23456', 'a.hofer@example.de'),
('dddddddd-dddd-dddd-dddd-ddddddddd003', 'cccccccc-cccc-cccc-cccc-ccccccccc003', 'Josef Steiner', '+49 8656 34567', NULL),
('dddddddd-dddd-dddd-dddd-ddddddddd004', 'cccccccc-cccc-cccc-cccc-ccccccccc004', 'Sabine Mayr', '+49 8652 45678', NULL),
('dddddddd-dddd-dddd-dddd-ddddddddd005', 'cccccccc-cccc-cccc-cccc-ccccccccc005', 'Thomas Wagner', '+49 8651 56789', 't.wagner@example.de'),
('dddddddd-dddd-dddd-dddd-ddddddddd006', 'cccccccc-cccc-cccc-cccc-ccccccccc006', 'Petra Berger', '+49 8656 67890', NULL),
('dddddddd-dddd-dddd-dddd-ddddddddd007', 'cccccccc-cccc-cccc-cccc-ccccccccc007', 'Franz Huber', '+49 8652 78901', NULL),
('dddddddd-dddd-dddd-dddd-ddddddddd008', 'cccccccc-cccc-cccc-cccc-ccccccccc008', 'Maria Lechner', '+49 8651 89012', 'm.lechner@example.de');
-- ── 4. Tour für PN 1001 ───────────────────────────────────────────────
-- Datum kommt als psql-Variable (Default CURRENT_DATE, sonst DATE 'YYYY-MM-DD').
INSERT INTO tours (id, account_id, tour_date, synced_at) VALUES
('55555555-5555-5555-5555-555555555555', 1001, :tour_date_expr, NOW());
-- ── 5. Lieferungen ───────────────────────────────────────────────────
-- erp_belegart_id = 1 (Auftragsbestätigung, AB) wie in den ursprünglichen
-- Seeds. sort_order entspricht der ERP-Vorgabe; die App kann nachträglich
-- über PUT /tours/{id}/delivery-order anders sortieren.
-- Payment-Method-IDs (siehe Migration 0008):
-- cash = 99999999-9999-9999-9999-999999999901
-- ec_card = 99999999-9999-9999-9999-999999999902
-- invoice = 99999999-9999-9999-9999-999999999904
-- (credit_card wurde aus den Stammdaten entfernt — Migration 0021)
INSERT INTO deliveries (
id, tour_id, erp_belegart_id, erp_belegnummer, customer_id,
snap_street, snap_house_number, snap_postal_code, snap_city, snap_country,
assigned_car_id, desired_time, special_agreements,
state, state_reason, sort_order,
prepaid_amount, payment_method_id
) VALUES
-- Bauer: voll vorab bezahlt (Online-Kauf), Methode bleibt der ERP-Default (cash)
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee001', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1001', 'cccccccc-cccc-cccc-cccc-ccccccccc001',
'Marktplatz', '5', '83435', 'Bad Reichenhall', 'Deutschland',
NULL, '08:30 10:00', NULL, 'active', NULL, 1,
899.00, '99999999-9999-9999-9999-999999999901'),
-- Hofer: nichts vorab, EC bei Lieferung (Wasch+Trockner)
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee002', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1002', 'cccccccc-cccc-cccc-cccc-ccccccccc002',
'Ludwigstraße', '12', '83435', 'Bad Reichenhall', 'Deutschland',
NULL, '09:00 11:00', 'Bitte alte Geräte mitnehmen', 'active', NULL, 2,
0.00, '99999999-9999-9999-9999-999999999902'),
-- Steiner: 200 EUR Anzahlung, Rest auf Rechnung
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee003', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1003', 'cccccccc-cccc-cccc-cccc-ccccccccc003',
'Bahnhofstraße', '8', '83454', 'Anger', 'Deutschland',
NULL, NULL, NULL, 'active', NULL, 3,
200.00, '99999999-9999-9999-9999-999999999904'),
-- Mayr: Großgerät, EC bei Lieferung
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee004', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1004', 'cccccccc-cccc-cccc-cccc-ccccccccc004',
'Hauptstraße', '22', '83471', 'Berchtesgaden', 'Deutschland',
NULL, '13:00 15:00', 'Einbau erfolgt durch Servicepartner', 'active', NULL, 4,
0.00, '99999999-9999-9999-9999-999999999902'),
-- Wagner: nichts vorab, Bar
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee005', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1005', 'cccccccc-cccc-cccc-cccc-ccccccccc005',
'Wittelsbacherstraße', '3', '83435', 'Bad Reichenhall', 'Deutschland',
NULL, NULL, NULL, 'active', NULL, 5,
0.00, '99999999-9999-9999-9999-999999999901'),
-- Berger: 500 EUR Anzahlung, Rest EC
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee006', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1006', 'cccccccc-cccc-cccc-cccc-ccccccccc006',
'Salzburger Straße', '45', '83454', 'Anger', 'Deutschland',
NULL, '11:00 13:00', NULL, 'active', NULL, 6,
500.00, '99999999-9999-9999-9999-999999999902'),
-- Huber: nichts vorab, Rechnung (Stammkunde)
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee007', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1007', 'cccccccc-cccc-cccc-cccc-ccccccccc007',
'Reichenhaller Straße', '10', '83483', 'Bischofswiesen', 'Deutschland',
NULL, NULL, 'Anlieferung Tiefgaragen-Zugang', 'active', NULL, 7,
0.00, '99999999-9999-9999-9999-999999999904'),
-- Lechner: nichts vorab, Bar
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee008', '55555555-5555-5555-5555-555555555555',
1, 'AB-2026-1008', 'cccccccc-cccc-cccc-cccc-ccccccccc008',
'Maximilianstraße', '15', '83435', 'Bad Reichenhall', 'Deutschland',
NULL, '15:30 17:00', NULL, 'active', NULL, 8,
0.00, '99999999-9999-9999-9999-999999999901');
-- Ansprechpartner pro Lieferung (1:1).
INSERT INTO delivery_contact_persons (delivery_id, customer_contact_id) VALUES
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee001', 'dddddddd-dddd-dddd-dddd-ddddddddd001'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee002', 'dddddddd-dddd-dddd-dddd-ddddddddd002'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee003', 'dddddddd-dddd-dddd-dddd-ddddddddd003'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee004', 'dddddddd-dddd-dddd-dddd-ddddddddd004'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee005', 'dddddddd-dddd-dddd-dddd-ddddddddd005'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee006', 'dddddddd-dddd-dddd-dddd-ddddddddd006'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee007', 'dddddddd-dddd-dddd-dddd-ddddddddd007'),
('eeeeeeee-eeee-eeee-eeee-eeeeeeeee008', 'dddddddd-dddd-dddd-dddd-ddddddddd008');
-- ── 6. Items pro Lieferung ───────────────────────────────────────────
-- 1 Stück pro Gerät (Elektrogeräte-Geschäft: pro Belegzeile genau ein
-- Gerät). Filial-Items (Backofen, Standherd) landen explizit auf
-- Filiale Freilassing, weil die Geräte zu sperrig für das Standardlager sind.
INSERT INTO delivery_items (
id, delivery_id, article_id, required_quantity, warehouse_id,
belegzeilen_nr, komponenten_artikel_nr,
scanned_quantity, scan_status, held_reason
) VALUES
-- Bauer: Kühl-Gefrierkombi
('ffffffff-ffff-ffff-ffff-fffffffff001', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee001',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa001', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
-- Hofer: Waschmaschine + Trockner
('ffffffff-ffff-ffff-ffff-fffffffff002', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee002',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa002', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
('ffffffff-ffff-ffff-ffff-fffffffff003', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee002',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa003', 1, '11111111-1111-1111-1111-111111111111', 2, NULL, 0, 'in_progress', NULL),
-- Steiner: Geschirrspüler
('ffffffff-ffff-ffff-ffff-fffffffff004', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee003',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa004', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
-- Mayr: NUR Filiale (Backofen) — UX-Test „Standardlager fertig — Filiale offen"
('ffffffff-ffff-ffff-ffff-fffffffff005', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee004',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa005', 1, '11111111-1111-1111-1111-111111111112', 1, NULL, 0, 'in_progress', NULL),
-- Wagner: Mikrowelle + Dunstabzugshaube
('ffffffff-ffff-ffff-ffff-fffffffff006', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee005',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa006', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
('ffffffff-ffff-ffff-ffff-fffffffff007', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee005',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa008', 1, '11111111-1111-1111-1111-111111111111', 2, NULL, 0, 'in_progress', NULL),
-- Berger: drei Geräte (alle Standard)
('ffffffff-ffff-ffff-ffff-fffffffff008', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee006',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa001', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
('ffffffff-ffff-ffff-ffff-fffffffff009', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee006',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa002', 1, '11111111-1111-1111-1111-111111111111', 2, NULL, 0, 'in_progress', NULL),
('ffffffff-ffff-ffff-ffff-fffffffff010', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee006',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa006', 1, '11111111-1111-1111-1111-111111111111', 3, NULL, 0, 'in_progress', NULL),
-- Huber: NUR Filiale (Standherd) — UX-Test „nur Filiale"
('ffffffff-ffff-ffff-ffff-fffffffff011', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee007',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa007', 1, '11111111-1111-1111-1111-111111111112', 1, NULL, 0, 'in_progress', NULL),
-- Lechner: Spüler (Standard) + Backofen (Filiale) — UX-Test „gemischt"
('ffffffff-ffff-ffff-ffff-fffffffff012', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee008',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa004', 1, '11111111-1111-1111-1111-111111111111', 1, NULL, 0, 'in_progress', NULL),
('ffffffff-ffff-ffff-ffff-fffffffff013', 'eeeeeeee-eeee-eeee-eeee-eeeeeeeee008',
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa005', 1, '11111111-1111-1111-1111-111111111112', 2, NULL, 0, 'in_progress', NULL);
-- Stückpreise (brutto, EUR) pro Artikel. Der Warenwert einer Lieferung =
-- Σ unit_price × ausgelieferte Menge (Soll Gutschrift). Plausible Demo-Werte;
-- das ERP-Sync-Makro liefert die Preise später live mit.
UPDATE delivery_items di SET unit_price = CASE di.article_id
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa001' THEN 899.00 -- Kühl-Gefrierkombi
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa002' THEN 649.00 -- Waschmaschine
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa003' THEN 599.00 -- Trockner
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa004' THEN 549.00 -- Geschirrspüler
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa005' THEN 499.00 -- Backofen
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa006' THEN 199.00 -- Mikrowelle
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa007' THEN 749.00 -- Standherd
WHEN 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaa008' THEN 329.00 -- Dunstabzugshaube
ELSE unit_price END
FROM deliveries d
WHERE d.id = di.delivery_id AND d.tour_id = '55555555-5555-5555-5555-555555555555';
COMMIT;
\echo
\echo --- ARTIKEL ---
SELECT article_number, name, scannable FROM articles ORDER BY article_number;
\echo
\echo --- KUNDEN ---
SELECT erp_customer_id, name, postal_code, city FROM customers ORDER BY erp_customer_id;
\echo
\echo --- TOUR ---
SELECT account_id, tour_date, synced_at
FROM tours
WHERE id = '55555555-5555-5555-5555-555555555555';
\echo
\echo --- LIEFERUNGEN (PN 1001) ---
SELECT d.sort_order, d.erp_belegnummer, c.name AS kunde, d.snap_city
FROM deliveries d
JOIN customers c ON c.id = d.customer_id
WHERE d.tour_id = '55555555-5555-5555-5555-555555555555'
ORDER BY d.sort_order;
\echo
\echo --- ITEMS PRO LIEFERUNG ---
SELECT d.erp_belegnummer, di.belegzeilen_nr, a.article_number, a.name,
w.name AS lager, di.required_quantity
FROM delivery_items di
JOIN deliveries d ON d.id = di.delivery_id
JOIN articles a ON a.id = di.article_id
JOIN warehouses w ON w.id = di.warehouse_id
WHERE d.tour_id = '55555555-5555-5555-5555-555555555555'
ORDER BY d.sort_order, di.belegzeilen_nr;
SQL
echo "✓ Demo-Daten geseedet (Tour-Datum: $DATE_LABEL)."