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:
@@ -348,6 +348,83 @@ function trigger_shipping_label_flow(array $order, array $localEnv): array
|
||||
];
|
||||
}
|
||||
|
||||
function trigger_excel_webhook(PDO $pdo, int $orderId, array $localEnv): array
|
||||
{
|
||||
$url = env_value('N8N_OUTBOUND_URL_ADRESSE', $localEnv);
|
||||
if ($url === '' || strpos($url, 'excel_befuellen') === false) {
|
||||
return [
|
||||
'enabled' => false,
|
||||
'ok' => false,
|
||||
'message' => 'Excel webhook URL not configured or incorrect (must contain "excel_befuellen")',
|
||||
];
|
||||
}
|
||||
|
||||
// SQL Query for all Excel data (without comments for n8n compatibility)
|
||||
$sql = "
|
||||
SELECT
|
||||
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\",
|
||||
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\",
|
||||
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\",
|
||||
COALESCE(SUM(CASE WHEN p.id = 8 THEN a.qty ELSE 0 END), 0) AS \"#_ChagaFlaschen\",
|
||||
COALESCE(SUM(CASE WHEN p.id = 5 THEN a.qty ELSE 0 END), 0) AS \"#_ReishiFlaschen\",
|
||||
COALESCE(SUM(CASE WHEN p.id = 9 THEN a.qty ELSE 0 END), 0) AS \"#_ShiitakeFlaschen\",
|
||||
COALESCE(SUM(CASE WHEN p.id = 6 THEN a.qty ELSE 0 END), 0) AS \"#_LionsManeFlaschen\"
|
||||
FROM sales_order so
|
||||
LEFT JOIN address ad ON so.party_id = ad.party_id AND ad.type = 'shipping'
|
||||
LEFT JOIN payment_method pm ON so.payment_method_id = pm.id
|
||||
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
|
||||
LEFT JOIN product p ON a.product_id = p.id AND p.status = 'active'
|
||||
WHERE so.id = :order_id
|
||||
GROUP BY so.id, ad.id, pm.id
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([':order_id' => $orderId]);
|
||||
$data = $stmt->fetch();
|
||||
|
||||
if (!$data) {
|
||||
return [
|
||||
'enabled' => true,
|
||||
'ok' => false,
|
||||
'message' => 'Order data not found or no product allocations',
|
||||
];
|
||||
}
|
||||
|
||||
// Authentication headers (same mechanism as shipping_label_flow)
|
||||
$headers = [];
|
||||
$secret = env_value('N8N_WEBHOOK_SECRET', $localEnv);
|
||||
if ($secret !== '') {
|
||||
$headers['X-Webhook-Secret'] = $secret;
|
||||
$headers['X-N8N-Secret'] = $secret;
|
||||
$headers['X-API-Key'] = $secret;
|
||||
$headers['Authorization'] = 'Bearer ' . $secret;
|
||||
}
|
||||
|
||||
$result = post_json($url, $data, $headers, 20);
|
||||
|
||||
return [
|
||||
'enabled' => true,
|
||||
'ok' => $result['ok'],
|
||||
'status' => $result['status'],
|
||||
'url' => $url,
|
||||
'message' => $result['ok'] ? 'Excel webhook triggered' : ($result['error'] !== '' ? $result['error'] : 'Excel webhook returned non-2xx'),
|
||||
'responseBody' => $result['body'],
|
||||
];
|
||||
}
|
||||
|
||||
function find_or_create_party(PDO $pdo, array $data): int
|
||||
{
|
||||
$email = trim((string) ($data['EmailKunde'] ?? ''));
|
||||
@@ -1520,6 +1597,7 @@ try {
|
||||
$pdo->commit();
|
||||
|
||||
$labelTrigger = trigger_shipping_label_flow($data, $env);
|
||||
$excelTrigger = trigger_excel_webhook($pdo, $orderId, $env);
|
||||
|
||||
json_response(200, [
|
||||
'ok' => true,
|
||||
@@ -1529,6 +1607,7 @@ try {
|
||||
'inventory' => $inventory,
|
||||
'inventoryRollback' => $inventoryRollback,
|
||||
'labelTrigger' => $labelTrigger,
|
||||
'excelTrigger' => $excelTrigger,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
|
||||
|
||||
Reference in New Issue
Block a user