From d494778fada130d907d49200c02dfef1c719793c Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sat, 14 Sep 2024 12:39:50 +0200 Subject: [PATCH 1/9] class.remote.php added additional logging --- www/lib/class.remote.php | 144 +++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 80 deletions(-) diff --git a/www/lib/class.remote.php b/www/lib/class.remote.php index d1883f32..c219059a 100644 --- a/www/lib/class.remote.php +++ b/www/lib/class.remote.php @@ -2240,13 +2240,12 @@ class Remote { $this->app->erp->AuftragProtokoll($orderId, 'Versandmeldung an Shop fehlgeschlagen', $bearbeiter); $this->logger->error('Versandmeldung an Shop fehlgeschlagen', - [ - 'orderId' => $orderId, - 'shopId' => $shopId, - 'message' => $response->getMessage() - ] + [ + 'orderId' => $orderId, + 'shopId' => $shopId, + 'message' => $response->getMessage() + ] ); - return; } @@ -2486,7 +2485,21 @@ class Remote { $shoptyp = $this->app->DB->Select("SELECT shoptyp FROM shopexport WHERE id='$id' LIMIT 1"); $modulename = trim($this->app->DB->Select("SELECT modulename FROM shopexport WHERE id='$id' LIMIT 1"), '.'); $isActionAuth = $action === 'auth'; + $exception = null; + + $this->logger->debug( + 'RemoteCommand (Shop '.$id.") ".$action, + [ + 'shop' => $id, + 'action' => $action, + 'data' => $data + ] + ); + if ($shoptyp === 'custom') { + + $error = null; + if ($modulename != '') { $file = dirname(__DIR__) . '/plugins/external/shopimporter/' . $modulename; @@ -2507,29 +2520,37 @@ class Remote { $method = $this->getMethod($obj, $action); if (method_exists($obj, $method)) { $ret = $obj->$method(); + $this->logger->debug('RemoteCommand result (Shop '.$id.') '.$modulename.' '.$action, + [ + 'shop' => $id, + 'action' => $action, + 'data' => $data, + 'result' => $ret + ] + ); if (!empty($this->app->stringcleaner)) { $this->app->stringcleaner->XMLArray_clean($ret); } } elseif ($isActionAuth) { - return 'Fehler: Importer konnte nicht initialisiert werden'; + $error = 'Fehler: Importer konnte nicht initialisiert werden'; } } elseif ($isActionAuth) { - return 'Fehler: Importer konnte nicht initialisiert werden'; + $error = 'Fehler: Importer konnte nicht initialisiert werden'; } } elseif ($isActionAuth) { - return 'Fehler: Importer konnte nicht initialisiert werden'; + $error = 'Fehler: Importer konnte nicht initialisiert werden'; } } elseif ($isActionAuth) { - return 'Fehler: Datei ' . $file . ' existiert nicht'; + $error = 'Fehler: Datei ' . $file . ' existiert nicht'; } } elseif ($isActionAuth) { - return 'Fehler: Schnittstelle nicht aktiv'; + $error = 'Fehler: Schnittstelle nicht aktiv'; } + } else { + $error = 'Fehler: Kein Modul angegeben'; } - return ''; } - - if ($shoptyp === 'intern') { + else if ($shoptyp === 'intern') { if ($modulename != '') { if ($this->app->erp->ModulVorhanden($modulename)) { $obj = $this->app->erp->LoadModul($modulename); @@ -2538,94 +2559,57 @@ class Remote { $obj->getKonfig($id, $data); } $method = 'Import' . $action; - if (method_exists($obj, $method)) { try { $ret = $obj->$method(); } catch (Exception $e) { + $exception = $e; if ($isActionAuth) { - return 'Fehler Auth: ' . $e->getMessage(); + $error = 'Fehler Auth: ' . $e->getMessage(); + } else { + $error = 'Fehler: ' . $e->getMessage(); } - return 'Fehler: ' . $e->getMessage(); } - + $this->logger->debug('RemoteCommand result (Shop '.$id.') '.$modulename.' '.$action, + [ + 'shop' => $id, + 'action' => $action, + 'data' => $data, + 'result' => $ret + ] + ); if (!empty($this->app->stringcleaner)) { $this->app->stringcleaner->XMLArray_clean($ret); } $this->parseReturn($ret, $id, $action); - return $ret; } else { - return 'Fehler: Funktion nicht implementiert: ' . $method; + $error = 'Fehler: Funktion nicht implementiert: ' . $method; } } elseif ($isActionAuth) { - return 'Fehler: Importer konnte nicht initialisiert werden'; + $error = 'Fehler: Importer konnte nicht initialisiert werden'; } } elseif ($isActionAuth) { - return 'Fehler: Dieses Modul ist nicht verfügbar'; + $error = 'Fehler: Dieses Modul ist nicht verfügbar'; } } elseif ($isActionAuth) { - return 'Fehler: Kein Modul vorhanden'; + $error = 'Fehler: Kein Modul vorhanden'; + } else { + $error = 'Fehler: Kein Modul angegeben'; } - return ''; } - $shopexport = $this->app->DB->SelectRow("SELECT * FROM shopexport WHERE id='$id' LIMIT 1"); - if ($shopexport) { - if ($shopexport['shoptyp'] === 'intern' || $shopexport['shoptyp'] === 'custom') { - return ''; - } - $token = $shopexport['token']; - $url = $shopexport['url']; - $z = $shopexport['passwort']; - $bezeichnung = $shopexport['bezeichnung']; - } else { - $token = ''; - $z = ''; - $url = ''; - } - if ($isActionAuth) { - if ($token === '' || strlen($z) < 32 || $url === '') { - return 'Fehler: Bitte Zugangsdaten prüfen'; - } - } elseif ($token === '' || strlen($z) < 32 || $url === '' || !$this->app->DB->Select("SELECT id FROM shopexport WHERE id = '$id' AND aktiv = 1 LIMIT 1")) { - return ''; - } - - $tmp = parse_url($url); - $tmp['host'] = rtrim($tmp['host'], '/'); - $tmp['path'] = rtrim($tmp['path'], '/') . '/'; - - $aes = new AES($z); - $token = base64_encode($aes->encrypt(serialize($token))); - $client = new HttpClient($tmp['host'], stripos($url, 'https') === 0 ? 443 : 80); - $geturl = $tmp['path'] . 'index.php?module=import&action=' . $action . '&challenge=' . (isset($challenge) ? $challenge : ''); - //Kein Fragezeichen vor module=import... - if (false !== stripos($bezeichnung, 'woocommerce')) { - $geturl = $tmp['path'] . 'module=import&action=' . $action . '&challenge=' . (isset($challenge) ? $challenge : ''); - } - if (false !== stripos($bezeichnung, 'shopware plugin')) { - $geturl = $tmp['path'] . 'wawisionimporter/?smodule=import&saction=' . $action . '&challenge=' . (isset($challenge) ? $challenge : ''); - } - - $post_data['token'] = $token; - $post_data['data'] = base64_encode(serialize($data)); - $client->timeout = 120; - if (!$client->post($geturl, $post_data)) { - - $this->logger->error('An error occurred', - [ - 'error' => $client->getError() - ] + if ($error) { + $this->logger->error('RemoteCommand error (Shop '.$id.') '.$modulename.' '.$action, + [ + 'error' => $error, + 'exception' => $exception + ] ); - - throw new Exception('An error occurred: ' . $client->getError()); - //return 'Netzwerkverbindung von WaWison zu Shopimporter fehlgeschlagen: '.$client->getError(); - } - $ret = unserialize(base64_decode($client->getContent())); - if (!empty($this->app->stringcleaner)) { - $this->app->stringcleaner->XMLArray_clean($ret); - } - $this->parseReturn($ret, $id, $action); + return($error); + } + return $ret; + + // Dead code removed here 2024-09-13 } /** From 0b807455cab0f3402838302e50cac1a6604b4498 Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sat, 14 Sep 2024 12:44:21 +0200 Subject: [PATCH 2/9] woocommerce migrated logging from logfile to logger --- www/pages/shopimporter_woocommerce.php | 181 ++++++++----------------- 1 file changed, 56 insertions(+), 125 deletions(-) diff --git a/www/pages/shopimporter_woocommerce.php b/www/pages/shopimporter_woocommerce.php index e1a30aed..f97e9896 100644 --- a/www/pages/shopimporter_woocommerce.php +++ b/www/pages/shopimporter_woocommerce.php @@ -16,10 +16,10 @@ use Xentral\Components\Http\JsonResponse; use Xentral\Modules\Onlineshop\Data\OrderStatus; use Xentral\Modules\Onlineshop\Data\OrderStatusUpdateRequest; +use Xentral\Components\Logger\Logger; class Shopimporter_Woocommerce extends ShopimporterBase { - // protected $canexport = false; public $intern = false; @@ -55,16 +55,17 @@ class Shopimporter_Woocommerce extends ShopimporterBase */ protected $app; protected $dump; + + /** @var Logger $logger */ + public $logger; + public function __construct($app, $intern = false) { $this->app=$app; $this->intern = true; - + $this->logger = $app->Container->get('Logger'); } - - - public function ImportList() { $msg = $this->app->erp->base64_url_encode('
Sie können hier die Shops einstellen
'); @@ -72,8 +73,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase exit; } - - /** * This function returns the number of orders which have not yet been imported */ @@ -83,7 +82,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase // We set per_page to 100 - this could lead to a situation where there are more than // 100 new Orders, but we still only return 100. - // Array containing additional settings, namely 'ab_nummer' (containting the next order number to get) // and 'holeallestati' (an integer) $tmp = $this->CatchRemoteCommand('data'); @@ -97,7 +95,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase if ($number_from) { // Number-based import is selected - // The WooCommerce API doenst allow for a proper "greater than id n" request. // we fake this behavior by creating an array that contains 'many' (~ 1000) consecutive // ids that are greater than $from_number and use this array with the 'include' property @@ -115,7 +112,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'include' => implode(",",$fakeGreaterThanIds), ]); - } else { // fetch posts by status @@ -129,7 +125,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase return (!empty($pendingOrders)?count($pendingOrders):0); } - /** * Calling this function queries the api for pending orders and returns them * as an array. @@ -141,7 +136,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase */ public function ImportGetAuftrag() { - // Array containing additional settings, namely 'ab_nummer' (containting the next order number to get) // and 'holeallestati' (an integer) $tmp = $this->CatchRemoteCommand('data'); @@ -155,7 +149,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase if ($number_from) { // Number-based import is selected - // The WooCommerce API doenst allow for a proper "greater than id n" request. // we fake this behavior by creating an array that contains 'many' (~ 1000) consecutive // ids that are greater than $from_number and use this array with the 'include' property @@ -175,7 +168,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'orderby' => 'id' ]); - } else { // fetch posts by status @@ -188,7 +180,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase } - // Return an empty array in case there are no orders to import if ((!empty($pendingOrders)?count($pendingOrders):0) === 0) { return null; @@ -214,10 +205,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase return $tmp; - } - // This function searches the wcOrder for the specified WC Meta key // and returns it if found, null otherise public function get_wc_meta($wcOrder, $meta_key) { @@ -231,15 +220,11 @@ class Shopimporter_Woocommerce extends ShopimporterBase return $value; } - // Parse the given WooCommerce order, return a Xentral array-represented order. // Overload this method whenever additional attributes are required. public function parseOrder($wcOrder) { - - - $order = array(); $order['auftragsdaten'] = $wcOrder; @@ -273,7 +258,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase } } - if(!empty($wcOrder->subshop)){ $order['subshop'] = $wcOrder->subshop; } @@ -302,7 +286,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase } // - // // Coupon Codes // @@ -333,7 +316,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase - $seperateShippingAddress = !self::compareObjects( $wcOrder->billing, $wcOrder->shipping, @@ -360,7 +342,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase $order['lieferadresse_land'] = $wcOrder->shipping->country; } - // VAT stuff $vatId = $this->get_wc_meta($wcOrder, "_billing_ustid"); @@ -375,7 +356,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase $order['zahlungsweise'] = $wcOrder->payment_method; $order['lieferung'] = $wcOrder->shipping_lines[0]->method_id; - return $order; } @@ -417,7 +397,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase return $orderItem; } - /** * Sets the Order status to processing, meaning we've successfully imported * the order into our DB. This prevents the order from beeing imported again. @@ -432,7 +411,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase ]); } - return 'ok'; } @@ -455,7 +433,13 @@ class Shopimporter_Woocommerce extends ShopimporterBase $this->client->post('orders/'.$data->orderId.'/notes', [ 'note' => 'Tracking Code: ' . $trackingCode ]); - $this->WooCommerceLog("Tracking Code Rückmeldung für Auftrag: $data->orderId", $trackingCode); + + $this->logger->info("WooCommerce Tracking Code Rückmeldung für Auftrag: ".$data->orderId, + [ + 'orderId' => $data->orderId, + 'trackingCode' => $trackingCode + ] + ); } $updateData = [ @@ -472,12 +456,16 @@ class Shopimporter_Woocommerce extends ShopimporterBase ], ]; $this->client->put('orders/'.$data->orderId, $updateData); - $this->WooCommerceLog("Statusrückmeldung 'completed' für Auftrag: $data->orderId", $this->statusCompleted ); - + + $this->logger->info("WooCommerce Statusrückmeldung 'completed' für Auftrag: ".$data->orderId, + [ + 'orderId' => $data->orderId, + 'status' => $this->statusCompleted + ] + ); return 'ok'; } - /** * This function syncs the current stock to the remote WooCommerce shop * @return int @@ -524,8 +512,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase if (empty($remoteIdInformation['id'])) { // The online shop doesnt know this article, write to log and continue with next product - $this->WooCommerceLog("Artikel $nummer wurde im Online-Shop nicht gefunden! Falsche Artikelnummer im Shop hinterlegt?"); - + + $this->logger->error("WooCommerce Artikel $nummer wurde im Online-Shop nicht gefunden! Falsche Artikelnummer im Shop hinterlegt?"); continue; } @@ -541,21 +529,19 @@ class Shopimporter_Woocommerce extends ShopimporterBase }else{ $result = $this->client->put('products/' . $remoteIdInformation['id'], $updateProductParams); } - $this->WooCommerceLog("WooCommerce Lagerzahlenübertragung für Artikel: $nummer / $remoteIdInformation[id] - Anzahl: $lageranzahl", $result); - + + $this->logger->error("WooCommerce Lagerzahlenübertragung für Artikel: $nummer / $remoteIdInformation[id] - Anzahl: $lageranzahl", + [ + 'result' => $result + ] + ); $anzahl++; } - - return $anzahl; } - - public function ImportStorniereAuftrag() { $orderId = $this->CatchRemoteCommand('data')['auftrag']; - - if (!empty($orderId)) { $this->client->put('orders/'.$orderId, [ 'status' => 'cancelled', @@ -563,22 +549,13 @@ class Shopimporter_Woocommerce extends ShopimporterBase } else { return 'failed'; } - return 'ok'; } - public function ImportSendList() { - - $tmp = $this->catchRemoteCommand('data'); - $anzahl = 0; - for($i=0;$i<(!empty($tmp)?count($tmp):0);$i++){ - - - $artikel = $tmp[$i]['artikel']; $nummer = $tmp[$i]['nummer']; if(!empty($tmp[$i]['artikelnummer_fremdnummern'][0]['nummer'])){ @@ -604,7 +581,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase $dim_width = $tmp[$i]['breite']; $dim_height = $tmp[$i]['hoehe']; - // Sanitize dimensions if (self::emptyString($weight_kg)) $weight_kg = null; @@ -619,11 +595,9 @@ class Shopimporter_Woocommerce extends ShopimporterBase $dim_height = null; - $meta_desc = $tmp[$i]['metadescription_de']; $meta_title = $tmp[$i]['metatitle_de']; - $pseudopreis = $tmp[$i]['pseudopreis'];//*1.19; if($pseudopreis <= $preis)$pseudopreis = $preis; $steuersatz = $tmp[$i]['steuersatz']; @@ -657,7 +631,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase ]; - // Attributes that are used for both updating an existing product as well as creating a new one $commonProductAtts = [ 'name' => $name_de, @@ -675,7 +648,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'meta_data' => $commonMetaData, ]; - if($lageranzahl===0){ $commonProductAtts['stock_status'] = 'outofstock'; $commonProductAtts['manage_stock'] = true; @@ -693,30 +665,22 @@ class Shopimporter_Woocommerce extends ShopimporterBase $commonProductAtts['stock_quantity'] = (int)$lageranzahl; } - - if(!is_null($product_id)) { // Such a product already appears to exist, so we update it $this->client->put('products/'.$product_id, array_merge([ ], $commonProductAtts)); - $this->WooCommerceLog("WooCommerce Artikel geändert für Artikel: $nummer / $product_id"); - + $this->logger->info("WooCommerce Artikel geändert für Artikel: $nummer / $product_id"); } else{ // create a new product $product_id = $this->client->post('products/', array_merge([ 'sku' => $nummer, ], $commonProductAtts))->id; - - - - $this->WooCommerceLog("WooCommerce neuer Artikel angelegt: $nummer"); - + $this->logger->info("WooCommerce neuer Artikel angelegt: $nummer"); } - - + // TODO: Kategoriebaum und Bilder werden noch nicht uebertragen // if(isset($tmp[$i]['kompletter_kategorienbaum'])){ @@ -729,13 +693,10 @@ class Shopimporter_Woocommerce extends ShopimporterBase // $this->save_images($dateien, $product_id); // } - // Update the associated product categories $chosenCats = array(); if(isset($tmp[$i]['kategorien']) || isset($tmp[$i]['kategoriename'])){ - - $kategorien = $tmp[$i]['kategorien']; if (!($kategorien) && !self::emptyString($tmp[$i]['kategoriename'])) { $kategorien = array( @@ -745,11 +706,9 @@ class Shopimporter_Woocommerce extends ShopimporterBase ); } if((!empty($kategorien)?count($kategorien):0)>0){ - // Retrive all WC categories via API $allWooCommerceCategories = $this->client->get('products/categories', ['per_page' => '100']); - $searchWpCategories = []; foreach($allWooCommerceCategories as $a){ $searchWpCategories[$a->id] = $a->name; @@ -764,13 +723,10 @@ class Shopimporter_Woocommerce extends ShopimporterBase // If WC has a matching category. We match based on name! if(array_search($wawi_cat_name,array_values($searchWpCategories)) !== false) { - // get id of that WC Category $wcCatId = array_search($wawi_cat_name,$searchWpCategories); - } else { - // No matching category exists $wcCatId = $this->client->post('products/categories', [ 'name' => $wawi_cat_name, @@ -778,14 +734,12 @@ class Shopimporter_Woocommerce extends ShopimporterBase } - if ($wcCatId) { // update category. We first retrieve the product and append the new product category, not replace the entire category array. $alreadyAssignedWCCats = $this->client->get('products/'.$product_id, [ 'per_page' => 1, ])->categories; - // Get ids of existing categories $existingCategoryIds = []; foreach ($alreadyAssignedWCCats as $cat) { @@ -814,16 +768,10 @@ class Shopimporter_Woocommerce extends ShopimporterBase $anzahl++; } - - - return $anzahl; - // return array($product_id,$anzahl,$nummer,$steuersatz, $preis); - } - /** * Checks the connection to the WooCommerce API by trying a simple API request * @@ -839,7 +787,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase } } - /** * This is called by class.remote.php, initializes some class variables from the DB * @param [type] $shopid [description] @@ -876,8 +823,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase $ImportWooCommerceApiKey, //WooCommerce API Secret $ImportWooCommerceApiSecret, - - ["query_string_auth" => true] + ["query_string_auth" => true], + $this->logger ); } @@ -919,8 +866,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase $ImportWooCommerceApiUrl, $ImportWooCommerceApiKey, $ImportWooCommerceApiSecret, - - ['query_string_auth' => true] + ['query_string_auth' => true], + $this->logger ); $auth = $this->ImportAuth(); @@ -931,7 +878,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase return null; } - /** * @return array[] */ @@ -987,7 +933,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase * @throws WCHttpClientException */ private function getShopIdBySKU($sku) { - // Retrieve the product with the given sku. // Note: We limit the result set to 1 (per_page=1), so this doesnt work // if there are multiple products with the same sku. should not happen in practice anyway @@ -1005,7 +950,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase return null; } - private function getSKUByShopId($articleid, $variationid) { $product = $this->client->get("products/$articleid/variations/$variationid"); @@ -1023,7 +967,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'ausblenden'=>array('abholmodus'=>array('zeitbereich')), 'archiv'=>array('ab_nummer'), 'felder'=>array( - 'protokoll'=>array('typ'=>'checkbox','bezeichnung'=>'Protokollierung im Logfile:'), +// 'protokoll'=>array('typ'=>'checkbox','bezeichnung'=>'Protokollierung im Logfile:'), 'ImportWoocommerceApiKey'=>array('typ'=>'text','bezeichnung'=>'{|API Key:','size'=>60), 'ImportWoocommerceApiSecret'=>array('typ'=>'text','bezeichnung'=>'{|API Secret|}:','size'=>60), 'ImportWoocommerceApiUrl'=>array('typ'=>'text','bezeichnung'=>'{|API Url|}:','size'=>40), @@ -1034,20 +978,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase )); } - - /** - * Writes data to the syslog - * @param [type] $nachricht message that will be logged - * @param string $dump php array or object, printed using print_r - */ - public function WooCommerceLog($nachricht, $dump = '') - { - if($this->protokoll){ - $this->app->erp->LogFile($nachricht, print_r($dump, true)); - } - } - - /** * Compares two Objects and returns true if every variable in items * is the same in $a and $b @@ -1068,8 +998,6 @@ class Shopimporter_Woocommerce extends ShopimporterBase return true; } - - /** * Returns true when the string entered is empty, after stripping whitespace * @param String $string input @@ -1081,11 +1009,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase } - - class WCClient { - /** * WooCommerce REST API WCClient version. */ @@ -1097,7 +1022,10 @@ class WCClient * @var WCHttpClient */ public $http; - + + /** @var Logger $logger */ + public $logger; + /** * Initialize client. * @@ -1108,9 +1036,10 @@ class WCClient * * @throws WCHttpClientException */ - public function __construct($url, $consumerKey, $consumerSecret, $options = []) + public function __construct($url, $consumerKey, $consumerSecret, $options = [], $logger) { - $this->http = new WCHttpClient($url, $consumerKey, $consumerSecret, $options); + $this->http = new WCHttpClient($url, $consumerKey, $consumerSecret, $options, $logger); + $this->logger = $logger; } /** @@ -1190,7 +1119,6 @@ class WCClient class WCResponse { - /** * WCResponse code. * @@ -1289,7 +1217,6 @@ class WCResponse class WCOptions { - /** * Default WooCommerce REST API version. */ @@ -1423,7 +1350,6 @@ class WCOptions class WCRequest { - /** * WCRequest url. * @@ -1596,7 +1522,6 @@ class WCRequest class WCOAuth { - /** * OAuth signature method algorithm. */ @@ -1906,7 +1831,6 @@ class WCHttpClientException extends \Exception class WCHttpClient { - /** * cURL handle. * @@ -1962,6 +1886,9 @@ class WCHttpClient * @var string */ private $responseHeaders; + + /** @var Logger $logger */ + public $logger; /** * Initialize HTTP client. @@ -1973,7 +1900,7 @@ class WCHttpClient * * @throws WCHttpClientException */ - public function __construct($url, $consumerKey, $consumerSecret, $options) + public function __construct($url, $consumerKey, $consumerSecret, $options, $logger) { if (!function_exists('curl_version')) { throw new WCHttpClientException('cURL is NOT installed on this server', -1, new WCRequest(), new WCResponse()); @@ -1983,6 +1910,7 @@ class WCHttpClient $this->url = $this->buildApiUrl($url); $this->consumerKey = $consumerKey; $this->consumerSecret = $consumerSecret; + $this->logger = $logger; } /** @@ -2171,7 +2099,6 @@ class WCHttpClient */ protected function createResponse() { - // Set response headers. $this->responseHeaders = ''; curl_setopt($this->ch, CURLOPT_HEADERFUNCTION, function ($_, $headers) { @@ -2195,7 +2122,7 @@ class WCHttpClient */ protected function setDefaultCurlSettings() { - $verifySsl = $this->options->verifySsl(); +// $verifySsl = $this->options->verifySsl(); $timeout = $this->options->getTimeout(); $followRedirects = $this->options->getFollowRedirects(); @@ -2235,6 +2162,13 @@ class WCHttpClient $errorMessage = $errors->message; $errorCode = $errors->code; } + + $this->logger->error('WooCommerce Error', + [ + 'request' => $this->request, + 'response' => $this->response + ] + ); throw new WCHttpClientException( sprintf('Error: %s [%s]', $errorMessage, $errorCode), @@ -2294,8 +2228,6 @@ class WCHttpClient public function request($endpoint, $method, $data = [], $parameters = []) { - - // Initialize cURL. $this->ch = curl_init(); @@ -2308,7 +2240,6 @@ class WCHttpClient // Get response. $response = $this->createResponse(); - // Check for cURL errors. if (curl_errno($this->ch)) { throw new WCHttpClientException('cURL Error: ' . \curl_error($this->ch), 0, $request, $response); From 6d13973c067f2a67d1a9a1c15ac36b4ba81f15e5 Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sat, 14 Sep 2024 12:45:13 +0200 Subject: [PATCH 3/9] woocommerce bugfix import order with product variation --- www/pages/shopimporter_woocommerce.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/pages/shopimporter_woocommerce.php b/www/pages/shopimporter_woocommerce.php index f97e9896..2e1bda94 100644 --- a/www/pages/shopimporter_woocommerce.php +++ b/www/pages/shopimporter_woocommerce.php @@ -388,7 +388,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase // The item could be a variable product in which case we have to retrieve the sku of the variation product if (!empty($wcOrderItem->variation_id)) { - $variation_product_sku = $this->getSKUByShopId($wcOrderItem->id,$wcOrderItem->variation_id); + $variation_product_sku = $this->getSKUByShopId($wcOrderItem->product_id,$wcOrderItem->variation_id); if (!empty($variation_product_sku)) { $orderItem['articleid'] = $variation_product_sku; } From 1710318e80bd39fea4e144e18cbaa9af46f8970b Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sun, 15 Sep 2024 16:05:33 +0200 Subject: [PATCH 4/9] bugfix erpapi importauftrag shopextid --- www/lib/class.erpapi.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/lib/class.erpapi.php b/www/lib/class.erpapi.php index ade72442..59ff99ea 100644 --- a/www/lib/class.erpapi.php +++ b/www/lib/class.erpapi.php @@ -19040,7 +19040,7 @@ function CheckShopTabelle($artikel) } } - return array("status" => true, "$auftragid" => $auftrag); + return array("status" => true, "auftragid" => $auftrag); } From ffaca2a7f3df33c7c04539fa13a23151b374816e Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sun, 15 Sep 2024 16:06:44 +0200 Subject: [PATCH 5/9] bugfix woocommerce shoprueckmeldung --- www/pages/shopimporter_woocommerce.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/www/pages/shopimporter_woocommerce.php b/www/pages/shopimporter_woocommerce.php index 2e1bda94..8e2bc802 100644 --- a/www/pages/shopimporter_woocommerce.php +++ b/www/pages/shopimporter_woocommerce.php @@ -202,9 +202,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'warenkorb' => base64_encode(serialize($order)), ]; } - return $tmp; - } // This function searches the wcOrder for the specified WC Meta key @@ -424,19 +422,20 @@ class Shopimporter_Woocommerce extends ShopimporterBase { /** @var OrderStatusUpdateRequest $data */ $data = $this->CatchRemoteCommand('data'); + if ($data->orderStatus !== OrderStatus::Completed) return; $trackingCode = $data->shipments[0]?->trackingNumber; if (!empty($trackingCode)) { - $this->client->post('orders/'.$data->orderId.'/notes', [ + $this->client->post('orders/'.$data->shopOrderId.'/notes', [ 'note' => 'Tracking Code: ' . $trackingCode ]); $this->logger->info("WooCommerce Tracking Code Rückmeldung für Auftrag: ".$data->orderId, [ - 'orderId' => $data->orderId, + 'orderId' => $data->shopOrderId, 'trackingCode' => $trackingCode ] ); @@ -455,11 +454,11 @@ class Shopimporter_Woocommerce extends ShopimporterBase ] ], ]; - $this->client->put('orders/'.$data->orderId, $updateData); + $this->client->put('orders/'.$data->shopOrderId, $updateData); $this->logger->info("WooCommerce Statusrückmeldung 'completed' für Auftrag: ".$data->orderId, [ - 'orderId' => $data->orderId, + 'orderId' => $data->shopOrderId, 'status' => $this->statusCompleted ] ); From 24f6623016d0fed322980820f3d82655ad98763e Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sun, 15 Sep 2024 16:32:38 +0200 Subject: [PATCH 6/9] bugfix OrderStatusUpdateRequest shipments default value empty array --- classes/Modules/Onlineshop/Data/OrderStatusUpdateRequest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Modules/Onlineshop/Data/OrderStatusUpdateRequest.php b/classes/Modules/Onlineshop/Data/OrderStatusUpdateRequest.php index 093dae93..80281628 100644 --- a/classes/Modules/Onlineshop/Data/OrderStatusUpdateRequest.php +++ b/classes/Modules/Onlineshop/Data/OrderStatusUpdateRequest.php @@ -26,7 +26,7 @@ class OrderStatusUpdateRequest /** * @var Shipment[] list of shipments for this order */ - public array $shipments; + public array $shipments = array(); public function getTrackingNumberList() : array { $list = []; @@ -45,4 +45,4 @@ class OrderStatusUpdateRequest } return $list; } -} \ No newline at end of file +} From c7b84603d4d173e6492bb93d5f4a8e58b218054e Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Sun, 15 Sep 2024 16:33:39 +0200 Subject: [PATCH 7/9] Bugfix woocommerce ImportUpdateAuftrag tracking --- www/pages/shopimporter_woocommerce.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/www/pages/shopimporter_woocommerce.php b/www/pages/shopimporter_woocommerce.php index 8e2bc802..08820672 100644 --- a/www/pages/shopimporter_woocommerce.php +++ b/www/pages/shopimporter_woocommerce.php @@ -426,7 +426,9 @@ class Shopimporter_Woocommerce extends ShopimporterBase if ($data->orderStatus !== OrderStatus::Completed) return; - $trackingCode = $data->shipments[0]?->trackingNumber; + if (isset($data->shipments)) { + $trackingCode = $data->shipments[0]?->trackingNumber; + } if (!empty($trackingCode)) { $this->client->post('orders/'.$data->shopOrderId.'/notes', [ @@ -446,7 +448,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'meta_data' => [ [ 'key' => 'tracking_code', - 'value' => $data->shipments[0]?->trackingNumber + 'value' => $trackingCode ], [ 'key' => 'shipping_carrier', From 6f197e257ccce0426d8a716394abe97740148f60 Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Tue, 17 Sep 2024 14:07:01 +0200 Subject: [PATCH 8/9] shopimport use grouprice of shop --- www/lib/class.erpapi.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/www/lib/class.erpapi.php b/www/lib/class.erpapi.php index 59ff99ea..5be8c239 100644 --- a/www/lib/class.erpapi.php +++ b/www/lib/class.erpapi.php @@ -18526,7 +18526,26 @@ function CheckShopTabelle($artikel) if(!empty($anummer)){ $value['articleid'] = $anummer; } - $ap = $this->AddAuftragPositionNummer($auftrag,$value['articleid'],$value['quantity'],$projekt,"",true, $doctype, $warenkorb['articlelist'][$key]); + $gruppenpreis = $this->GetVerkaufspreisGruppe($j_id,$value['quantity'],$shopexportArr['preisgruppe'],$waehrung); + if ($gruppenpreis) { + $ap = $this->AddPositionManuellPreisNummer( + $doctype, + $auftrag, + $projekt, + $value['articleid'], + $value['quantity'], + $value['name'], + $gruppenpreis, + $j_umsatzsteuer, + $value['rabatt'], + $shop, + $waehrung, + $warenkorb['articlelist'][$key], + $warenkorb['articlelist'] + ); + } else { + $ap = $this->AddAuftragPositionNummer($auftrag,$value['articleid'],$value['quantity'],$projekt,"",true, $doctype, $warenkorb['articlelist'][$key]); + } if(isset($value['webid'])){ $this->app->DB->Update("UPDATE $doctype"."_position SET webid = '".$this->app->DB->real_escape_string($value['webid'])."' WHERE id = '$ap' LIMIT 1"); } From a358125eae9c0a97cfbe2563890007d6b7291c9b Mon Sep 17 00:00:00 2001 From: OpenXE <> Date: Wed, 18 Sep 2024 15:50:48 +0200 Subject: [PATCH 9/9] woocommerce ignore_ssl option --- www/pages/shopimporter_woocommerce.php | 28 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/www/pages/shopimporter_woocommerce.php b/www/pages/shopimporter_woocommerce.php index 08820672..64d93143 100644 --- a/www/pages/shopimporter_woocommerce.php +++ b/www/pages/shopimporter_woocommerce.php @@ -806,6 +806,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase } $this->protokoll = $preferences['felder']['protokoll']; + $this->ssl_ignore = $preferences['felder']['ssl_ignore']; $ImportWooCommerceApiSecret = $preferences['felder']['ImportWoocommerceApiSecret']; $ImportWooCommerceApiKey = $preferences['felder']['ImportWoocommerceApiKey']; $ImportWooCommerceApiUrl = $preferences['felder']['ImportWoocommerceApiUrl']; @@ -825,7 +826,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase //WooCommerce API Secret $ImportWooCommerceApiSecret, ["query_string_auth" => true], - $this->logger + $this->logger, + $this->ssl_ignore ); } @@ -868,7 +870,8 @@ class Shopimporter_Woocommerce extends ShopimporterBase $ImportWooCommerceApiKey, $ImportWooCommerceApiSecret, ['query_string_auth' => true], - $this->logger + $this->logger, + $this->ssl_ignore ); $auth = $this->ImportAuth(); @@ -969,6 +972,7 @@ class Shopimporter_Woocommerce extends ShopimporterBase 'archiv'=>array('ab_nummer'), 'felder'=>array( // 'protokoll'=>array('typ'=>'checkbox','bezeichnung'=>'Protokollierung im Logfile:'), + 'ssl_ignore'=>array('typ'=>'checkbox','bezeichnung'=>'SSL-Prüfung abschalten:','info' => 'Nur für Testzwecke!'), 'ImportWoocommerceApiKey'=>array('typ'=>'text','bezeichnung'=>'{|API Key:','size'=>60), 'ImportWoocommerceApiSecret'=>array('typ'=>'text','bezeichnung'=>'{|API Secret|}:','size'=>60), 'ImportWoocommerceApiUrl'=>array('typ'=>'text','bezeichnung'=>'{|API Url|}:','size'=>40), @@ -1027,6 +1031,8 @@ class WCClient /** @var Logger $logger */ public $logger; + public $ssl_ignore = false; + /** * Initialize client. * @@ -1037,9 +1043,9 @@ class WCClient * * @throws WCHttpClientException */ - public function __construct($url, $consumerKey, $consumerSecret, $options = [], $logger) + public function __construct($url, $consumerKey, $consumerSecret, $options = [], $logger, $ssl_ignore) { - $this->http = new WCHttpClient($url, $consumerKey, $consumerSecret, $options, $logger); + $this->http = new WCHttpClient($url, $consumerKey, $consumerSecret, $options, $logger, $ssl_ignore); $this->logger = $logger; } @@ -1792,7 +1798,7 @@ class WCHttpClientException extends \Exception * @var WCResponse */ private $response; - + /** * Initialize exception. * @@ -1805,7 +1811,7 @@ class WCHttpClientException extends \Exception { parent::__construct($message, $code); - $this->request = $request; + $this->request = $request; $this->response = $response; } @@ -1890,6 +1896,8 @@ class WCHttpClient /** @var Logger $logger */ public $logger; + + public $ssl_ignore = false; /** * Initialize HTTP client. @@ -1901,7 +1909,7 @@ class WCHttpClient * * @throws WCHttpClientException */ - public function __construct($url, $consumerKey, $consumerSecret, $options, $logger) + public function __construct($url, $consumerKey, $consumerSecret, $options, $logger, $ssl_ignore) { if (!function_exists('curl_version')) { throw new WCHttpClientException('cURL is NOT installed on this server', -1, new WCRequest(), new WCResponse()); @@ -1912,6 +1920,7 @@ class WCHttpClient $this->consumerKey = $consumerKey; $this->consumerSecret = $consumerSecret; $this->logger = $logger; + $this->ssl_ignore = $ssl_ignore; } /** @@ -2123,7 +2132,10 @@ class WCHttpClient */ protected function setDefaultCurlSettings() { -// $verifySsl = $this->options->verifySsl(); + if (!$this->ssl_ignore) { + $verifySsl = $this->options->verifySsl(); + } + $timeout = $this->options->getTimeout(); $followRedirects = $this->options->getFollowRedirects();