prepare("SELECT id FROM public.{$table} WHERE code = :code LIMIT 1"); $stmt->execute([':code' => $code]); $id = $stmt->fetchColumn(); return $id === false ? null : (int) $id; } function map_payment_code(string $input): ?string { $v = strtolower(trim($input)); if ($v === '') { return null; } if (str_contains($v, 'twint')) { return 'twint'; } if (str_contains($v, 'bank') || str_contains($v, 'vorauskasse') || str_contains($v, 'ueberweisung')) { return 'bank_transfer'; } if (str_contains($v, 'kredit') || str_contains($v, 'debit') || str_contains($v, 'card')) { return 'card'; } return null; } function map_shipping_code(string $input): ?string { $v = strtolower(trim($input)); if ($v === '') { return null; } if (str_contains($v, 'abholung') || str_contains($v, 'pickup')) { return 'pickup'; } if (str_contains($v, 'post') || str_contains($v, 'versand')) { return 'post_standard'; } return null; } function ensure_required_tables_exist(PDO $pdo): void { $required = [ 'party', 'address', 'sales_order', 'sales_order_line', 'payment_method', 'shipping_method', ]; $stmt = $pdo->query( "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'" ); $rows = $stmt->fetchAll(PDO::FETCH_COLUMN); $existing = array_map('strval', $rows ?: []); $missing = array_values(array_diff($required, $existing)); if ($missing !== []) { throw new RuntimeException('DB schema not initialized. Missing tables: ' . implode(', ', $missing)); } } function find_existing_order_id(PDO $pdo, string $externalRef): ?int { $stmt = $pdo->prepare('SELECT id FROM sales_order WHERE external_ref = :external_ref LIMIT 1'); $stmt->execute([':external_ref' => $externalRef]); $id = $stmt->fetchColumn(); return $id === false ? null : (int) $id; } function upsert_sales_order(PDO $pdo, array $fields): int { $stmt = $pdo->prepare( 'INSERT INTO public.sales_order ( external_ref, party_id, order_source, order_status, payment_status, payment_method_id, shipping_method_id, amount_net, amount_shipping, amount_tax, amount_discount, total_amount, currency, webhook_payload, imported_at, created_at, updated_at ) VALUES ( :external_ref, :party_id, :order_source, :order_status, :payment_status, :payment_method_id, :shipping_method_id, :amount_net, :amount_shipping, :amount_tax, :amount_discount, :total_amount, :currency, :webhook_payload::jsonb, NOW(), NOW(), NOW() ) ON CONFLICT (external_ref) DO UPDATE SET party_id = EXCLUDED.party_id, order_source = EXCLUDED.order_source, order_status = EXCLUDED.order_status, payment_status = EXCLUDED.payment_status, payment_method_id = EXCLUDED.payment_method_id, shipping_method_id = EXCLUDED.shipping_method_id, amount_net = EXCLUDED.amount_net, amount_shipping = EXCLUDED.amount_shipping, amount_tax = EXCLUDED.amount_tax, amount_discount = EXCLUDED.amount_discount, total_amount = EXCLUDED.total_amount, currency = EXCLUDED.currency, webhook_payload = EXCLUDED.webhook_payload, imported_at = NOW(), updated_at = NOW() RETURNING id' ); $stmt->execute($fields); $id = $stmt->fetchColumn(); if ($id === false) { throw new RuntimeException('Could not upsert order'); } return (int) $id; } function create_direct_sales_order(PDO $pdo, array $fields): array { $stmt = $pdo->prepare( "INSERT INTO sales_order ( external_ref, party_id, order_source, order_status, payment_status, payment_method_id, amount_net, amount_shipping, amount_tax, amount_discount, total_amount, currency, imported_at, created_at, updated_at ) VALUES ( '', :party_id, 'direct', 'imported', 'paid', :payment_method_id, :amount_net, 0, 0, 0, :total_amount, 'CHF', NOW(), NOW(), NOW() ) RETURNING id, external_ref" ); $stmt->execute($fields); $row = $stmt->fetch(); if ($row === false) { throw new RuntimeException('Could not create order'); } return [ 'id' => (int) $row['id'], 'external_ref' => (string) $row['external_ref'], ]; } function delete_sales_order_lines(PDO $pdo, int $orderId): void { $deleteLines = $pdo->prepare('DELETE FROM public.sales_order_line WHERE sales_order_id = :sales_order_id'); $deleteLines->execute([':sales_order_id' => $orderId]); } function insert_sales_order_line(PDO $pdo, array $fields): int { $stmt = $pdo->prepare( 'INSERT INTO public.sales_order_line ( sales_order_id, line_no, sellable_item_id, raw_external_article_number, raw_external_title, qty, unit_price, line_total, created_at, updated_at ) VALUES ( :sales_order_id, :line_no, :sellable_item_id, :article_number, :title, :qty, :unit_price, :line_total, NOW(), NOW() ) RETURNING id' ); $stmt->execute($fields); $id = $stmt->fetchColumn(); if ($id === false) { throw new RuntimeException('Could not insert sales_order_line'); } return (int) $id; }