'mysql', 'database_name' => $database[ 'name' ], 'server' => $database[ 'host' ], 'username' => $database[ 'user' ], 'password' => $database[ 'password' ], 'charset' => 'utf8' ] ); $settings = \front\factory\Settings::settings_details(); $baselinker_settings = \front\factory\Shop::baselinker_settings(); $apilo_settings = \admin\factory\Integrations::apilo_settings(); $baselinker_settings = \admin\factory\Integrations::baselinker_settings(); $sellasist_settings = \admin\factory\Integrations::sellasist_settings(); 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 sellasist.pl if ( $sellasist_settings['enabled'] and $sellasist_settings['sync_products'] and $sellasist_settings['api_code'] ) { if ( $result = $mdb -> query( 'SELECT id, sellasist_product_id, sellasist_get_data_date, sellasist_product_name FROM pp_shop_products WHERE sellasist_product_id IS NOT NULL AND sellasist_product_id != 0 AND ( sellasist_get_data_date IS NULL OR sellasist_get_data_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-10 minutes', time() ) ) . '\' ) ORDER BY sellasist_get_data_date ASC LIMIT 1' ) -> fetch( \PDO::FETCH_ASSOC ) ) { $url = "https://projectpro.sellasist.pl/api/v1/products/" . $result['sellasist_product_id'] . "/"; $api_code = \admin\factory\Integrations::sellasist_settings( 'api_code' ); $ch = curl_init( $url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_HTTPHEADER, [ "apiKey: " . $api_code, "accept: application/json" ] ); $response = curl_exec( $ch ); $responseData = json_decode( $response, true ); if ( $responseData['id'] ) { $price_brutto = $responseData['price']; $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' => \S::normalize_decimal( $price_netto, 2 ), 'price_brutto' => \S::normalize_decimal( $price_brutto, 2 ) ], [ 'sellasist_product_id' => $result['sellasist_product_id'] ] ); \admin\factory\ShopProduct::update_product_combinations_prices( (int)$result['id'], $price_brutto, $vat, null ); } // aktualizowanie stanu magazynowego $mdb -> update( 'pp_shop_products', [ 'quantity' => $responseData['storages'][0]['quantity'] ], [ 'sellasist_product_id' => $result['sellasist_product_id'] ] ); $mdb -> update( 'pp_shop_products', [ 'sellasist_get_data_date' => date( 'Y-m-d H:i:s' ) ], [ 'sellasist_product_id' => $result['sellasist_product_id'] ] ); // Czyszczenie cache produktu \S::clear_product_cache( (int)$result['id'] ); echo '

Zaktualizowałem dane produktu ' . $result['sellasist_product_name'] . ' #' . $result['id'] . '

'; } } // 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 = \admin\factory\Integrations::apilo_get_access_token(); $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' => \S::normalize_decimal( $responseData['priceWithoutTax'], 2 ), 'price_brutto' => \S::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 \S::clear_product_cache( (int)$result['id'] ); echo '

Zaktualizowałem dane produktu (APILO) ' . $result['apilo_product_name'] . ' #' . $result['id'] . '

'; } } // 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 = \admin\factory\Integrations::apilo_get_access_token(); $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' => \S::normalize_decimal( $price_netto, 2 ), 'price_brutto' => \S::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'] ] ); \admin\factory\ShopProduct::update_product_combinations_prices( (int)$product_id, $price_brutto, $vat, null ); // Czyszczenie cache produktu \S::clear_product_cache( (int)$product_id ); } } } \admin\factory\Integrations::apilo_settings_save( 'pricelist_update_date', date( 'Y-m-d H:i:s' ) ); echo '

Zaktualizowałem ceny produktów (APILO)

'; } // pobieranie informachji o produkcie w tym: cen, cen promocyjnych, wagi, stanów magazynowych if ( $baselinker_settings['enabled'] and $baselinker_settings['sync_products'] and $baselinker_settings['api_code'] ) { if ( $result = $mdb -> query( 'SELECT id, baselinker_product_id, baselinker_get_data_date FROM pp_shop_products WHERE baselinker_product_id IS NOT NULL AND baselinker_product_id != 0 AND ( baselinker_get_data_date IS NULL OR baselinker_get_data_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-1440 minutes', time() ) ) . '\' ) ORDER BY baselinker_get_data_date ASC LIMIT 1' ) -> fetch( \PDO::FETCH_ASSOC ) ) { $methodParams = '{ "inventory_id": "' . $baselinker_settings['inventory_id'] . '", "products": [' . $result['baselinker_product_id'] . '] }'; $apiParams = [ "token" => $baselinker_settings['api_code'], "method" => "getInventoryProductsData", "parameters" => $methodParams ]; $curl = curl_init( "https://api.baselinker.com/connector.php" ); curl_setopt( $curl, CURLOPT_POST, 1 ); curl_setopt( $curl, CURLOPT_POSTFIELDS, http_build_query( $apiParams ) ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); $response = json_decode( curl_exec( $curl ), true ); $i = 0; if ( $response['status'] == 'SUCCESS' and count( $response['products'] ) ) { foreach ( $response['products'] as $baselinker_product_id => $baselinker_product ) { // aktualizowanie ceny if ( $vat = $mdb -> get( 'pp_shop_products', 'vat', [ 'baselinker_product_id' => $baselinker_product_id ] ) ) { $price_brutto = $baselinker_product['prices'][$baselinker_settings['price_group']]; $price_netto = $baselinker_product['prices'][$baselinker_settings['price_group']] / ( ( 100 + $vat ) / 100 ); $price_brutto_promo = $baselinker_product['prices'][ $baselinker_settings['price_group_promo'] ]; if ( $price_brutto_promo and $price_brutto_promo != $price_brutto ) { $price_netto_promo = $baselinker_product['prices'][$baselinker_settings['price_group_promo']] / ( ( 100 + $vat ) / 100 ); $mdb -> update( 'pp_shop_products', [ 'price_netto_promo' => \S::normalize_decimal( $price_netto_promo, 2 ), 'price_brutto_promo' => \S::normalize_decimal( $price_brutto_promo, 2 ) ], [ 'baselinker_product_id' => $baselinker_product_id ] ); } else $mdb -> update( 'pp_shop_products', [ 'price_netto_promo' => null, 'price_brutto_promo' => null ], [ 'baselinker_product_id' => $baselinker_product_id ] ); $mdb -> update( 'pp_shop_products', [ 'price_netto' => \S::normalize_decimal( $price_netto, 2 ), 'price_brutto' => \S::normalize_decimal( $price_brutto, 2 ) ], [ 'baselinker_product_id' => $baselinker_product_id ] ); $product_id = $mdb -> get( 'pp_shop_products', 'id', [ 'baselinker_product_id' => $baselinker_product_id ] ); $vat = $mdb -> get( 'pp_shop_products', 'vat', [ 'baselinker_product_id' => $baselinker_product_id ] ); \admin\factory\ShopProduct::update_product_combinations_prices( (int)$product_id, $price_brutto, $vat, $price_brutto_promo ); } // aktualizowanie wagi $mdb -> update( 'pp_shop_products', [ 'weight' => $baselinker_product['weight'] ], [ 'baselinker_product_id' => $baselinker_product_id ] ); // aktualizowanie stanu magazynowego $mdb -> update( 'pp_shop_products', [ 'quantity' => $baselinker_product['stock'][$baselinker_settings['stock_id']] ], [ 'baselinker_product_id' => $baselinker_product_id ] ); $mdb -> update( 'pp_shop_products', [ 'baselinker_get_data_date' => date( 'Y-m-d H:i:s' ) ], [ 'baselinker_product_id' => $baselinker_product_id ] ); // Czyszczenie cache produktu \S::clear_product_cache( (int)$result['id'] ); echo '

Zaktualizowałem dane produktu ' . $baselinker_product['text_fields']['name'] . ' #' . $result['id'] . '

'; } } else { $mdb -> update( 'pp_shop_products', [ 'baselinker_get_data_date' => date( 'Y-m-d H:i:s' ) ], [ 'baselinker_product_id' => $baselinker_product_id ] ); echo '

Z powodu błędu pominąłem produkt o ID: ' . $result['id'] . '

'; } } } // sprawdzanie statusów zamówień w sellasist.pl jeżeli zamówienie nie jest zrealizowane, anulowane lub nieodebrane if ( $sellasist_settings['enabled'] and $sellasist_settings['sync_orders'] and $sellasist_settings['api_code'] and $sellasist_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) ) { $order = $mdb -> query( 'SELECT id, sellasist_order_id, sellasist_order_status_date, number FROM pp_shop_orders WHERE sellasist_order_id IS NOT NULL AND sellasist_order_id != 0 AND ( status != 6 AND status != 8 AND status != 9 ) AND ( sellasist_order_status_date IS NULL OR sellasist_order_status_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-30 minutes', time() ) ) . '\' ) ORDER BY sellasist_order_status_date ASC LIMIT 1' ) -> fetch( \PDO::FETCH_ASSOC ); if ( $order['sellasist_order_id'] ) { $url = "https://projectpro.sellasist.pl/api/v1/orders/" . $order['sellasist_order_id'] . "/"; $api_code = \admin\factory\Integrations::sellasist_settings( 'api_code' ); $ch = curl_init( $url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_HTTPHEADER, [ "apiKey: " . $api_code, "accept: application/json" ] ); $response = curl_exec( $ch ); $responseData = json_decode( $response, true ); if ( $responseData['id'] and $responseData['status']['id'] ) { $shop_status_id = \front\factory\ShopStatuses::get_shop_status_by_integration_status_id( 'sellasist', $responseData['status']['id'] ); $mdb -> update( 'pp_shop_orders', [ 'status' => $shop_status_id, 'sellasist_order_status_date' => date( 'Y-m-d H:i:s' ) ], [ 'id' => $order['id'] ] ); echo '

Zaktualizowałem status zamówienia ' . $order['number'] . '

'; } } } // wysyłanie zamówień do sellasist.pl if ( $sellasist_settings['enabled'] and $sellasist_settings['sync_orders'] and $sellasist_settings['api_code'] and $sellasist_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) ) { $orders = $mdb -> select( 'pp_shop_orders', '*', [ 'AND' => [ 'sellasist_order_id' => null, 'date_order[<=]' => date( 'Y-m-d H:i:s', strtotime( '-1 minutes', time() ) ), 'date_order[>=]' => $sellasist_settings['sync_orders_date_start'] ], 'ORDER' => [ 'date_order' => 'ASC' ], 'LIMIT' => 1 ] ); foreach ( $orders as $order ) { $z = 0; $products = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order['id'] ] ); $products_array = []; foreach ( $products as $product ) { $json_data['carts'][] = [ 'id' => $product['product_id'], 'product_id' => \front\factory\ShopProduct::get_sellasist_product_id( $product['product_id'] ), 'name' => $product['name'], 'quantity' => $product['quantity'], 'price' => $product['price_brutto_promo'] ? $product['price_brutto_promo'] : $product['price_brutto'], 'message' => strip_tags( $product['attributes'] ) . ' | ' . $product['message'] ]; } $json_data['id'] = $order['id']; $json_data['currency'] = 'pln'; $json_data['payment_status'] = $order['paid'] ? 'paid' : 'unpaid'; $json_data['paid'] = $order['paid'] ? str_replace( ',', '.', $order['summary'] ) : 0; $json_data['status'] = \front\factory\ShopStatuses::get_sellasist_status_id( $order['status'] ); $json_data['email'] = $order['client_email']; // date $json_data['date'] = date( 'Y-m-d H:i:s', strtotime( $order['date_order'] ) ); // shipment_price $json_data['shipment_price'] = $order['transport_cost']; // payment_id $json_data['payment_id'] = \front\factory\ShopPaymentMethod::get_sellasist_payment_method_id( $order['payment_method_id'] ); // payment_name $json_data['payment_name'] = $order['payment_method']; // shipment_id $json_data['shipment_id'] = \front\factory\ShopTransport::get_sellasist_transport_id( $order['transport_id'] ); // shipment_name $json_data['shipment_name'] = strip_tags( $order['transport'] ); // invoice $json_data['invoice'] = 0; // comment $json_data['comment'] = $order['message']; // bill_address $json_data['bill_address'] = [ 'name' => $order['client_name'], 'surname' => $order['client_surname'], 'street' => $order['client_street'], 'city' => $order['client_city'], 'postcode' => $order['client_postal_code'], 'phone' => $order['client_phone'], 'email' => $order['client_email'], 'country' => [ 'id' => 170, 'name' => 'Poland', 'code' => 'PL' ] ]; // shipment_address $json_data['shipment_address'] = [ 'name' => $order['client_name'], 'surname' => $order['client_surname'], 'street' => $order['client_street'], 'city' => $order['client_city'], 'postcode' => $order['client_postal_code'], 'phone' => $order['client_phone'], 'email' => $order['client_email'], 'country' => [ 'id' => 170, 'name' => 'Poland', 'code' => 'PL' ] ]; // pickup_point if ( $order['inpost_paczkomat'] ) { $pickup = explode( ' | ', $order['inpost_paczkomat'] ); $pickup_code = $pickup[0]; $pickup_address = $pickup[1]; $json_data['pickup_point'] = [ 'code' => $pickup_code, 'type' => 'inpost', 'address' => $pickup_address ]; } // URL docelowe $url = "https://projectpro.sellasist.pl/api/v1/orders"; // Nagłówki $headers = array( "accept: application/json", "apiKey: " . $sellasist_settings['api_code'], "Content-Type: application/json" ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($json_data) ); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 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 ( $response['status'] == 'exist' ) { $mdb -> update( 'pp_shop_orders', [ 'sellasist_order_id' => $response['order_id'] ], [ 'id' => $order['id'] ] ); } else if ( $response['id'] ) { $mdb -> update( 'pp_shop_orders', [ 'sellasist_order_id' => $response['id'] ], [ 'id' => $order['id'] ] ); echo '

Wysłałem zamówienie do sellasist.pl

'; } } } // 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 ) { $sku = \front\factory\ShopProduct::get_product_sku( $product['product_id'], true ); $products_array[] = [ 'idExternal' => $product['product_id'], 'ean' => \front\factory\ShopProduct::get_product_ean( $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 .= ''; $order_message .= ''; $order_message .= ''; $order_message .= ''; $order_message .= ''; $order_message .= '
'; $order_message .= ''; $order_message .= ''; $order_message .= '' . $product['name'] . '
'; $order_message .= strip_tags( $product['attributes'] ) . '
'; $order_message .= preg_replace( '/\s+/', ' ', htmlspecialchars( $product['message'] ) ) . '
'; $order_message .= strip_tags( str_replace( '
', ' | ', preg_replace( '/\s+/', ' ', $product['custom_fields'] ) ) ) . '
'; $order_message .= '
'; $order_message .= '
'; } //TODO: ostatnio był problem kiedy wiadomość miała mniej 1024 znaki ale zawierała przeniesienie tekstu '
' i do tego jeszcze miała emoji. Wtedy APILO tego nie przepuszczał. if ( strlen( $order_message ) > 850 ) $order_message = '

Wiadomość do zamówienia była zbyt długa. Sprawdź szczegóły w panelu sklepu

'; // 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 = \admin\factory\Integrations::apilo_get_access_token(); $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 ) { \S::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)\front\factory\ShopPaymentMethod::get_apilo_payment_method_id( $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)\front\factory\ShopTransport::get_apilo_carrier_account_id( $order['transport_id'] ), 'orderNotes' => [ [ 'type' => 1, 'comment' => 'Wiadomość do zamówienia:
' . $order['message'] . '

' . $order_message ] ], 'status' => (int)\front\factory\ShopStatuses::get_apilo_status_id( $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' => \front\factory\ShopPaymentMethod::get_apilo_payment_method_id( $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 '

Zaktualizowałem id zamówienia na podstawie zamówienia apilo.com

'; } 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 '

Zamówienie już istnieje w Apilo. Zaktualizowano ID zamówienia: ' . $apilo_order_id . '

'; } else { echo '
';
          echo print_r( $response, true );
          echo print_r( $postData, true );
          echo '
'; $email_data = print_r( $response, true ); $email_data .= print_r( $postData, true ); \S::send_email( 'biuro@project-pro.pl', 'Błąd wysyłania zamówienia do apilo.com - nie znaleziono zamówienia', $email_data ); } } else { echo '
';
        echo print_r( $response, true );
        echo print_r( $postData, true );
        echo '
'; $email_data = print_r( $response, true ); $email_data .= print_r( $postData, true ); \S::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 '

Wysłałem zamówienie do apilo.com: ID: ' . $order['id'] . ' - ' . $response['id'] . '

'; } } } // 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 = \admin\factory\Integrations::apilo_get_access_token(); $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 = \front\factory\ShopStatuses::get_shop_status_by_integration_status_id( 'apilo', $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 '

Zaktualizowałem status zamówienia ' . $order['number'] . '

'; } } } } // sprawdzanie statusów zamówień w baselinker.com jeżeli zamówienie nie jest zrealizowane, anulowane lub nieodebrane if ( $baselinker_settings['enabled'] and $baselinker_settings['sync_orders'] and $baselinker_settings['api_code'] and $baselinker_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) ) { $order = $mdb -> query( 'SELECT id, baselinker_order_id, baselinker_order_status_date, number FROM pp_shop_orders WHERE baselinker_order_id IS NOT NULL AND baselinker_order_id != 0 AND ( status != 6 AND status != 8 AND status != 9 ) AND ( baselinker_order_status_date IS NULL OR baselinker_order_status_date <= \'' . date( 'Y-m-d H:i:s', strtotime( '-30 minutes', time() ) ) . '\' ) ORDER BY baselinker_order_status_date ASC LIMIT 1' ) -> fetch( \PDO::FETCH_ASSOC ); if ( $order['baselinker_order_id'] ) { $methodParams = '{ "order_id": ' . $order['baselinker_order_id'] . ' }'; $apiParams = [ "token" => $baselinker_settings['api_code'], "method" => "getOrders", "parameters" => $methodParams ]; $curl = curl_init( "https://api.baselinker.com/connector.php" ); curl_setopt( $curl, CURLOPT_POST, 1 ); curl_setopt( $curl, CURLOPT_POSTFIELDS, http_build_query( $apiParams ) ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); $response = json_decode( curl_exec( $curl ), true ); if ( $response['status'] == 'SUCCESS' and count( $response['orders'] ) ) { $shop_status_id = \shop\ShopStatus::get_shop_status_by_baselinker_status( (int) $response['orders'][0]['order_status_id'] ); $order_tmp = new Order( $order['id'] ); $order_tmp -> update_status( $shop_status_id, false ); $order_tmp -> update_baselinker_order_status_date( date( 'Y-m-d H:i:s' ) ); echo '

Zaktualizowałem status zamówienia ' . $order['number'] . '

'; } else { $mdb -> update( 'pp_shop_orders', [ 'baselinker_order_status_date' => date( 'Y-m-d H:i:s' ) ], [ 'id' => $order['id'] ] ); echo '

Z powodu błędu pominąłem zamówienie o ID: ' . $order['id'] . '

'; } } } // wysyłanie zamówień do baselinker if ( $baselinker_settings['enabled'] and $baselinker_settings['sync_orders'] and $baselinker_settings['api_code'] and $baselinker_settings['sync_orders_date_start'] <= date( 'Y-m-d H:i:s' ) ) { $orders = $mdb -> select( 'pp_shop_orders', '*', [ 'AND' => [ 'baselinker_order_id' => null, 'date_order[<=]' => date( 'Y-m-d H:i:s', strtotime( '-1 minutes', time() ) ), 'date_order[>=]' => $baselinker_settings['sync_orders_date_start'] ], 'ORDER' => [ 'date_order' => 'ASC' ], 'LIMIT' => 1 ] ); foreach ( $orders as $order ) { if ( $order['transport_id'] == 2 ) { $pickup = explode( ' | ', $order['inpost_paczkomat'] ); $pickup_name = $pickup[0]; $pickup_address = $pickup[1]; } $methodParams = '{ "order_status_id": "' . \front\factory\ShopStatuses::get_baselinker_order_status_id( $order['status'] ) . '", "date_add": "' . strtotime( $order['date_order'] ) . '", "user_comments": "' . preg_replace('/\s+/', ' ', \S::remove_special_chars( $order['message'] ) ) . '", "admin_comments": "' . $order['notes'] . '", "phone": "' . $order['client_phone'] . '", "email": "' . $order['client_email'] . '", "user_login": "' . $order['client_name'] . ' ' . $order['client_surname'] . '", "currency": "PLN", "payment_method": "' . $order['payment_method'] . '", "payment_method_cod": "' . ( $order['payment_method_id'] == 3 ? 1 : 0 ) . '", "paid": "' . $order['paid'] . '", "delivery_method": "' . strip_tags( $order['transport'] ) . '", "delivery_price": "' . $order['transport_cost'] . '", "delivery_fullname": "' . $order['client_name'] . ' ' . $order['client_surname'] . '", "delivery_company": "' . $order['client_firm'] . '", "delivery_address": "' . $order['client_street'] . '", "delivery_city": "' . $order['client_city'] . '", "delivery_postcode": "' . $order['client_postal_code'] . '", "delivery_country_code": "PL", "delivery_point_id": "' . $pickup_name . '", "delivery_point_name": "' . ( $pickup_name != '' ? 'Paczkomat ' . $pickup_name : '' ) . '", "delivery_point_address": "' . $pickup_address . '", "delivery_point_postcode": "", "delivery_point_city": "", "invoice_fullname": "", "invoice_company": "", "invoice_nip": "", "invoice_address": "", "invoice_city": "", "invoice_postcode": "", "invoice_country_code": "", "want_invoice": "0", "extra_field_1": "", "extra_field_2": "", "products": ['; $products = $mdb -> select( 'pp_shop_order_products', '*', [ 'order_id' => $order['id'] ] ); foreach ( $products as $product ) { $methodParams .= '{ "storage": "db", "storage_id": 0, "product_id": "' .\shop\Product::get_baselinker_product_id( (int)$product['product_id'] ) . '", "variant_id": "", "name": "' . htmlspecialchars( $product['name'] ) . '", "sku": "' . \shop\Product::get_product_sku( (int)$product['product_id'] ) . '", "ean": "", "attributes": "' . strip_tags( $product['attributes'] ) . ' | ' . strip_tags( str_replace( '
', ' | ', preg_replace( '/\s+/', ' ', $product['custom_fields'] ) ) ) . ' | ' . preg_replace( '/\s+/', ' ', htmlspecialchars( $product['message'] ) ) . '", "price_brutto": ' . ( $product['price_brutto_promo'] ? $product['price_brutto_promo'] : $product['price_brutto'] ) . ', "tax_rate": ' . $product['vat'] . ', "quantity": ' . $product['quantity'] . ', "weight": 1 }'; if ( $product != end( $products ) ) $methodParams .= ','; } $methodParams .= '] }'; $apiParams = [ "token" => $baselinker_settings['api_code'], "method" => "addOrder", "parameters" => $methodParams ]; $curl = curl_init( "https://api.baselinker.com/connector.php" ); curl_setopt( $curl, CURLOPT_POST, 1 ); curl_setopt( $curl, CURLOPT_POSTFIELDS, http_build_query( $apiParams ) ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); $response = json_decode( curl_exec( $curl ), true ); if ( $response['status'] == 'SUCCESS' ) { $mdb -> update( 'pp_shop_orders', [ 'baselinker_order_id' => $response['order_id'] ], [ 'id' => $order['id'] ] ); echo '

Wysłałem zamówienie do Baselinker ' . $order['number'] . '

'; } } } /* 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 '

Zapisuję historyczną cenę dla produktu #' . $row['id'] . '

'; } /* 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 '

Parsuję zamówienie #' . $order . '

'; }