diff --git a/www/lib/class.remote.php b/www/lib/class.remote.php index 8fa23b2c..05d71eec 100644 --- a/www/lib/class.remote.php +++ b/www/lib/class.remote.php @@ -1,4 +1,4 @@ - +*/ +?> app->erp->CreateDatei($path_parts['basename'], 'Shopbild', '', '', base64_decode($v['content']), 'Cronjob'); + $tmpfilename = tempnam($this->app->erp->GetTMP(), 'img'); + file_put_contents($tmpfilename, base64_decode($v['content'])); + $fileid = $this->app->erp->CreateDatei($path_parts['basename'], 'Shopbild', '', '', $tmpfilename, 'Cronjob'); $this->app->erp->AddDateiStichwort($fileid, 'Shopbild', 'artikel', $articleid); + if (@is_file($tmpfilename)) + unlink($tmpfilename); } } }elseif($dateien[0]['subjekt'] === 'shopbild'){ @@ -766,12 +770,16 @@ class Remote if($v['path'] != '' && $v['content'] != '') { $path_parts = pathinfo($v['path']); - $fileid = $this->app->erp->CreateDatei($path_parts['basename'], 'Shopbild', '', '', base64_decode($v['content']), 'Cronjob'); + $tmpfilename = tempnam($this->app->erp->GetTMP(), 'img'); + file_put_contents($tmpfilename, base64_decode($v['content'])); + $fileid = $this->app->erp->CreateDatei($path_parts['basename'], 'Shopbild', '', '', $tmpfilename, 'Cronjob'); if(isset($v['id'])) { $this->ShopexportMappingSet($id, 'datei', $fileid, $v['id'], $articleid); } $this->app->erp->AddDateiStichwort($fileid, 'Shopbild', 'artikel', $articleid); + if (@is_file($tmpfilename)) + unlink($tmpfilename); } } } diff --git a/www/pages/appstore.php b/www/pages/appstore.php index ad3f857b..5ada3d28 100644 --- a/www/pages/appstore.php +++ b/www/pages/appstore.php @@ -1,4 +1,4 @@ - +*/ +?> array('Bezeichnung'=>'Presta', 'Link'=>'index.php?module=onlineshops&action=create&cmd=shopimporter_presta', 'Icon'=>'Icons_dunkel_1.gif', - 'Versionen'=>'ENT','install'=>true, 'beta' => false,'kategorie'=>'{|Shop Schnittstelle|}') + 'Versionen'=>'ALL','install'=>true, 'beta' => false,'kategorie'=>'{|Shop Schnittstelle|}') ,'shopimporter_shopify'=>array( 'Bezeichnung'=>'Shopify API Advanced', 'Link'=>'index.php?module=onlineshops&action=create&cmd=shopimporter_shopify', diff --git a/www/pages/shopimporter_presta.php b/www/pages/shopimporter_presta.php new file mode 100644 index 00000000..7ee9eae2 --- /dev/null +++ b/www/pages/shopimporter_presta.php @@ -0,0 +1,417 @@ + 'de', 1 => 'en']; + private $taxationByDestinationCountry; + + + public function __construct($app, $intern = false) + { + $this->app = $app; + $this->intern = $intern; + if ($intern) + return; + + } + + public function EinstellungenStruktur() + { + return [ + 'ausblenden' => ['abholmodus' => ['ab_nummer', 'zeitbereich']], + 'functions' => ['getarticlelist'], + 'felder' => [ + 'protokoll' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Protokollierung im Logfile|}:' + ], + 'textekuerzen' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Texte bei Artikelexport auf Maximallänge kürzen|}:' + ], + 'useKeyAsParameter' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Shop Version ist mindestens 1.6.1.1|}:' + ], + 'apikey' => [ + 'typ' => 'text', + 'bezeichnung' => '{|API Key|}:', + 'size' => 40, + ], + 'shopurl' => [ + 'typ' => 'text', + 'bezeichnung' => '{|Shop URL|}:', + 'size' => 40, + ], + 'shopidpresta' => [ + 'typ' => 'text', + 'bezeichnung' => '{|Shop ID des Shops|}:', + 'size' => 40, + ], + 'steuergruppen' => [ + 'typ' => 'text', + 'bezeichnung' => '{|Steuergruppenmapping|}:', + 'size' => 40, + ], + 'zustand' => [ + 'typ' => 'text', + 'bezeichnung' => '{|Freifeld Zustand|}:', + 'size' => 40, + ], + 'abholen' => [ + 'typ' => 'text', + 'bezeichnung' => '{|\'Abholen\' Status IDs|}:', + 'size' => 40, + ], + 'bearbeitung' => [ + 'typ' => 'text', + 'bezeichnung' => '{|\'In Bearbeitung\' Status IDs|}:', + 'size' => 40, + ], + 'abgeschlossen' => [ + 'typ' => 'text', + 'bezeichnung' => '{|\'Abgeschlossen\' Status IDs|}:', + 'size' => 40, + ], + 'autoerstellehersteller' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Fehlende Hersteller automatisch anlegen|}:', + 'col' => 2 + ], + 'zeigezustand' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Artikelzustand im Shop anzeigen|}:', + 'col' => 2 + ], + 'zeigepreis' => [ + 'typ' => 'checkbox', + 'bezeichnung' => '{|Artikelpreis im Shop anzeigen|}:', + 'col' => 2 + ], + ] + ]; + } + + public function getKonfig($shopid, $data) + { + $this->shopid = $shopid; + $this->data = $data; + $importerSettings = $this->app->DB->SelectArr("SELECT `einstellungen_json` FROM `shopexport` WHERE `id` = '$shopid' LIMIT 1"); + $importerSettings = reset($importerSettings); + + $einstellungen = []; + if (!empty($importerSettings['einstellungen_json'])) { + $einstellungen = json_decode($importerSettings['einstellungen_json'], true); + } + $this->protocol = $einstellungen['felder']['protokoll']; + $this->apiKey = $einstellungen['felder']['apikey']; + $this->shopUrl = rtrim($einstellungen['felder']['shopurl'], '/') . '/'; + if ($einstellungen['felder']['autoerstellehersteller'] === '1') { + $this->createManufacturerAllowed = true; + } + $this->idsabholen = $einstellungen['felder']['abholen']; + $this->idbearbeitung = $einstellungen['felder']['bearbeitung']; + $this->idabgeschlossen = $einstellungen['felder']['abgeschlossen']; + $query = sprintf('SELECT `steuerfreilieferlandexport` FROM `shopexport` WHERE `id` = %d', $this->shopid); + $this->taxationByDestinationCountry = !empty($this->app->DB->Select($query)); + } + + public function ImportAuth() { + $ch = curl_init($this->shopUrl); + curl_setopt($ch, CURLOPT_USERNAME, $this->apiKey); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); + if ($code == 200) + return 'success'; + + return $response; + } + + public function ImportDeleteAuftrag() + { + $auftrag = $this->data['auftrag']; + + $obj = $this->prestaRequest('GET', 'order_histories?schema=blank'); + $obj->order_history->id_order = $auftrag; + $obj->order_history->id_order_state = $this->idbearbeitung; + + $this->prestaRequest('POST', 'order_histories', $obj->asXML()); + } + + public function ImportUpdateAuftrag() + { + $auftrag = $this->data['auftrag']; + + $obj = $this->prestaRequest('GET', 'order_histories?schema=blank'); + $obj->order_history->id_order = $auftrag; + $obj->order_history->id_order_state = $this->idabgeschlossen; + + $this->prestaRequest('POST', 'order_histories', $obj->asXML()); + + //TODO Tracking + } + + public function ImportGetAuftraegeAnzahl() + { + $ordersToProcess = $this->getOrdersToProcess($this->getOrderSearchLimit()); + return count($ordersToProcess); + } + + public function ImportGetAuftrag() + { + $voucherArticleId = $this->app->DB->Select("SELECT s.artikelrabatt FROM `shopexport` AS `s` WHERE s.id='$this->shopid' LIMIT 1"); + $voucherArticleNumber = $this->app->DB->Select("SELECT a.nummer FROM `artikel` AS `a` WHERE a.id='$voucherArticleId' LIMIT 1"); + + if (empty($this->idsabholen)) { + return false; + } + $expectOrderArray = !empty($this->data['anzgleichzeitig']) && (int)$this->data['anzgleichzeitig'] > 1; + $expectNumber = !empty($this->data['nummer']); + if ($expectNumber) { + $ordersToProcess = [$this->data['nummer']]; + } elseif (!$expectOrderArray) { + $ordersToProcess = $this->getOrdersToProcess(1); + } else { + $ordersToProcess = $this->getOrdersToProcess($this->getOrderSearchLimit()); + } + + $fetchedOrders = []; + foreach ($ordersToProcess as $currentOrderId) { + $this->Log("Importing order from presta", [$this->data, $ordersToProcess, $currentOrderId]); + $order = $this->prestaRequest('GET', "orders/$currentOrderId"); + $order = $order->order; + $cart = []; + $cart['zeitstempel'] = strval($order->date_add); + $cart['auftrag'] = strval($order->id); + $cart['onlinebestellnummer'] = strval($order->reference); + $cart['gesamtsumme'] = strval($order->total_paid); + $cart['versandkostenbrutto'] = strval($order->total_shipping); + $cart['bestelldatum'] = strval($order->date_add); + + $carrier = $this->prestaRequest('GET', "carriers/$order->id_carrier"); + $cart['lieferung'] = strval($carrier->name); + + $customer = $this->prestaRequest('GET', "customers/$order->id_customer"); + $cart['email'] = strval($customer->email); + + $invoiceAddress = $this->prestaRequest('GET', "addresses/$order->id_address_invoice"); + $invoiceAddress = $invoiceAddress->address; + $invoiceCountry = $this->prestaRequest('GET', "countries/$invoiceAddress->id_country"); + $invoiceCountry = $invoiceCountry->country; + $cart['name'] = "$invoiceAddress->firstname $invoiceAddress->lastname"; + if (!empty($invoiceAddress->company)) { + $cart['ansprechpartner'] = $cart['name']; + $cart['name'] = strval($invoiceAddress->company); + } + $cart['strasse'] = strval($invoiceAddress->address1); + $cart['adresszusatz'] = strval($invoiceAddress->address2); + $cart['telefon'] = strval($invoiceAddress->phone_mobile); + if (empty($cart['telefon'])) + $cart['telefon'] = strval($invoiceAddress->phone); + $cart['plz'] = strval($invoiceAddress->postcode); + $cart['ort'] = strval($invoiceAddress->city); + $cart['ustid'] = strval($invoiceAddress->vat_number); + $cart['land'] = strval($invoiceCountry->iso_code); + + if ($order->id_address_invoice != $order->id_address_delivery) { + $deliveryAddress = $this->prestaRequest('GET', "addresses/$order->id_address_delivery"); + $deliveryAddress = $deliveryAddress->address; + $deliveryCountry = $this->prestaRequest('GET', "countries/$deliveryAddress->id_country"); + $deliveryCountry = $deliveryCountry->country; + $cart['abweichendelieferadresse'] = 1; + $cart['lieferadresse_name'] = "$deliveryAddress->firstname $deliveryAddress->lastname"; + if (!empty($deliveryAddress->company)) { + $cart['lieferadresse_ansprechpartner'] = $cart['lieferadresse_name']; + $cart['lieferadresse_name'] = strval($deliveryAddress->company); + } + $cart['lieferadresse_strasse'] = strval($deliveryAddress->address1); + $cart['lieferadresse_adresszusatz'] = strval($deliveryAddress->address2); + $cart['lieferadresse_plz'] = strval($deliveryAddress->postcode); + $cart['lieferadresse_ort'] = strval($deliveryAddress->city); + $cart['lieferadresse_land'] = strval($deliveryCountry->iso_code); + } + + //TODO + //$cart['transaktionsnummer'] + $cart['zahlungsweise'] = strval($order->payment); + + $taxedCountry = $cart['land']; + if (!empty($cart['lieferadresse_land']) && $this->taxationByDestinationCountry) { + $taxedCountry = $cart['lieferadresse_land']; + } + if (strval($order->total_paid_tax_incl) === strval($order->total_paid_tax_excl)) { + if ($this->app->erp->IstEU($taxedCountry)) { + $cart['ust_befreit'] = 1; + } elseif ($this->app->erp->Export($taxedCountry)) { + $cart['ust_befreit'] = 2; + } else { + $cart['ust_befreit'] = 3; + } + } + + $cart['articlelist'] = []; + foreach ($order->associations->order_rows->order_row as $order_row) { + + $steuersatz = (strval($order_row->unit_price_tax_incl) / strval($order_row->unit_price_tax_excl)) - 1; + $steuersatz = round($steuersatz, 1); + + $cart['articlelist'][] = [ + 'articleid' => strval($order_row->product_reference), + 'name' => strval($order_row->product_name), + 'quantity' => strval($order_row->product_quantity), + 'price_netto' => strval($order_row->product_price), + 'steuersatz' => $steuersatz + ]; + } + + $fetchedOrders[] = [ + 'id' => $cart['auftrag'], + 'sessionid' => '', + 'logdatei' => '', + 'warenkorb' => base64_encode(serialize($cart)), + 'warenkorbjson' => base64_encode(json_encode($cart)), + ]; + } + $this->Log('Precessed order from presta', $fetchedOrders); + + return $fetchedOrders; + } + + public function ImportGetArticleList() + { + $result = []; + $response = $this->prestaRequest('GET', 'products?display=[reference]'); + foreach ($response->products->product as $product) { + $result[] = $product->reference; + } + + array_unique($result); + return $result; + } + + public function ImportGetArticle() + { + $nummer = $this->data['nummer']; + if (isset($this->data['nummerintern'])) { + $nummer = $this->data['nummerintern']; + } + $nummer = trim($nummer); + + if (empty($nummer)) + return; + + $searchresult = $this->prestaRequest('GET', 'products?filter[reference]='.$nummer); + if (empty($searchresult)) { + $this->Log('No product found in Shop', $this->data); + return; + } + if (count($searchresult->products->product) > 1) { + $this->Log('Got multiple results from Shop', $this->data); + } + + $productid = $searchresult->products->product->attributes()->id; + $product = $this->prestaRequest('GET', "products/$productid"); + $res = []; + $res['nummer'] = strval($product->product->reference); + $res['artikelnummerausshop'] = strval($product->product->reference); + $names = $this->toMultilangArray($product->product->name->language); + $descriptions = $this->toMultilangArray($product->product->description->language); + $shortdescriptions = $this->toMultilangArray($product->product->description_short->language); + $res['name'] = $names['de']; + $res['name_en'] = $names['en']; + $res['uebersicht_de'] = $descriptions['de']; + $res['uebersicht_en'] = $descriptions['en']; + $res['preis_netto'] = strval($product->product->price); + $res['hersteller'] = strval($product->product->manufacturer_name); + $res['ean'] = strval($product->product->ean13); + + $images = []; + foreach ($product->product->associations->images->image as $img) { + $endpoint = "images/products/$productid/$img->id"; + $imgdata = $this->prestaRequest('GET', $endpoint, '', true); + $images[] = [ + 'content' => base64_encode($imgdata), + 'path' => "$img->id.jpg", + 'id' => $img->id + ]; + } + $res['bilder'] = $images; + return $res; + } + + private function toMultilangArray($xmlnode) { + $res = []; + foreach ($xmlnode as $item) { + $iso = $this->langidToIso[strval($item->attributes()->id)]; + $res[$iso] = strval($item); + } + return $res; + } + + private function getOrdersToProcess(int $limit) + { + $states = implode('|', explode(',', $this->idsabholen)); + $response = $this->prestaRequest('GET', "orders?display=[id]&limit=$limit&filter[current_state]=[$states]"); + $result = []; + foreach ($response->orders->order as $order) { + $result[] = strval($order->id); + } + return $result; + } + + public function getOrderSearchLimit(): int + { + if(in_array($this->orderSearchLimit, ['50', '75', '100'])) { + return (int)$this->orderSearchLimit; + } + + return 25; + } + + private function Log($message, $dump = '') + { + if ($this->protocol) { + $this->app->erp->Logfile($message, print_r($dump, true)); + } + } + + private function prestaRequest($method, $endpoint, $data = '', $raw = false) + { + $url = $this->shopUrl . $endpoint; + $url = str_replace('[', '%5b', $url); + $url = str_replace(']', '%5d', $url); + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + if (!empty($data)) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + curl_setopt($ch, CURLOPT_USERNAME, $this->apiKey); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + if (curl_error($ch)) { + $this->error[] = curl_error($ch); + } + curl_close($ch); + + if ($raw) + return $response; + + return simplexml_load_string($response); + } +} \ No newline at end of file