Full migration of front\factory\ — entire directory removed (all 20 classes migrated). ProductRepository +20 frontend methods, PromotionRepository +5 applyType methods, TransportRepository +4 cached methods, PaymentMethodRepository +cached frontend methods. Fix: broken transports_list() in ajax.php replaced with forPaymentMethod(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
587 lines
25 KiB
PHP
587 lines
25 KiB
PHP
<?php
|
|
use shop\Order;
|
|
|
|
error_reporting( E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED );
|
|
|
|
function __autoload_my_classes( $classname )
|
|
{
|
|
$q = explode( '\\', $classname );
|
|
$c = array_pop( $q );
|
|
$f = 'autoload/' . implode( '/', $q ) . '/class.' . $c . '.php';
|
|
|
|
if ( file_exists( $f ) )
|
|
require_once( $f );
|
|
else
|
|
{
|
|
$f = 'autoload/' . implode( '/', $q ) . '/' . $c . '.php';
|
|
if ( file_exists( $f ) )
|
|
require_once( $f );
|
|
}
|
|
}
|
|
|
|
spl_autoload_register( '__autoload_my_classes' );
|
|
date_default_timezone_set( 'Europe/Warsaw' );
|
|
|
|
require_once 'config.php';
|
|
require_once 'libraries/medoo/medoo.php';
|
|
require_once 'libraries/phpmailer/class.phpmailer.php';
|
|
require_once 'libraries/phpmailer/class.smtp.php';
|
|
|
|
session_start();
|
|
|
|
if ( !isset( $_SESSION[ 'check' ] ) )
|
|
{
|
|
session_regenerate_id();
|
|
$_SESSION[ 'check' ] = true;
|
|
$_SESSION[ 'ip' ] = $_SERVER[ 'REMOTE_ADDR' ];
|
|
}
|
|
|
|
if ( $_SESSION[ 'ip' ] !== $_SERVER[ 'REMOTE_ADDR' ] )
|
|
{
|
|
session_destroy();
|
|
header( 'Location: /' );
|
|
exit;
|
|
}
|
|
|
|
$mdb = new medoo( [
|
|
'database_type' => 'mysql',
|
|
'database_name' => $database[ 'name' ],
|
|
'server' => $database[ 'host' ],
|
|
'username' => $database[ 'user' ],
|
|
'password' => $database[ 'password' ],
|
|
'charset' => 'utf8'
|
|
] );
|
|
|
|
$settings = ( new \Domain\Settings\SettingsRepository( $mdb ) )->allSettings();
|
|
$integrationsRepository = new \Domain\Integrations\IntegrationsRepository( $mdb );
|
|
$apilo_settings = $integrationsRepository -> getSettings( 'apilo' );
|
|
|
|
// Keepalive tokenu Apilo: odswiezaj token przed wygasnieciem, zeby integracja byla stale aktywna.
|
|
if ( (int)($apilo_settings['enabled'] ?? 0) === 1 ) {
|
|
$integrationsRepository -> apiloKeepalive( 300 );
|
|
$apilo_settings = $integrationsRepository -> getSettings( 'apilo' );
|
|
Order::process_apilo_sync_queue( 10 );
|
|
}
|
|
|
|
function parsePaczkomatAddress($input)
|
|
{
|
|
$pattern = '/^([\w-]+)\s+\|\s+([^,]+),\s+(\d{2}-\d{3})\s+(.+)$/';
|
|
|
|
if (preg_match($pattern, $input, $matches)) {
|
|
return [
|
|
'code' => $matches[1],
|
|
'address' => $matches[2],
|
|
'postalCode' => $matches[3],
|
|
'city' => $matches[4],
|
|
];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function parseOrlenAddress( $input )
|
|
{
|
|
$pattern = '/^([^\|]+)\s*\|\s*([^,]+),\s*(.+?)\s+(\d{2}-\d{3})$/';
|
|
if (preg_match($pattern, $input, $matches)) {
|
|
return [
|
|
'code' => trim($matches[1]),
|
|
'address' => trim($matches[2]),
|
|
'city' => trim($matches[3]),
|
|
'postalCode' => trim($matches[4]),
|
|
];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function getImageUrlById($id) {
|
|
$apiUrl = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . '/api/v1/product.php';
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $apiUrl . '?id=' . urlencode($id));
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
|
'Content-Type: application/json',
|
|
));
|
|
|
|
$response = curl_exec($ch);
|
|
if ($response === false) {
|
|
curl_close($ch);
|
|
return null;
|
|
}
|
|
|
|
curl_close($ch);
|
|
|
|
$data = json_decode($response, true);
|
|
|
|
return isset($data['img']) ? $data['img'] : null;
|
|
}
|
|
|
|
// pobieranie informacji o produkcie z apilo.com
|
|
if ( $apilo_settings['enabled'] and $apilo_settings['sync_products'] and $apilo_settings['access-token'] )
|
|
{
|
|
if ( $result = $mdb -> query( 'SELECT id, apilo_product_id, apilo_get_data_date, apilo_product_name FROM pp_shop_products WHERE apilo_product_id IS NOT NULL AND apilo_product_id != 0 AND ( apilo_get_data_date IS NULL OR apilo_get_data_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-10 minutes', time() ) ) . '\' ) ORDER BY apilo_get_data_date ASC LIMIT 1' ) -> fetch( \PDO::FETCH_ASSOC ) )
|
|
{
|
|
$access_token = $integrationsRepository -> apiloGetAccessToken();
|
|
$url = 'https://projectpro.apilo.com/rest/api/warehouse/product/' . $result['apilo_product_id'] . '/';
|
|
$curl = curl_init( $url );
|
|
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
|
|
curl_setopt( $curl, CURLOPT_HTTPHEADER, [
|
|
"Authorization: Bearer " . $access_token,
|
|
"Accept: application/json"
|
|
] );
|
|
|
|
$response = curl_exec( $curl );
|
|
$responseData = json_decode( $response, true );
|
|
|
|
// aktualizowanie stanu magazynowego
|
|
$mdb -> update( 'pp_shop_products', [ 'quantity' => $responseData['quantity'] ], [ 'apilo_product_id' => $result['apilo_product_id'] ] );
|
|
// aktualizowanie ceny
|
|
$mdb -> update( 'pp_shop_products', [ 'price_netto' => \Shared\Helpers\Helpers::normalize_decimal( $responseData['priceWithoutTax'], 2 ), 'price_brutto' => \Shared\Helpers\Helpers::normalize_decimal( $responseData['priceWithTax'], 2 ) ], [ 'apilo_product_id' => $result['apilo_product_id'] ] );
|
|
|
|
$mdb -> update( 'pp_shop_products', [ 'apilo_get_data_date' => date( 'Y-m-d H:i:s' ) ], [ 'apilo_product_id' => $result['apilo_product_id'] ] );
|
|
|
|
// Czyszczenie cache produktu
|
|
\Shared\Helpers\Helpers::clear_product_cache( (int)$result['id'] );
|
|
|
|
echo '<p>Zaktualizowałem dane produktu (APILO) <b>' . $result['apilo_product_name'] . ' #' . $result['id'] . '</b></p>';
|
|
}
|
|
}
|
|
|
|
// synchronizacja cen apilo.com
|
|
if ( $apilo_settings['enabled'] and $apilo_settings['access-token'] and ( !$apilo_settings['pricelist_update_date'] or $apilo_settings['pricelist_update_date'] <= date( 'Y-m-d H:i:s', strtotime( '-1 hour', time() ) ) ) )
|
|
{
|
|
$access_token = $integrationsRepository -> apiloGetAccessToken();
|
|
|
|
$url = 'https://projectpro.apilo.com/rest/api/warehouse/price-calculated/?price=' . $apilo_settings['pricelist_id'];
|
|
|
|
$curl = curl_init( $url );
|
|
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
|
|
curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, "GET" );
|
|
curl_setopt( $curl, CURLOPT_HTTPHEADER, [
|
|
"Authorization: Bearer " . $access_token,
|
|
"Accept: application/json",
|
|
"Content-Type: application/json"
|
|
] );
|
|
|
|
$response = curl_exec( $curl );
|
|
$responseData = json_decode( $response, true );
|
|
|
|
if ( $responseData['list'] )
|
|
{
|
|
foreach ( $responseData['list'] as $product_price )
|
|
{
|
|
//aktualizowanie ceny
|
|
if ( $product_price['customPriceWithTax'] )
|
|
{
|
|
$price_brutto = $product_price['customPriceWithTax'];
|
|
$vat = $vat = $mdb -> get( 'pp_shop_products', 'vat', [ 'apilo_product_id' => $result['apilo_product_id'] ] );
|
|
$price_netto = $price_brutto / ( ( 100 + $vat ) / 100 );
|
|
|
|
$mdb -> update( 'pp_shop_products', [ 'price_netto' => \Shared\Helpers\Helpers::normalize_decimal( $price_netto, 2 ), 'price_brutto' => \Shared\Helpers\Helpers::normalize_decimal( $price_brutto, 2 ) ], [ 'apilo_product_id' => $product_price['product'] ] );
|
|
$product_id = $mdb -> get( 'pp_shop_products', 'id', [ 'apilo_product_id' => $product_price['product'] ] );
|
|
|
|
( new \Domain\Product\ProductRepository( $mdb ) )->updateCombinationPricesFromBase( (int)$product_id, $price_brutto, $vat, null );
|
|
|
|
// Czyszczenie cache produktu
|
|
\Shared\Helpers\Helpers::clear_product_cache( (int)$product_id );
|
|
}
|
|
}
|
|
}
|
|
$integrationsRepository -> saveSetting( 'apilo', 'pricelist_update_date', date( 'Y-m-d H:i:s' ) );
|
|
echo '<p>Zaktualizowałem ceny produktów (APILO)</p>';
|
|
}
|
|
|
|
// wysyłanie zamówień do apilo
|
|
if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_settings['access-token'] and $apilo_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) )
|
|
{
|
|
$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 ] );
|
|
foreach ( $orders as $order )
|
|
{
|
|
$products = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order['id'] ] );
|
|
$products_array = [];
|
|
foreach ( $products as $product )
|
|
{
|
|
$productRepo = new \Domain\Product\ProductRepository( $mdb );
|
|
$sku = $productRepo->getSkuWithFallback( (int)$product['product_id'], true );
|
|
|
|
$products_array[] = [
|
|
'idExternal' => $product['product_id'],
|
|
'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 ) ),
|
|
'quantity' => $product['quantity'],
|
|
'tax' => number_format( $product['vat'], 2, '.', '' ),
|
|
'status' => 1,
|
|
'type' => 1,
|
|
'media' => $product['message']
|
|
];
|
|
|
|
$order_message .= '<table>';
|
|
$order_message .= '<tr>';
|
|
$order_message .= '<td style="width: 150px; vertical-align: middle; text-align: center;">';
|
|
$order_message .= '<img src="' . getImageUrlById( $product['parent_product_id'] ) . '" style="width: 150px;" alt="">';
|
|
$order_message .= '</td>';
|
|
$order_message .= '<td style="vertical-align: middle;">';
|
|
$order_message .= '<strong>' . $product['name'] . '</strong><br>';
|
|
$order_message .= strip_tags( $product['attributes'] ) . '<br>';
|
|
$order_message .= preg_replace( '/\s+/', ' ', htmlspecialchars( $product['message'] ) ) . '<br>';
|
|
$order_message .= strip_tags( str_replace( '<br>', ' | ', preg_replace( '/\s+/', ' ', $product['custom_fields'] ) ) ) . '<br>';
|
|
$order_message .= '</td>';
|
|
$order_message .= '</tr>';
|
|
$order_message .= '</table>';
|
|
$order_message .= '<hr>';
|
|
}
|
|
|
|
//TODO: ostatnio był problem kiedy wiadomość miała mniej 1024 znaki ale zawierała przeniesienie tekstu '<br>' i do tego jeszcze miała emoji. Wtedy APILO tego nie przepuszczał.
|
|
if ( strlen( $order_message ) > 850 )
|
|
$order_message = '<p><strong>Wiadomość do zamówienia była zbyt długa. Sprawdź szczegóły w panelu sklepu</strong></p>';
|
|
|
|
// add transport as product
|
|
$products_array[] = [
|
|
'idExternal' => '',
|
|
'ean' => null,
|
|
'sku' => '',
|
|
'originalName' => strip_tags( $order['transport'] ),
|
|
'originalPriceWithTax' => str_replace( ',', '.', $order['transport_cost'] ),
|
|
'originalPriceWithoutTax' => str_replace( ',', '.', round( $order['transport_cost'] / ( 1 + 23/100 ), 2 ) ),
|
|
'quantity' => 1,
|
|
'tax' => number_format( 23, 2, '.', '' ),
|
|
'status' => 1,
|
|
'type' => 2,
|
|
'media' => null
|
|
];
|
|
|
|
$access_token = $integrationsRepository -> apiloGetAccessToken();
|
|
|
|
$order_date = new DateTime( $order['date_order'] );
|
|
|
|
$paczkomatData = parsePaczkomatAddress( $order['inpost_paczkomat'] );
|
|
$orlenPointData = parseOrlenAddress( $order['orlen_point'] );
|
|
|
|
$street = '';
|
|
$city = '';
|
|
$postal_code = '';
|
|
|
|
if ( $order['client_street'] )
|
|
$street = $order['client_street'];
|
|
else if ( $paczkomatData )
|
|
$street = $paczkomatData['address'];
|
|
else if ( $orlenPointData )
|
|
$street = $orlenPointData['address'];
|
|
else if ( $order['transport_id'] == 3 or ( $order['transport_id'] == 9 and $order['orlen_point'] == null ) )
|
|
$street = 'ul. Krakowska 156/104';
|
|
|
|
if ( $order['client_city'] )
|
|
$city = $order['client_city'];
|
|
else if ( $paczkomatData )
|
|
$city = $paczkomatData['city'];
|
|
else if ( $orlenPointData )
|
|
$city = $orlenPointData['city'];
|
|
else if ( $order['transport_id'] == 3 or ( $order['transport_id'] == 9 and $order['orlen_point'] == null ) )
|
|
$city = 'Rzeszów';
|
|
|
|
if ( $order['client_postal_code'] )
|
|
$postal_code = $order['client_postal_code'];
|
|
else if ( $paczkomatData )
|
|
$postal_code = $paczkomatData['postalCode'];
|
|
else if ( $orlenPointData )
|
|
$postal_code = $orlenPointData['postalCode'];
|
|
else if ( $order['transport_id'] == 3 or ( $order['transport_id'] == 9 and $order['orlen_point'] == null ) )
|
|
$postal_code = '35-506';
|
|
|
|
if ( $order['transport_id'] == 9 and $order['orlen_point'] == null )
|
|
{
|
|
\Shared\Helpers\Helpers::send_email( 'biuro@project-pro.pl', 'Błąd integracji APILO - brak punktu ORLEN PACZKA', 'W zamówieniu #' . $order['id'] . ' wybrano dostawę ORLEN PACZKA, ale nie podano punktu odbioru. Proszę o uzupełnienie danych w panelu sklepu.' );
|
|
}
|
|
|
|
$postData = [
|
|
'idExternal' => $order['id'],
|
|
'isInvoice' => $order['firm_name'] ? true : false,
|
|
'customerLogin' => $order['client_email'],
|
|
'paymentType' => (int)( new \Domain\PaymentMethod\PaymentMethodRepository( $mdb ) )->getApiloPaymentTypeId( (int)$order['payment_method_id'] ),
|
|
'originalCurrency' => 'PLN',
|
|
'originalAmountTotalWithTax' => str_replace( ',', '.', $order['summary'] ),
|
|
'orderItems' => $products_array,
|
|
'orderedAt' => $order_date -> format('Y-m-d\TH:i:s\Z'),
|
|
'addressCustomer' => [
|
|
'name' => $order['client_name'] . ' ' . $order['client_surname'],
|
|
'phone' => $order['client_phone'],
|
|
'email' => $order['client_email'],
|
|
'streetName' => $street,
|
|
'city' => $city,
|
|
'zipCode' => $postal_code
|
|
],
|
|
'addressDelivery' => [
|
|
'name' => $order['client_name'] . ' ' . $order['client_surname'],
|
|
'phone' => $order['client_phone'],
|
|
'email' => $order['client_email'],
|
|
'streetName' => $street,
|
|
'city' => $city,
|
|
'zipCode' => $postal_code
|
|
],
|
|
'carrierAccount' => (int)( new \Domain\Transport\TransportRepository( $mdb ) )->getApiloCarrierAccountId( (int)$order['transport_id'] ),
|
|
'orderNotes' => [ [
|
|
'type' => 1,
|
|
'comment' => 'Wiadomość do zamówienia:<br>' . $order['message'] . '<br><br>' . $order_message
|
|
] ],
|
|
'status' => (int)( new \Domain\ShopStatus\ShopStatusRepository( $mdb ) )->getApiloStatusId( (int)$order['status'] ),
|
|
'platformId' => $apilo_settings['platform-id']
|
|
];
|
|
|
|
if ( $order['firm_name'] )
|
|
{
|
|
$postData['addressInvoice']['name'] = $order['firm_name'];
|
|
$postData['addressInvoice']['streetName'] = $order['firm_street'];
|
|
$postData['addressInvoice']['city'] = $order['firm_city'];
|
|
$postData['addressInvoice']['zipCode'] = $order['firm_postal_code'];
|
|
$postData['addressInvoice']['companyTaxNumber'] = $order['firm_nip'];
|
|
}
|
|
|
|
// jeżeli paczkomat
|
|
if ( $order['inpost_paczkomat'] )
|
|
{
|
|
$postData['addressDelivery']['parcelName'] = $order['inpost_paczkomat'] ? 'Paczkomat: ' . $order['inpost_paczkomat'] : null;
|
|
$postData['addressDelivery']['parcelIdExternal'] = $order['inpost_paczkomat'] ? ( $paczkomat = trim( explode( '|', $order['inpost_paczkomat'] )[0] ) ) : null;
|
|
|
|
if ( !$postData['addressDelivery']['zipCode'] or !$postData['addressDelivery']['city'] )
|
|
{
|
|
preg_match("/\b\d{2}-\d{3}\b/", $order['inpost_paczkomat'], $postalCodeMatches);
|
|
$postalCode = $postalCodeMatches[0] ?? '';
|
|
|
|
$cityPattern = "/\d{2}-\d{3}\s+(.+)/";
|
|
preg_match($cityPattern, $order['inpost_paczkomat'], $cityMatches);
|
|
$city = $cityMatches[1] ?? '';
|
|
|
|
$postData['addressDelivery']['zipCode'] = $postalCode;
|
|
$postData['addressDelivery']['city'] = $city;
|
|
}
|
|
}
|
|
|
|
// jeżeli orlen paczka
|
|
if ( $order['orlen_point'] )
|
|
{
|
|
$postData['addressDelivery']['parcelName'] = $order['orlen_point'] ? 'Automat ORLEN ' . $order['orlen_point'] : null;
|
|
$postData['addressDelivery']['parcelIdExternal'] = $order['orlen_point'] ? ( $parcelId = trim( explode( '-', $order['orlen_point'] )[1] ) ) : null;
|
|
|
|
if ( !$postData['addressDelivery']['zipCode'] or !$postData['addressDelivery']['city'] )
|
|
{
|
|
preg_match("/\b\d{2}-\d{3}\b/", $order['orlen_point'], $postalCodeMatches);
|
|
$postalCode = $postalCodeMatches[0] ?? '';
|
|
|
|
$cityPattern = "/\d{2}-\d{3}\s+(.+)/";
|
|
preg_match($cityPattern, $order['orlen_point'], $cityMatches);
|
|
$city = $cityMatches[1] ?? '';
|
|
|
|
$postData['addressDelivery']['zipCode'] = $postalCode;
|
|
$postData['addressDelivery']['city'] = $city;
|
|
}
|
|
|
|
}
|
|
|
|
if ( $order['paid'] )
|
|
{
|
|
$payment_date = new DateTime( $order['date_order'] );
|
|
|
|
$postData['orderPayments'][] = [
|
|
'amount' => str_replace( ',', '.', $order['summary'] ),
|
|
'paymentDate' => $payment_date -> format('Y-m-d\TH:i:s\Z'),
|
|
'type' => ( new \Domain\PaymentMethod\PaymentMethodRepository( $mdb ) )->getApiloPaymentTypeId( (int)$order['payment_method_id'] )
|
|
];
|
|
}
|
|
|
|
$ch = curl_init();
|
|
curl_setopt( $ch, CURLOPT_URL, "https://projectpro.apilo.com/rest/api/orders/" );
|
|
curl_setopt( $ch, CURLOPT_POST, 1 );
|
|
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $postData ) );
|
|
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
|
|
"Authorization: Bearer " . $access_token,
|
|
"Accept: application/json",
|
|
"Content-Type: application/json"
|
|
));
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
|
$response = curl_exec( $ch );
|
|
if (curl_errno( $ch ) ) {
|
|
echo 'Błąd cURL: ' . curl_error( $ch );
|
|
}
|
|
curl_close( $ch );
|
|
|
|
$response = json_decode( $response, true );
|
|
|
|
if ( $config['debug']['apilo'] )
|
|
{
|
|
file_put_contents( $_SERVER['DOCUMENT_ROOT'] . '/logs/apilo.txt', date( 'Y-m-d H:i:s' ) . " --- SEND ORDER TO APILO\n\n", FILE_APPEND );
|
|
file_put_contents( $_SERVER['DOCUMENT_ROOT'] . '/logs/apilo.txt', print_r( $postData, true ) . "\n\n", FILE_APPEND );
|
|
file_put_contents( $_SERVER['DOCUMENT_ROOT'] . '/logs/apilo.txt', print_r( $response, true ) . "\n\n", FILE_APPEND );
|
|
}
|
|
|
|
if ( $response['message'] == 'Order already exists' )
|
|
{
|
|
$apilo_order_id = str_replace( 'Order id: ', '', $response['description'] );
|
|
$mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => $apilo_order_id ], [ 'id' => $order['id'] ] );
|
|
echo '<p>Zaktualizowałem id zamówienia na podstawie zamówienia apilo.com</p>';
|
|
}
|
|
elseif ( $response['message'] == 'Validation error' )
|
|
{
|
|
// sprawdzanie czy błąd dotyczy duplikatu idExternal
|
|
$is_duplicate_idexternal = false;
|
|
if ( isset( $response['errors'] ) and is_array( $response['errors'] ) )
|
|
{
|
|
foreach ( $response['errors'] as $error )
|
|
{
|
|
if ( isset( $error['field'] ) and $error['field'] == 'idExternal' and
|
|
( strpos( $error['message'], 'już wykorzystywana' ) !== false or
|
|
strpos( $error['message'], 'already' ) !== false ) )
|
|
{
|
|
$is_duplicate_idexternal = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $is_duplicate_idexternal )
|
|
{
|
|
// próba pobrania zamówienia z Apilo na podstawie idExternal
|
|
$ch_get = curl_init();
|
|
curl_setopt( $ch_get, CURLOPT_URL, "https://projectpro.apilo.com/rest/api/orders/?idExternal=" . $order['id'] );
|
|
curl_setopt( $ch_get, CURLOPT_RETURNTRANSFER, true );
|
|
curl_setopt( $ch_get, CURLOPT_HTTPHEADER, array(
|
|
"Authorization: Bearer " . $access_token,
|
|
"Accept: application/json"
|
|
));
|
|
$get_response = curl_exec( $ch_get );
|
|
curl_close( $ch_get );
|
|
|
|
$get_response_data = json_decode( $get_response, true );
|
|
|
|
if ( isset( $get_response_data['list'] ) and count( $get_response_data['list'] ) > 0 )
|
|
{
|
|
$apilo_order_id = $get_response_data['list'][0]['id'];
|
|
$mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => $apilo_order_id ], [ 'id' => $order['id'] ] );
|
|
echo '<p>Zamówienie już istnieje w Apilo. Zaktualizowano ID zamówienia: ' . $apilo_order_id . '</p>';
|
|
}
|
|
else
|
|
{
|
|
echo '<pre>';
|
|
echo print_r( $response, true );
|
|
echo print_r( $postData, true );
|
|
echo '</pre>';
|
|
|
|
$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 do apilo.com - nie znaleziono zamówienia', $email_data );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo '<pre>';
|
|
echo print_r( $response, true );
|
|
echo print_r( $postData, true );
|
|
echo '</pre>';
|
|
|
|
$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 do apilo.com', $email_data );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$mdb -> update( 'pp_shop_orders', [ 'apilo_order_id' => $response['id'] ], [ 'id' => $order['id'] ] );
|
|
echo '<p>Wysłałem zamówienie do apilo.com: ID: ' . $order['id'] . ' - ' . $response['id'] . '</p>';
|
|
}
|
|
}
|
|
}
|
|
|
|
// sprawdzanie statusów zamówień w apilo.com jeżeli zamówienie nie jest zrealizowane, anulowane lub nieodebrane
|
|
if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_settings['access-token'] and $apilo_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) )
|
|
{
|
|
$orders = $mdb -> query( 'SELECT id, apilo_order_id, apilo_order_status_date, number FROM pp_shop_orders WHERE apilo_order_id IS NOT NULL AND ( status != 6 AND status != 8 AND status != 9 ) AND ( apilo_order_status_date IS NULL OR apilo_order_status_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-10 minutes', time() ) ) . '\' ) ORDER BY apilo_order_status_date ASC LIMIT 5' ) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
foreach ( $orders as $order )
|
|
{
|
|
if ( $order['apilo_order_id'] )
|
|
{
|
|
$access_token = $integrationsRepository -> apiloGetAccessToken();
|
|
$url = 'https://projectpro.apilo.com/rest/api/orders/' . $order['apilo_order_id'] . '/';
|
|
|
|
$ch = curl_init( $url );
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
|
|
"Authorization: Bearer " . $access_token,
|
|
"Accept: application/json"
|
|
] );
|
|
|
|
$response = curl_exec( $ch );
|
|
$responseData = json_decode( $response, true );
|
|
|
|
if ( $responseData['id'] and $responseData['status'] )
|
|
{
|
|
$shop_status_id = ( new \Domain\ShopStatus\ShopStatusRepository( $mdb ) )->getByIntegrationStatusId( 'apilo', (int)$responseData['status'] );
|
|
|
|
$order_tmp = new Order( $order['id'] );
|
|
|
|
if ( $shop_status_id )
|
|
$order_tmp -> update_status( $shop_status_id, false );
|
|
|
|
$order_tmp -> update_aplio_order_status_date( date( 'Y-m-d H:i:s' ) );
|
|
echo '<p>Zaktualizowałem status zamówienia <b>' . $order['number'] . '</b></p>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* zapisywanie historii cen produktów */
|
|
$results = $mdb -> select( 'pp_shop_products', [ 'id', 'price_brutto', 'price_brutto_promo' ], [ 'OR' => [ 'price_history_date[!]' => date( 'Y-m-d' ), 'price_history_date' => null ], 'ORDER' => [ 'price_history_date' => 'ASC' ], 'LIMIT' => 100 ] );
|
|
foreach ( $results as $row )
|
|
{
|
|
if ( $price )
|
|
{
|
|
$mdb -> insert( 'pp_shop_product_price_history', [
|
|
'id_product' => $row['id'],
|
|
'price' => $row['price_brutto_promo'] > 0 ? $row['price_brutto_promo'] : $row['price_brutto'],
|
|
'date' => date( 'Y-m-d' )
|
|
] );
|
|
}
|
|
|
|
$mdb -> update( 'pp_shop_products', [ 'price_history_date' => date( 'Y-m-d' ) ], [ 'id' => $row['id'] ] );
|
|
|
|
$mdb -> delete( 'pp_shop_product_price_history', [ 'date[<=]' => date( 'Y-m-d', strtotime( '-31 days', time() ) ) ] );
|
|
echo '<p>Zapisuję historyczną cenę dla produktu <b>#' . $row['id'] . '</b></p>';
|
|
}
|
|
|
|
/* parsowanie zamówień m.in. pod kątem najczęściej sprzedawanych razem produktów */
|
|
$orders = $mdb -> select( 'pp_shop_orders', 'id', [ 'parsed' => 0, 'LIMIT' => 1 ] );
|
|
foreach ( $orders as $order )
|
|
{
|
|
$products = $mdb -> select( 'pp_shop_order_products', 'product_id', [ 'order_id' => $order ] );
|
|
foreach ( $products as $product1 )
|
|
{
|
|
if ( $parent_id = $mdb -> get( 'pp_shop_products', 'parent_id', [ 'id' => $product1 ] ) )
|
|
$product1 = $parent_id;
|
|
|
|
foreach ( $products as $product2 )
|
|
{
|
|
if ( $parent_id = $mdb -> get( 'pp_shop_products', 'parent_id', [ 'id' => $product2 ] ) )
|
|
$product2 = $parent_id;
|
|
|
|
if ( $product1 != $product2 )
|
|
{
|
|
$intersection_id = $mdb -> query( 'SELECT * FROM pp_shop_orders_products_intersection WHERE product_1_id = :product_1_id AND product_2_id = :product_2_id OR product_1_id = :product_2_id AND product_2_id = :product_1_id', [ 'product_1_id' => (int)$product1, 'product_2_id' => (int)$product2 ] ) -> fetch( \PDO::FETCH_ASSOC );
|
|
if ( $intersection_id )
|
|
{
|
|
$mdb -> update( 'pp_shop_orders_products_intersection', [ 'count' => $intersection_id['count'] + 1 ], [ 'id' => $intersection_id['id'] ] );
|
|
}
|
|
else
|
|
{
|
|
$mdb -> insert( 'pp_shop_orders_products_intersection', [ 'product_1_id' => (int)$product1, 'product_2_id' => (int)$product2, 'count' => 1 ] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$mdb -> update( 'pp_shop_orders', [ 'parsed' => 1 ], [ 'id' => $order ] );
|
|
echo '<p>Parsuję zamówienie <b>#' . $order . '</b></p>';
|
|
}
|