# Postgres Query für n8n Excel Node ## Übersicht Diese Query extrahiert alle benötigten Daten für die Excel-Buchhaltung basierend auf einer Bestellnummer. ## Postgres Node Konfiguration für n8n ### Connection Details ``` Host: 192.168.1.199 Port: 55432 Database: naurua_erp User: codex_db_user Password: Ze90re0KAry8gyJ6eAx0Gf4IelEGI SSL: Disabled (lokales Netzwerk) ``` ### SQL Query für Excel-Daten ```sql SELECT -- Bestellinformationen so.external_ref AS "Bestellnummer", TO_CHAR(so.order_date, 'YYYY-MM-DD"T"HH24:MI:SS') AS "Bestelldatum", TO_CHAR(so.shipping_date, 'YYYY-MM-DD') AS "Versanddatum", -- Kundenadresse (Lieferadresse) COALESCE(ad.first_name, '') AS "Vorname", COALESCE(ad.last_name, '') AS "Nachname", COALESCE(ad.street, '') AS "Strasse", COALESCE(ad.house_number, '') AS "Hausnummer", COALESCE(ad.zip, '') AS "PLZ", COALESCE(ad.city, '') AS "Stadt", COALESCE(ad.country_name, '') AS "Land", -- Zahlungs- und Betragsinformationen COALESCE(pm.code, '') AS "Zahlungsart", COALESCE(so.amount_net, 0) AS "Gesamtbetrag_netto", COALESCE(so.amount_shipping, 0) AS "Versandkosten", COALESCE(so.total_amount, 0) AS "Gesamtbetrag_brutto", COALESCE(so.amount_discount, 0) AS "Rabatt", -- Produktzählungen (nur aktive Produkte) COALESCE(SUM(CASE WHEN p.id = 8 THEN a.qty ELSE 0 END), 0) AS "#_ChagaFlaschen", -- CHAGA (ID 8) COALESCE(SUM(CASE WHEN p.id = 5 THEN a.qty ELSE 0 END), 0) AS "#_ReishiFlaschen", -- 003.01 (ID 5) COALESCE(SUM(CASE WHEN p.id = 9 THEN a.qty ELSE 0 END), 0) AS "#_ShiitakeFlaschen", -- SHIITAKE (ID 9) COALESCE(SUM(CASE WHEN p.id = 6 THEN a.qty ELSE 0 END), 0) AS "#_LionsManeFlaschen" -- 005.02 (ID 6) FROM sales_order so -- Lieferadresse LEFT JOIN address ad ON so.party_id = ad.party_id AND ad.type = 'shipping' -- Zahlungsart LEFT JOIN payment_method pm ON so.payment_method_id = pm.id -- Bestellpositionen und Allokationen LEFT JOIN sales_order_line sol ON so.id = sol.sales_order_id LEFT JOIN sales_order_line_lot_allocation a ON sol.id = a.sales_order_line_id -- Produkte (nur aktive) LEFT JOIN product p ON a.product_id = p.id AND p.status = 'active' WHERE so.external_ref = :bestellnummer GROUP BY so.id, ad.id, pm.id ``` ## Parameter - `:bestellnummer` - Die externe Bestellreferenz (z.B. `W123456` oder `DIR-20260329-00017`) ## Produkt-Mapping | Excel-Feld | Produkt-ID | SKU | Name | Status | |------------|------------|-----|------|--------| | `#_ChagaFlaschen` | 8 | `CHAGA` | Chaga Extrakt Tinktur 50 ml | 100% rein | aktiv | | `#_ReishiFlaschen` | 5 | `003.01` | Reishi Extrakt Tinktur 50 ml | 100% rein | aktiv | | `#_ShiitakeFlaschen` | 9 | `SHIITAKE` | Shiitake Extrakt Tinktur 50 ml | 100% rein | aktiv | | `#_LionsManeFlaschen` | 6 | `005.02` | Lion's Mane Extrakt Tinktur 50 ml | 100% rein | aktiv | **Ignoriert:** Produkt-ID 7 (`LIONSMANE`) - Status: inaktiv ## Feld-Erklärungen ### Bestellinformationen - `Bestellnummer` - Eindeutige Bestellreferenz (Wix: BestellungNr, Direktverkauf: DIR-...) - `Bestelldatum` - ISO 8601 Format: `YYYY-MM-DDTHH:MM:SS` - `Versanddatum` - ISO Date Format: `YYYY-MM-DD` (automatisch berechnet als nächster Arbeitstag) ### Kundenadresse - Alle Felder aus der Lieferadresse (`type = 'shipping'`) - Leere Werte werden als leere Strings zurückgegeben ### Zahlungsinformationen - `Zahlungsart` - Interner Code aus `payment_method` (z.B. `twint`, `bank_transfer`, `card`, `pickup`) - Beträge mit 2 Dezimalstellen, NULL wird zu 0 ### Produktzählungen - Summe der allokierten Mengen pro Produkt - Nur aktive Produkte (`status = 'active'`) - NULL wird zu 0 ## Beispieldaten ### Input ``` Bestellnummer: "W123456" ``` ### Output ```json { "Bestellnummer": "W123456", "Bestelldatum": "2026-04-06T14:30:00", "Versanddatum": "2026-04-07", "Vorname": "Max", "Nachname": "Mustermann", "Strasse": "Musterstrasse", "Hausnummer": "123", "PLZ": "8000", "Stadt": "Zürich", "Land": "Schweiz", "Zahlungsart": "twint", "Gesamtbetrag_netto": 85.00, "Versandkosten": 5.90, "Gesamtbetrag_brutto": 100.00, "Rabatt": 0.00, "#_ChagaFlaschen": 2, "#_ReishiFlaschen": 1, "#_ShiitakeFlaschen": 0, "#_LionsManeFlaschen": 1 } ``` ## Fehlerbehandlung ### Keine Bestellung gefunden ```json { "Bestellnummer": "W123456", "Bestelldatum": "", "Versanddatum": "", "Vorname": "", "Nachname": "", "Strasse": "", "Hausnummer": "", "PLZ": "", "Stadt": "", "Land": "", "Zahlungsart": "", "Gesamtbetrag_netto": 0, "Versandkosten": 0, "Gesamtbetrag_brutto": 0, "Rabatt": 0, "#_ChagaFlaschen": 0, "#_ReishiFlaschen": 0, "#_ShiitakeFlaschen": 0, "#_LionsManeFlaschen": 0 } ``` ### Keine Produkt-Allokationen - Alle Produktzählungen sind 0 - Andere Felder sind normal gefüllt ## Integration in n8n Flow ### Flow-Ablauf 1. **Webhook Node**: Empfängt `Bestellnummer` vom ERP 2. **Postgres Node**: Führt diese Query mit `:bestellnummer = $json.Bestellnummer` aus 3. **Excel Node**: Schreibt das Ergebnis in die Excel-Datei 4. **Response Node**: Optional - Bestätigung senden ### Query Parameters in n8n ``` Query: (siehe oben) Query Values: bestellnummer: {{ $json.Bestellnummer }} Operation: Select ``` ## Technische Hinweise ### Performance - Query verwendet JOINs auf indizierten Spalten - Gruppierung ist effizient für einzelne Bestellungen - `COALESCE` verhindert NULL-Werte für Excel-Kompatibilität ### Datum-Logik - `shipping_date` wird automatisch via Trigger berechnet - Wochenend-Logik: Freitag → Montag, Samstag → Montag, Sonntag → Montag - Keine Feiertags-Logik in Phase 1 ### Schema-Konsistenz - Alle Tabellen existieren nach Migration 0007 - `shipping_date` kann NULL sein (für sehr alte Bestellungen) - Produkt-IDs sind statisch in der aktuellen DB ## Testing ### Test Query ```sql -- Test mit existierender Bestellung SELECT * FROM sales_order WHERE external_ref LIKE 'W%' OR external_ref LIKE 'DIR-%' LIMIT 5; -- Test Query mit konkreter Bestellnummer -- [Hier Query einfügen und :bestellnummer ersetzen] ``` ### Expected Results - Eine Zeile pro Bestellung - Alle Felder gefüllt oder leere Strings/0 - Produktzählungen als Ganzzahlen