fix: naprawiono wysyłkę zamówień do Apilo — brakujące $apiloRepository w closurach cron.php
Regresja z ver. 0.339 (split IntegrationsRepository → ApiloRepository): $apiloRepository nie było w use() 5 handlerów cron.php. Dodano retry zamówień z apilo_order_id=-1 co 1h. Dodano powiadomienia mailowe o błędach sync Apilo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
42
cron.php
42
cron.php
@@ -185,7 +185,7 @@ if ( file_exists( $json_queue_path ) )
|
||||
// =========================================================================
|
||||
|
||||
// 1. Apilo token keepalive (priorytet: krytyczny)
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_TOKEN_KEEPALIVE, function($payload) use ($integrationsRepository) {
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_TOKEN_KEEPALIVE, function($payload) use ($integrationsRepository, $apiloRepository) {
|
||||
$apilo_settings = $integrationsRepository->getSettings('apilo');
|
||||
if ( !(int)($apilo_settings['enabled'] ?? 0) ) return true; // skip if disabled
|
||||
|
||||
@@ -195,11 +195,18 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_TOKEN_KEEPALIVE,
|
||||
});
|
||||
|
||||
// 2. Apilo send order (priorytet: wysoki)
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_SEND_ORDER, function($payload) use ($mdb, $integrationsRepository, $orderAdminService, $config) {
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_SEND_ORDER, function($payload) use ($mdb, $integrationsRepository, $apiloRepository, $orderAdminService, $config) {
|
||||
$apilo_settings = $integrationsRepository->getSettings('apilo');
|
||||
if ( !$apilo_settings['enabled'] || !$apilo_settings['sync_orders'] || !$apilo_settings['access-token'] || $apilo_settings['sync_orders_date_start'] > date('Y-m-d H:i:s') ) return true;
|
||||
|
||||
$orders = $mdb->select( 'pp_shop_orders', '*', [ 'AND' => [ 'apilo_order_id' => null, 'date_order[>=]' => $apilo_settings['sync_orders_date_start'] ], 'ORDER' => [ 'date_order' => 'ASC' ], 'LIMIT' => 1 ] );
|
||||
|
||||
// Jeśli brak nowych, ponów failed (-1) z interwałem 1h
|
||||
if ( empty($orders) ) {
|
||||
$retryAfter = date( 'Y-m-d H:i:s', strtotime( '-1 hour' ) );
|
||||
$orders = $mdb->select( 'pp_shop_orders', '*', [ 'AND' => [ 'apilo_order_id' => -1, 'apilo_order_status_date[<=]' => $retryAfter, 'date_order[>=]' => $apilo_settings['sync_orders_date_start'] ], 'ORDER' => [ 'date_order' => 'ASC' ], 'LIMIT' => 1 ] );
|
||||
}
|
||||
|
||||
if ( empty($orders) ) return true;
|
||||
|
||||
foreach ( $orders as $order )
|
||||
@@ -424,6 +431,7 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_SEND_ORDER, func
|
||||
if (curl_errno( $ch ) ) {
|
||||
$curl_error_send = curl_error( $ch );
|
||||
\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 ] );
|
||||
\Shared\Helpers\Helpers::send_email( 'biuro@project-pro.pl', 'Błąd cURL wysyłania zamówienia #' . $order['id'] . ' do apilo.com', 'Zamówienie #' . $order['id'] . ' nie zostało wysłane do Apilo z powodu błędu połączenia (cURL).' . "\n\n" . 'Błąd: ' . $curl_error_send );
|
||||
echo 'Błąd cURL: ' . $curl_error_send;
|
||||
}
|
||||
$http_code_send = (int)curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
||||
@@ -501,8 +509,8 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_SEND_ORDER, func
|
||||
}
|
||||
elseif ( $http_code_send >= 400 || !isset( $response['id'] ) )
|
||||
{
|
||||
$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 ] );
|
||||
$mdb->update( 'pp_shop_orders', [ 'apilo_order_id' => -1, 'apilo_order_status_date' => date('Y-m-d H:i:s') ], [ '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 . ') — ponowna próba za 1h', [ '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 );
|
||||
@@ -550,7 +558,7 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_SYNC_STATUS, fun
|
||||
});
|
||||
|
||||
// 5. Apilo product sync
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRODUCT_SYNC, function($payload) use ($mdb, $integrationsRepository) {
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRODUCT_SYNC, function($payload) use ($mdb, $integrationsRepository, $apiloRepository) {
|
||||
$apilo_settings = $integrationsRepository->getSettings('apilo');
|
||||
if ( !$apilo_settings['enabled'] || !$apilo_settings['sync_products'] || !$apilo_settings['access-token'] ) return true;
|
||||
|
||||
@@ -583,7 +591,7 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRODUCT_SYNC, fu
|
||||
});
|
||||
|
||||
// 6. Apilo pricelist sync
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRICELIST_SYNC, function($payload) use ($mdb, $integrationsRepository) {
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRICELIST_SYNC, function($payload) use ($mdb, $integrationsRepository, $apiloRepository) {
|
||||
$apilo_settings = $integrationsRepository->getSettings('apilo');
|
||||
if ( !$apilo_settings['enabled'] || !$apilo_settings['access-token'] ) return true;
|
||||
|
||||
@@ -629,7 +637,7 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::APILO_PRICELIST_SYNC,
|
||||
});
|
||||
|
||||
// 7. Apilo status poll
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_STATUS_POLL, function($payload) use ($mdb, $integrationsRepository, $orderRepo, $orderAdminService) {
|
||||
$processor->registerHandler( \Domain\CronJob\CronJobType::APILO_STATUS_POLL, function($payload) use ($mdb, $integrationsRepository, $apiloRepository, $orderRepo, $orderAdminService) {
|
||||
$apilo_settings = $integrationsRepository->getSettings('apilo');
|
||||
if ( !$apilo_settings['enabled'] || !$apilo_settings['sync_orders'] || !$apilo_settings['access-token'] ) return true;
|
||||
|
||||
@@ -752,5 +760,25 @@ $processor->registerHandler( \Domain\CronJob\CronJobType::TRUSTMATE_INVITATION,
|
||||
|
||||
$result = $processor->run( 20 );
|
||||
|
||||
// Powiadomienie mailowe o trwale nieudanych zadaniach Apilo
|
||||
$failedApiloJobs = $mdb->select('pp_cron_jobs', ['id', 'job_type', 'last_error', 'payload', 'attempts', 'completed_at'], [
|
||||
'AND' => [
|
||||
'status' => 'failed',
|
||||
'job_type[~]' => 'apilo_%',
|
||||
'completed_at[>=]' => date('Y-m-d H:i:s', time() - 120),
|
||||
]
|
||||
]);
|
||||
if (!empty($failedApiloJobs)) {
|
||||
$emailBody = "Następujące zadania Apilo zakończyły się trwałym błędem (wyczerpano limit prób):\n\n";
|
||||
foreach ($failedApiloJobs as $fj) {
|
||||
$emailBody .= "Job #" . $fj['id'] . " (" . $fj['job_type'] . ")\n";
|
||||
$emailBody .= " Payload: " . $fj['payload'] . "\n";
|
||||
$emailBody .= " Próby: " . $fj['attempts'] . "\n";
|
||||
$emailBody .= " Błąd: " . $fj['last_error'] . "\n";
|
||||
$emailBody .= " Data: " . $fj['completed_at'] . "\n\n";
|
||||
}
|
||||
\Shared\Helpers\Helpers::send_email('biuro@project-pro.pl', 'shopPRO: Trwały błąd synchronizacji Apilo (' . count($failedApiloJobs) . ' zadań)', $emailBody);
|
||||
}
|
||||
|
||||
echo '<hr>';
|
||||
echo '<p><small>CronJob stats: scheduled=' . $result['scheduled'] . ', processed=' . $result['processed'] . ', succeeded=' . $result['succeeded'] . ', failed=' . $result['failed'] . ', skipped=' . $result['skipped'] . '</small></p>';
|
||||
|
||||
Reference in New Issue
Block a user