Implement Excel webhook integration
Features: - Migration 0007: shipping_date column with automatic next-business-day calculation - New function trigger_excel_webhook() in order-import.php - SQL query for extracting Excel data from ERP database - Integration after successful order import - Documentation for n8n Postgres node configuration Changes: 1. db/migrations/0007_phase1_excel_webhook.sql - adds shipping_date column, trigger, next-business-day function 2. order-import.php - adds trigger_excel_webhook() function and integration point 3. docs/EXAKTE_POSTGRES_QUERY.sql - exact SQL query for n8n Postgres node 4. docs/N8N_POSTGRES_QUERY.md - comprehensive documentation 5. docs/N8N_POSTGRES_NODE.* - n8n node configurations 6. docs/N8N_EXCEL_WORKFLOW.json - complete workflow JSON 7. docs/N8N_NODE_COPY_PASTE.md - copy-paste ready instructions The implementation triggers an Excel webhook after every successful order import, sending all necessary data for Excel bookkeeping to n8n.
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user