From 842ed77f5ba4c1b5e2de49449ec56d96ff46b52c Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Mon, 23 Feb 2026 11:11:28 +0100 Subject: [PATCH] =?UTF-8?q?ver.=200.312:=20fix=20krytycznych=20bug=C3=B3w?= =?UTF-8?q?=20integracji=20Apilo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - curl_getinfo() po curl_close() dawał HTTP 0 — przeniesienie przed close - nieskończona pętla wysyłki zamówienia przy błędzie serwera Apilo (apilo_order_id = -1) - ceny 0.00 PLN — string "0.00" z MySQL jest truthy, zmiana na (float) > 0 - walidacja zerowych cen przed wysyłką (apilo_order_id = -2) - niezainicjalizowana $order_message Co-Authored-By: Claude Opus 4.6 --- cron.php | 40 +++++++++++++++++++++++++++++++++++++--- docs/CHANGELOG.md | 10 ++++++++++ updates/versions.php | 2 +- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cron.php b/cron.php index 3b42f59..14fc28b 100644 --- a/cron.php +++ b/cron.php @@ -201,6 +201,7 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se { $products = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order['id'] ] ); $products_array = []; + $order_message = ''; foreach ( $products as $product ) { $productRepo = new \Domain\Product\ProductRepository( $mdb ); @@ -211,8 +212,8 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se 'ean' => $productRepo->getEanWithFallback( (int)$product['product_id'], true ), 'sku' => $sku ? $sku : md5( $product['product_id'] ), 'originalName' => $product['name'], - 'originalPriceWithTax' => $product['price_brutto_promo'] ? str_replace( ',', '.', $product['price_brutto_promo'] ) : str_replace( ',', '.', $product['price_brutto'] ), - 'originalPriceWithoutTax' => $product['price_brutto_promo'] ? str_replace( ',', '.', round( $product['price_brutto_promo'] / ( 1 + $product['vat']/100 ), 2 ) ) : str_replace( ',', '.', round( $product['price_brutto'] / ( 1 + $product['vat']/100 ), 2 ) ), + 'originalPriceWithTax' => (float)$product['price_brutto_promo'] > 0 ? str_replace( ',', '.', $product['price_brutto_promo'] ) : str_replace( ',', '.', $product['price_brutto'] ), + 'originalPriceWithoutTax' => (float)$product['price_brutto_promo'] > 0 ? str_replace( ',', '.', round( $product['price_brutto_promo'] / ( 1 + $product['vat']/100 ), 2 ) ) : str_replace( ',', '.', round( $product['price_brutto'] / ( 1 + $product['vat']/100 ), 2 ) ), 'quantity' => $product['quantity'], 'tax' => number_format( $product['vat'], 2, '.', '' ), 'status' => 1, @@ -255,6 +256,25 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se 'media' => null ]; + // Walidacja: sprawdź czy zamówienie ma produkty z cenami > 0 + $has_priced_products = false; + foreach ( $products_array as $pa ) + { + if ( $pa['type'] == 1 && (float)$pa['originalPriceWithTax'] > 0 ) + { + $has_priced_products = true; + break; + } + } + if ( !$has_priced_products ) + { + \Domain\Integrations\ApiloLogger::log( $mdb, 'send_order', (int)$order['id'], 'Pominięto zamówienie - wszystkie produkty mają cenę 0.00', [ 'products' => $products_array ] ); + \Shared\Helpers\Helpers::send_email( 'biuro@project-pro.pl', 'Apilo: zamówienie #' . $order['id'] . ' ma zerowe ceny produktów', 'Zamówienie #' . $order['id'] . ' nie zostało wysłane do Apilo, ponieważ wszystkie produkty mają cenę 0.00 PLN. Sprawdź zamówienie w panelu sklepu.' ); + $mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => -2 ], [ 'id' => $order['id'] ] ); + echo '

Pominięto zamówienie #' . $order['id'] . ' - zerowe ceny produktów

'; + continue; + } + $access_token = $integrationsRepository -> apiloGetAccessToken(); $order_date = new DateTime( $order['date_order'] ); @@ -410,9 +430,9 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se \Domain\Integrations\ApiloLogger::log( $mdb, 'send_order', (int)$order['id'], 'Błąd cURL przy wysyłaniu zamówienia: ' . $curl_error_send, [ 'curl_error' => $curl_error_send ] ); echo 'Błąd cURL: ' . $curl_error_send; } + $http_code_send = (int)curl_getinfo( $ch, CURLINFO_HTTP_CODE ); curl_close( $ch ); - $http_code_send = (int)curl_getinfo( $ch, CURLINFO_HTTP_CODE ); $response = json_decode( $response, true ); if ( $config['debug']['apilo'] ) @@ -497,6 +517,20 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se \Shared\Helpers\Helpers::send_email( 'biuro@project-pro.pl', 'Błąd wysyłania zamówienia do apilo.com', $email_data ); } } + elseif ( $http_code_send >= 400 || !isset( $response['id'] ) ) + { + // Błąd serwera lub brak ID w odpowiedzi — logujemy i pomijamy, NIE ustawiamy apilo_order_id + // żeby zamówienie nie wpadło w nieskończoną pętlę, ustawiamy apilo_order_id na -1 (błąd) + $mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => -1 ], [ 'id' => $order['id'] ] ); + \Domain\Integrations\ApiloLogger::log( $mdb, 'send_order', (int)$order['id'], 'Błąd wysyłania zamówienia do Apilo (HTTP ' . $http_code_send . ')', [ 'http_code' => $http_code_send, 'response' => $response ] ); + + $email_data = 'HTTP Code: ' . $http_code_send . "\n\n"; + $email_data .= print_r( $response, true ); + $email_data .= print_r( $postData, true ); + \Shared\Helpers\Helpers::send_email( 'biuro@project-pro.pl', 'Błąd wysyłania zamówienia #' . $order['id'] . ' do apilo.com (HTTP ' . $http_code_send . ')', $email_data ); + + echo '

Błąd wysyłania zamówienia do apilo.com: ID: ' . $order['id'] . ' (HTTP ' . $http_code_send . ')

'; + } else { $mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => $response['id'] ], [ 'id' => $order['id'] ] ); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2c0739f..758e15b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,16 @@ Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze. --- +## ver. 0.312 (2026-02-23) - Fix krytycznych bugów integracji Apilo + +- **FIX**: `curl_getinfo()` wywoływane po `curl_close()` — HTTP code zawsze wynosił 0, uniemożliwiając prawidłową obsługę odpowiedzi Apilo +- **FIX**: Nieskończona pętla wysyłania zamówienia — gdy Apilo zwracało błąd serwera, zamówienie nie dostawało `apilo_order_id` i było ponownie wybierane w każdym cyklu crona. Teraz błędne zamówienia oznaczane `apilo_order_id = -1` z powiadomieniem email +- **FIX**: Ceny produktów 0.00 PLN w Apilo — string `"0.00"` z MySQL jest truthy w PHP, więc ternary wybierał `price_brutto_promo` (0.00) zamiast `price_brutto`. Zmiana na `(float)... > 0` +- **FIX**: Walidacja cen przed wysyłką — zamówienia z zerowymi cenami produktów nie są wysyłane do Apilo (`apilo_order_id = -2`) z powiadomieniem email +- **FIX**: Niezainicjalizowana zmienna `$order_message` powodująca PHP warning + +--- + ## ver. 0.311 (2026-02-23) - Fix race condition Apilo + persistence filtrów + poprawki cen - **FIX**: Race condition — callback płatności przed wysłaniem zamówienia do Apilo nie synchronizował płatności (task trafiał w pustkę). Teraz `syncApiloPaymentIfNeeded` i `syncApiloStatusIfNeeded` kolejkują sync do retry gdy `apilo_order_id` jeszcze nie istnieje diff --git a/updates/versions.php b/updates/versions.php index d15c6c1..48601a5 100644 --- a/updates/versions.php +++ b/updates/versions.php @@ -1,5 +1,5 @@