diff --git a/config/services.yml b/config/services.yml old mode 100644 new mode 100755 diff --git a/config_it.xml b/config_it.xml index e313130d31546774123e2ba43390527117a00d3e..740dd887fb4207122549c322adb758eb6b31aaf8 100644 --- a/config_it.xml +++ b/config_it.xml @@ -2,10 +2,12 @@ <module> <name>ps_connect_io6</name> <displayName><![CDATA[ImporterONE Cloud Connector]]></displayName> - <version><![CDATA[1.3.0]]></version> + <version><![CDATA[1.4.2]]></version> <description><![CDATA[Connette il tuo negozio con ImporterONE Cloud]]></description> <author><![CDATA[Imprimis]]></author> <tab><![CDATA[quick_bulk_update]]></tab> + <confirmUninstall><![CDATA[]]></confirmUninstall> <is_configurable>1</is_configurable> - <need_instance>1</need_instance> -</module> + <need_instance>0</need_instance> + <limited_countries></limited_countries> +</module> \ No newline at end of file diff --git a/controllers/AdminPsConnectIo6ActionsController.php b/controllers/AdminPsConnectIo6ActionsController.php old mode 100644 new mode 100755 index bacf66ffa714e05a01ba639d7858acf4faa4267d..42fbfb60b152091a6f82c02f45e5e6d27d2d08ab --- a/controllers/AdminPsConnectIo6ActionsController.php +++ b/controllers/AdminPsConnectIo6ActionsController.php @@ -50,7 +50,7 @@ class AdminPsConnectIo6ActionsController extends FrameworkBundleAdminController if ($module->active && !empty($io6_id_product)) { $res = $module->io6Sync($io6_id_product); } - + if (version_compare(_PS_VERSION_, '8.1', '>=') && $new_product_page && !empty($res)) { echo json_encode($res); die(); diff --git a/controllers/front/actions.php b/controllers/front/actions.php index de1b89a23d96a8a156d0a268dce16bd323efae67..3463dde571ceb6d7b7fb876e50765570e994d98c 100755 --- a/controllers/front/actions.php +++ b/controllers/front/actions.php @@ -83,6 +83,153 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController } } + public function displayAjaxExcludeProducts() + { + $this->processExcludeProducts(); + } + + public function processExcludeProducts(){ + try { + $sql = 'INSERT IGNORE INTO '. _DB_PREFIX_ .'importerone6connect_products + SELECT + p.id_product, + 0, + NULL, + 0, + \'\', + 1, + NULL, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + \'\', + 0, + NULL + FROM '. _DB_PREFIX_ .'product p + LEFT JOIN '. _DB_PREFIX_ .'importerone6connect_products ip ON ip.id_product = p.id_product + WHERE ip.id_product IS NULL'; + $res = Db::getInstance()->execute($sql); + + if ($res){ + echo json_encode(["success" => true, "message" => "Prodotti esclusi correttamente"]); + } else { + echo json_encode(["success" => false, "message" => "Errore durante lo spostamento dei prodotti"]); + } + } catch (Exception $e) { + echo json_encode(["success" => false, "message" => $e->getMessage()]); + } + } + + public function displayAjaxIncludeProducts() + { + $this->processIncludeProducts(); + } + + public function processIncludeProducts(){ + try { + $sql = 'INSERT IGNORE INTO '. _DB_PREFIX_ .'importerone6connect_products + SELECT + p.id_product, + 0, + NULL, + 0, + \'\', + 0, + NULL, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + \'\', + 0, + NULL + FROM '. _DB_PREFIX_ .'product p + LEFT JOIN '. _DB_PREFIX_ .'importerone6connect_products ip ON ip.id_product = p.id_product + WHERE ip.id_product IS NULL'; + $res = Db::getInstance()->execute($sql); + + if ($res){ + echo json_encode(["success" => true, "message" => "Prodotti inclusi correttamente"]); + } else { + echo json_encode(["success" => false, "message" => "Errore durante lo spostamento dei prodotti"]); + } + } catch (Exception $e) { + echo json_encode(["success" => false, "message" => $e->getMessage()]); + } + } + + public function displayAjaxDownloadNotIO6Catalog() + { + $this->processDownloadNotIO6Catalog(); + } + + public function processDownloadNotIO6Catalog(){ + try { + $sql = "SELECT DISTINCT p.id_product, p.ean13, p.reference, p.mpn, pl.name FROM ". _DB_PREFIX_ ."product p + INNER JOIN ". _DB_PREFIX_ ."product_lang pl ON pl.id_product = p.id_product + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_products ip ON ip.id_product = p.id_product + WHERE ip.id_product IS NULL"; + $productNotInIo6Tables = Db::getInstance()->executeS($sql); + + if(!empty($productNotInIo6Tables)){ + $this->prepareCSV($productNotInIo6Tables, 'product_not_in_io6_tables'); + } + + } catch (Exception $e) { + echo json_encode(["success" => false, "message" => $e->getMessage()]); + } + } + + public function displayAjaxExportCategoriesTree() + { + $this->processExportCategoriesTree(); + } + + public function processExportCategoriesTree(){ + try { + $sql = "SELECT DISTINCT c.id_category, c.id_parent, TRIM(cl.name) as name FROM ". _DB_PREFIX_ ."category c + INNER JOIN ". _DB_PREFIX_ ."category_lang cl ON cl.id_category = c.id_category + WHERE c.active = 1 AND c.level_depth != 0 AND c.is_root_category = 0 + ORDER BY c.id_parent ASC, c.id_category ASC"; + $categories_tree = Db::getInstance()->executeS($sql); + + foreach (Shop::getShops() as $shop) { + $root_category = Db::getInstance()->getValue("SELECT id_category FROM ". _DB_PREFIX_ ."category c + WHERE c.is_root_category = 1 AND c.id_shop_default = ". $shop['id_shop']); + + foreach ($categories_tree as $key => $category) { + if ($category['id_parent'] == $root_category){ + $categories_tree[$key]['id_parent'] = 0; + } + } + } + + if(!empty($categories_tree)){ + $this->prepareCSV($categories_tree, 'prestashop_categories_tree'); + } + + } catch (Exception $e) { + echo json_encode(["success" => false, "message" => $e->getMessage()]); + } + } + public function displayAjaxExpandStatisticInfo() { $this->processExpandStatisticInfo(); @@ -112,7 +259,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_immagini_da_scaricare'); + $this->prepareCSV($result, 'io6_immagini_da_scaricare'); } } else { echo json_encode($rows); @@ -131,7 +278,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_prestashop'); + $this->prepareCSV($result, 'io6_prodotti_prestashop'); } } else { echo json_encode($rows); @@ -151,7 +298,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_ImporterONE'); + $this->prepareCSV($result, 'io6_prodotti_ImporterONE'); } } else { echo json_encode($rows); @@ -173,7 +320,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_con_immagini'); + $this->prepareCSV($result, 'io6_prodotti_con_immagini'); } } else { echo json_encode($rows); @@ -195,7 +342,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_senza_immagini'); + $this->prepareCSV($result, 'io6_prodotti_senza_immagini'); } } else { echo json_encode($rows); @@ -215,7 +362,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_senza_margine'); + $this->prepareCSV($result, 'io6_prodotti_senza_margine'); } } else { echo json_encode($rows); @@ -227,7 +374,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController SELECT p2.reference FROM "._DB_PREFIX_."product p INNER JOIN "._DB_PREFIX_."product p2 ON p2.id_product = p.id_product - WHERE p2.reference = p.reference + WHERE p2.reference = p.reference AND p2.reference != '' AND p.reference != '' GROUP BY p2.reference HAVING COUNT(p2.reference) > 1) pf INNER JOIN "._DB_PREFIX_."product p ON p.reference = pf.reference"; @@ -239,7 +386,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_con_stesso_reference'); + $this->prepareCSV($result, 'io6_prodotti_con_stesso_reference'); } } else { echo json_encode($rows); @@ -251,7 +398,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController SELECT p2.mpn FROM "._DB_PREFIX_."product p INNER JOIN "._DB_PREFIX_."product p2 ON p2.id_product = p.id_product - WHERE p2.mpn = p.mpn + WHERE p2.mpn = p.mpn AND p2.mpn != '' AND p.mpn != '' GROUP BY p2.mpn HAVING COUNT(p2.mpn) > 1) pf INNER JOIN "._DB_PREFIX_."product p ON p.mpn = pf.mpn"; @@ -263,7 +410,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_con_stesso_mpn'); + $this->prepareCSV($result, 'io6_prodotti_con_stesso_mpn'); } } else { echo json_encode($rows); @@ -275,7 +422,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController SELECT p2.ean13 FROM "._DB_PREFIX_."product p INNER JOIN "._DB_PREFIX_."product p2 ON p2.id_product = p.id_product - WHERE p2.ean13 = p.ean13 + WHERE p2.ean13 = p.ean13 AND p2.ean13 != '' AND p.ean13 != '' GROUP BY p2.ean13 HAVING COUNT(p2.ean13) > 1) pf INNER JOIN "._DB_PREFIX_."product p ON p.ean13 = pf.ean13"; @@ -287,7 +434,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController if($download){ if(!empty($result)){ - $this->prepareStatisticCSV($result, 'io6_prodotti_con_stesso_ean'); + $this->prepareCSV($result, 'io6_prodotti_con_stesso_ean'); } } else { echo json_encode($rows); @@ -297,7 +444,7 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController } - private function prepareStatisticCSV($result, $filename){ + private function prepareCSV($result, $filename){ header('Content-Description: File Transfer'); header('Content-Type: application/csv'); header('Content-Disposition: attachment; filename="'.$filename.'.csv"'); @@ -402,4 +549,62 @@ class Ps_Connect_Io6ActionsModuleFrontController extends ModuleFrontController return $this->context->smarty->fetch(_PS_MODULE_DIR_ . $this->module->name .'/views/templates/admin/statistic_info.tpl'); } + public function displayAjaxDisableProducts() + { + $this->processDisableProducts(); + } + + public function processDisableProducts(){ + try { + if (!empty('catalogId')){ + $result = true; + $catalogId = Tools::getValue('catalogId'); + + $sql = 'UPDATE `' . _DB_PREFIX_ . 'product` product + INNER JOIN `' . _DB_PREFIX_ . 'importerone6connect_products` ioprod ON product.id_product = ioprod.id_product + SET product.`active` = 0 + WHERE product.`active` = 1 and ioprod.`sync_exclude` = 0 AND ioprod.io6_id_product > 0 AND ioprod.catalog_id = '.(int)$catalogId.';'; + $result &= Db::getInstance()->execute($sql); + + $sql = 'UPDATE `' . _DB_PREFIX_ . 'product_shop` p_shop + INNER JOIN `' . _DB_PREFIX_ . 'product` p ON p_shop.id_product = p.id_product + SET p_shop.active = p.active + WHERE p_shop.`active` = 1;'; + + $result &= Db::getInstance()->execute($sql); + + echo json_encode(['success' => $result]); + } else { + echo json_encode(['success' => false]); + } + } catch (Exception $e) { + echo json_encode(['success' => false]); + } + } + + public function displayAjaxMoveProducts() + { + $this->processMoveProducts(); + } + + public function processMoveProducts(){ + try { + if (!empty('catalogId')){ + $result = true; + $oldCatalogId = Tools::getValue('oldCatalogId'); + $newCatalogId = Tools::getValue('newCatalogId'); + + $sql = "UPDATE ". _DB_PREFIX_ ."importerone6connect_products ip SET ip.catalog_id = " . (int)$newCatalogId ." + WHERE ip.catalog_id = ". (int)$oldCatalogId; + + $result &= Db::getInstance()->execute($sql); + + echo json_encode(['success' => $result]); + } else { + echo json_encode(['success' => false]); + } + } catch (Exception $e) { + echo json_encode(['success' => false]); + } + } } diff --git a/core/src/classes/IO6Catalog.class.php b/core/src/classes/IO6Catalog.class.php index a907aba342d02155dd3a6954fcb50073ffa620f6..d6a05d577660d82caf5a182b2d05baca5f06c068 100644 --- a/core/src/classes/IO6Catalog.class.php +++ b/core/src/classes/IO6Catalog.class.php @@ -10,9 +10,13 @@ class IO6Catalog { public $id; public $name; + public $selected; + public $priceLists; function __construct($jCatalog) { $this->id = $jCatalog['id']; $this->name = $jCatalog['name']; + $this->selected = false; + $this->priceLists = []; } } diff --git a/core/src/classes/IO6Category.class.php b/core/src/classes/IO6Category.class.php index 29ca0e91ff44580a1b9216f45f919708e81cfa05..0bc8d35aaab3abb8bfa47e0564168c9ac61e2b98 100644 --- a/core/src/classes/IO6Category.class.php +++ b/core/src/classes/IO6Category.class.php @@ -15,7 +15,7 @@ class IO6Category { $this->parentId = $jCategory['parentId']; //TODO: EM20210318 => vedere se fare una get con le IO6API oppure aggiungerlo al json - $this->parentCode = !empty($jCategory['parentId']) ? str_pad($jCategory['parentId'], 10, '0', STR_PAD_LEFT) : ''; + $this->parentCode = !empty($jCategory['parentCode']) ? $jCategory['parentCode'] : ''; $this->name = $jCategory['name']; $this->subCategories = $subCategories; } diff --git a/core/src/classes/IO6ConnectConfiguration.class.php b/core/src/classes/IO6ConnectConfiguration.class.php index a5fa4667cf9e80dfe0fddc04b9b3a91c0be6e4d3..0add30cb5ce31ffa22bbdfad1987a3187848f1d0 100644 --- a/core/src/classes/IO6ConnectConfiguration.class.php +++ b/core/src/classes/IO6ConnectConfiguration.class.php @@ -4,8 +4,8 @@ class IO6ConnectConfiguration public $apiToken; public $apiEndPoint; public $catalogId; + public $catalogsData; - public $priceListId; public $pageSize; public $selectedBrandField; @@ -26,6 +26,7 @@ class IO6ConnectConfiguration public $manageStock; public $manageFeaturesHTML; public $manageTaxRule; + public $manageIo6Suppliers; public $concatFeaturesHTML; public $excludeNoImage; public $delayedDownloadsImages; @@ -44,7 +45,8 @@ class IO6ConnectConfiguration if (isset($configuration) && is_array($configuration) ) { $this->apiToken = array_key_exists('apitoken', $configuration) ? $configuration['apitoken'] : ''; $this->apiEndPoint = array_key_exists('apiendpoint', $configuration) ? $configuration['apiendpoint'] : ''; - $this->catalogId = array_key_exists('catalog', $configuration) ? (int)$configuration['catalog'] : ''; + $this->catalogId = array_key_exists('catalog', $configuration) ? explode(',', $configuration['catalog']) : ''; + $this->catalogsData = array_key_exists('catalogs', $configuration) ? unserialize($configuration['catalogs']) : ''; $this->languageCode = array_key_exists('languagecode', $configuration) ? $configuration['languagecode'] : ''; $this->tempFolder = array_key_exists('tempfolder', $configuration) ? $configuration['tempfolder'] : ''; @@ -52,8 +54,6 @@ class IO6ConnectConfiguration $this->selectedSkuField = array_key_exists('select_sku_field', $configuration) ? $configuration['select_sku_field'] : 'io6_sku_partNumber'; $this->selectedEanField = array_key_exists('select_ean_field', $configuration) ? $configuration['select_ean_field'] : 'io6_eancode'; $this->selectedPartNumberField = array_key_exists('select_partnumber_field', $configuration) ? $configuration['select_partnumber_field'] : 'io6_partnumber'; - - $this->priceListId = array_key_exists('price_list', $configuration) ? (int)$configuration['price_list'] : 0; $this->pageSize = array_key_exists('page_size', $configuration) ? (int)$configuration['page_size'] : 25; $this->manageImages = array_key_exists('manage_images', $configuration) ? $configuration['manage_images'] == 1 : false; @@ -69,6 +69,7 @@ class IO6ConnectConfiguration $this->manageCategories = array_key_exists('manage_categories', $configuration) ? $configuration['manage_categories'] == 1 : false; $this->manageFeaturesHTML = array_key_exists('manage_features_html', $configuration) ? $configuration['manage_features_html'] == 1 : false; $this->manageTaxRule = array_key_exists('manage_tax_rule', $configuration) ? $configuration['manage_tax_rule'] == 1 : false; + $this->manageIo6Suppliers = array_key_exists('manage_io6_suppliers', $configuration) ? $configuration['manage_io6_suppliers'] == 1 : false; $this->concatFeaturesHTML = array_key_exists('concat_features_html', $configuration) ? $configuration['concat_features_html'] == 1 : false; $this->featuresHTMLTemplate = array_key_exists('features_html_template', $configuration) ? $configuration['features_html_template'] : 0; $this->excludeNoImage = array_key_exists('exclude_noimage', $configuration) ? $configuration['exclude_noimage'] == 1 : false; @@ -84,8 +85,6 @@ class IO6ConnectConfiguration $this->selectedSkuField = 'io6_sku_partNumber'; $this->selectedEanField = 'io6_eancode'; $this->selectedPartNumberField = 'io6_partnumber'; - - $this->priceListId = 0; $this->pageSize = 25; $this->manageImages = true; @@ -101,6 +100,7 @@ class IO6ConnectConfiguration $this->manageDimensions = true; $this->manageWeight = true; $this->manageTaxRule = true; + $this->manageIo6Suppliers = true; $this->concatFeaturesHTML = true; $this->excludeNoImage = true; $this->delayedDownloadsImages = false; diff --git a/core/src/classes/IO6ConnectEngine.class.php b/core/src/classes/IO6ConnectEngine.class.php index 52f67fc8e923f6ada01c73ca0d9a14776b94a35d..ddbbc0053765b757d8e74f8f148cd2e496be32a9 100755 --- a/core/src/classes/IO6ConnectEngine.class.php +++ b/core/src/classes/IO6ConnectEngine.class.php @@ -51,7 +51,7 @@ class IO6ConnectEngine $jCatalogs = []; foreach ($jCatalogs as $jCatalog) { - $catalogs[] = new IO6Catalog($jCatalog); + $catalogs[$jCatalog['id']] = new IO6Catalog($jCatalog); } return $catalogs; @@ -61,11 +61,11 @@ class IO6ConnectEngine * Return array of IO6Supplier for current Catalog from API Call * @return array IO6Supplier */ - public function GetIO6Suppliers() + public function GetIO6Suppliers($catalogId) { $parameters = []; $parameters['onlyActive'] = 'true'; - $parameters['personalCatalogId'] = $this->configuration->catalogId; + $parameters['personalCatalogId'] = $catalogId; $jSuppliers = $this->callIO6API('suppliers', 'GET', $parameters); $suppliers = []; foreach ($jSuppliers as $jSupplier) { @@ -82,18 +82,18 @@ class IO6ConnectEngine * @param int $parentCategoryId ParentCategory to retrieve. * @return array IO6Category */ - public function GetIO6Categories($parentCategoryId = 0) + public function GetIO6Categories($catalogId, $parentCategoryId = 0) { $parameters = []; $parameters['parentId'] = $parentCategoryId; - $jCategories = $this->callIO6API(sprintf('catalogs/%s/categories/list', $this->configuration->catalogId), 'POST', $parameters); + $jCategories = $this->callIO6API(sprintf('catalogs/%s/categories/list', $catalogId), 'POST', $parameters); $categories = array(); foreach ($jCategories['items'] as $jCategory) { $subCategories = []; if ($jCategory['hasChildCategories'] == true) - $subCategories = $this->GetIO6Categories($jCategory['id']); + $subCategories = $this->GetIO6Categories($catalogId, $jCategory['id']); $categories[] = new IO6Category($jCategory, $subCategories); } @@ -101,10 +101,10 @@ class IO6ConnectEngine return $categories; } - public function GetIO6Brands() + public function GetIO6Brands($catalogId) { $parameters = []; - $jBrands = $this->callIO6API(sprintf('catalogs/%s/brands/list', $this->configuration->catalogId), 'POST', $parameters); + $jBrands = $this->callIO6API(sprintf('catalogs/%s/brands/list', $catalogId), 'POST', $parameters); $brands = array(); @@ -115,10 +115,8 @@ class IO6ConnectEngine return $brands; } - public function GetIO6Products($currentPage = 1, $pageSize = 0, $io6_id_product_syngle_sync = 0) + public function GetIO6Products($currentPage = 1, $pageSize = 0, $catalogId, $priceListId, $io6_id_product_syngle_sync = 0) { - session_start(); - $elementsFounds = isset($_SESSION['elementsfounds']) ? intval($_SESSION['elementsfounds']) : 0; $pages = isset($_SESSION['pages']) ? intval($_SESSION['pages']) : 0; $calculateFoundRows = $currentPage == 1 || $elementsFounds <= 0; @@ -126,7 +124,7 @@ class IO6ConnectEngine $retValue = array(); $parameters = []; - $parameters['priceListId'] = $this->configuration->priceListId; + $parameters['priceListId'] = $priceListId; $parameters['pageSize'] = $pageSize; $parameters['currentPage'] = $currentPage; $parameters['imagelimit'] = $this->configuration->imageLimit; @@ -138,10 +136,11 @@ class IO6ConnectEngine $parameters['isActive'] = 1; $parameters['isObsolete'] = 0; + //$parameters['ean'] = '4242004259015'; if (!empty($io6_id_product_syngle_sync)) $parameters['productIds'] = [$io6_id_product_syngle_sync]; - $results = $this->callIO6API(sprintf('catalogs/%s/products/search', $this->configuration->catalogId), 'POST', $parameters); + $results = $this->callIO6API(sprintf('catalogs/%s/products/search', $catalogId), 'POST', $parameters); $products = array(); @@ -163,15 +162,14 @@ class IO6ConnectEngine if($currentPage == $pages){ $_SESSION['elementsfounds'] = 0; $_SESSION['pages'] = 0; - //session_destroy(); } return $retValue; } - public function GetIO6PriceLists() + public function GetIO6PriceLists($catalogId) { $parameters = []; - $jPriceLists = $this->callIO6API(sprintf('catalogs/%s/pricelists', $this->configuration->catalogId), 'GET', $parameters); + $jPriceLists = $this->callIO6API(sprintf('catalogs/%s/pricelists', $catalogId), 'GET', $parameters); // if(empty($jPriceLists)) // $jPriceLists = []; diff --git a/core/src/classes/IO6PriceList.class.php b/core/src/classes/IO6PriceList.class.php index 7587f7909d64a451f4b44f95ab0fba1869e928d1..2620bcd3689bef22bda63933928f3641791c3b7a 100644 --- a/core/src/classes/IO6PriceList.class.php +++ b/core/src/classes/IO6PriceList.class.php @@ -4,11 +4,13 @@ class IO6PriceList { public $id; public $name; + public $selected; function __construct($jPriceList) { $this->id = $jPriceList['id']; $this->name = $jPriceList['name']; + $this->selected = false; } } diff --git a/core/src/classes/IO6Product.class.php b/core/src/classes/IO6Product.class.php old mode 100644 new mode 100755 diff --git a/cron.php b/cron.php index 51f900413e3b91f400583f3940e1afe7e30a1af8..65b7b293c53bbdfd71aa3e4d9f85f9eb3c222570 100644 --- a/cron.php +++ b/cron.php @@ -1,4 +1,4 @@ -<?php +<?php //echo("OK..."); //die(); @@ -16,34 +16,36 @@ if (Tools::isPHPCLI()) { error_reporting(E_ERROR | E_WARNING | E_PARSE); } -$currentPage = 1; -$totalPages = 1; - -$totalRows = -1; $actionUrl = isset($argv) && count($argv) > 1 ? $argv[1] : ''; - +$catalogsSelected = unserialize(Configuration::get('IMPORTERONE6CONNECT_CATALOGS', [])); if($actionUrl != '') { - $contents = ''; - - while ($currentPage <= $totalPages) { - try { - $callUrl = $actionUrl . '&page=' . $currentPage; - $results = get_web_page($callUrl); - - $totalPages = $results['pages']; - - echo sprintf('Totale prodotti: %s. Pagine: %s di %s'. PHP_EOL, $results['elementsFounds'], $currentPage , $totalPages); - $currentPage++; - - } - catch(Exception $e) { - $totalPages=-1; - echo($e->getMessage() . PHP_EOL); - } - } - die('Update from ImporterONE Cloud terminata'); + + foreach ($catalogsSelected as $catalog) { + $contents = ''; + + $currentPage = 1; + $totalPages = 1; + + while ($currentPage <= $totalPages) { + try { + $callUrl = $actionUrl . '&catalogId='.$catalog['catalog_id'].'&page=' . $currentPage; + $results = get_web_page($callUrl); + + $totalPages = $results['pages']; + + echo sprintf('Catalogo "'.$catalog['catalog_id'].'", Totale prodotti: %s. Pagine: %s di %s'. PHP_EOL, $results['elementsFounds'], $currentPage , $totalPages); + $currentPage++; + + } + catch(Exception $e) { + $totalPages=-1; + echo($e->getMessage() . PHP_EOL); + } + } + echo('Update Catalogo-'.$catalog['catalog_id'].' from ImporterONE Cloud terminata'. PHP_EOL); + } } else die('Parametro Url plugin non impostato!'); diff --git a/override/classes/Product.php b/override/classes/Product.php index e300038906c51fd6dae6b8f7bbed03ce39cf65a1..920c230293b6a7d72c6c9481ef91f9517df816b8 100755 --- a/override/classes/Product.php +++ b/override/classes/Product.php @@ -27,6 +27,8 @@ class Product extends ProductCore $delayedDownloadsImages = Configuration::get('IMPORTERONE6CONNECT_DELAYED_DOWNLOADS_IMAGES'); if ((int)$delayedDownloadsImages == 1) { if($context->controller->controller_type == 'admin'){ + + Product::getIO6DelayedImages($id_product, 0); //Limit 1 = solo una immagine } else { Product::getIO6DelayedImages($id_product, 1); //Limit 1 = solo una immagine @@ -60,7 +62,6 @@ class Product extends ProductCore $io6ConnectGallery = Db::getInstance()->ExecuteS($sql); if (is_array($io6ConnectGallery) && count($io6ConnectGallery)) { $importerone6connectModule = Module::getInstanceByName("ps_connect_io6"); - foreach ($io6ConnectGallery as $k => $io6image) { try { if (function_exists('curl_version')){ @@ -68,14 +69,21 @@ class Product extends ProductCore curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $image_data = curl_exec($ch); - } - + } + if (!function_exists('curl_version')) { $image_data = @file_get_contents($io6image['image_uri']); // Get image data } if (!isset($image_data) || empty($image_data)) continue; + $finfo = new finfo(FILEINFO_MIME_TYPE); + $image_mime_type = $finfo->buffer($image_data); + + if (!str_contains($image_mime_type, 'image')) continue; + + if (str_contains($image_mime_type, 'bmp')) continue; + $image_filename = date('YmdHis') . '_' . basename($io6image['image_uri']); $image_filepath = IO6_IMAGES_DIRPATH . $image_filename; diff --git a/ps_connect_io6.php b/ps_connect_io6.php index 6a85dc3c1ad8148ebb1fade1778d4eb8fa92ede2..91f6ab77f7052df0be2d1dab0419209a41c56830 100755 --- a/ps_connect_io6.php +++ b/ps_connect_io6.php @@ -41,11 +41,12 @@ define('IO6_IMAGES_DIRPATH', _PS_UPLOAD_DIR_ . 'io6-images' . DIRECTORY_SEPARATO define('IO6_PHP_MIN', '7.4.13'); -define('IO6_PHP_MAX', '8.1.30'); +define('IO6_PHP_MAX', '8.1.31'); define('IO6_MAX_EXECUTION_TIME', 300); define('IO6_MEMORY_LIMIT', 512); define('IO6_PS_VERSION_MIN', '1.7.8.0'); -define('IO6_PS_VERSION_MAX', '8.2.0.0'); +define('IO6_PS_VERSION_MAX', '8.2.0'); +define('IO6_SESSION_ID', 'IO6SESSION'); require_once('core/src/classes/IO6ConnectEngine.class.php'); @@ -81,7 +82,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface { $this->name = 'ps_connect_io6'; $this->tab = 'quick_bulk_update'; - $this->version = '1.4.4'; + $this->version = '2.0.0'; $this->author = 'Imprimis'; $this->need_instance = 0; @@ -141,12 +142,15 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface Configuration::updateValue('IMPORTERONE6CONNECT_MANAGE_HTMLFEATURES', 1); Configuration::updateValue('IMPORTERONE6CONNECT_TEMPLATE_HTMLFEATURES', 0); Configuration::updateValue('IMPORTERONE6CONNECT_MANAGE_TAX_RULE_DEFAULT', 0); + Configuration::updateValue('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS', 1); Configuration::updateValue('IMPORTERONE6CONNECT_TAX_RULE_DEFAULT', 0); Configuration::updateValue('IMPORTERONE6CONNECT_CONCAT_HTMLFEATURES', 1); Configuration::updateValue('IMPORTERONE6CONNECT_EXCLUDE_NOIMAGE', 1); Configuration::updateValue('IMPORTERONE6CONNECT_MANAGE_FACETEDSEARCH_MODELS', 0); Configuration::updateValue('IMPORTERONE6CONNECT_EXCLUDE_AVAILLESSTHAN', 0); Configuration::updateValue('IMPORTERONE6CONNECT_EXCLUDE_AVAILTYPE', 0); + Configuration::updateValue('IMPORTERONE6CONNECT_CATALOGS', serialize([])); + return parent::install() && $this->registerHook('displayFooterProduct') && @@ -156,7 +160,15 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $this->registerHook('displayAdminProductsExtra') && $this->registerHook('displayAdminProductsMainStepLeftColumnMiddle') && $this->registerHook('displayAdminProductsPriceStepBottom') && - $this->registerHook('actionProductFormBuilderModifier'); + $this->registerHook('actionProductFormBuilderModifier') && + $this->registerHook('actionIO6ProductSaveBefore') && + $this->registerHook('actionIO6ProductSaveAfter') && + $this->registerHook('actionIO6CategorySaveBefore') && + $this->registerHook('actionIO6CategorySaveAfter') && + $this->registerHook('actionIO6BrandSaveBefore') && + $this->registerHook('actionIO6BrandSaveAfter') && + $this->registerHook('actionIO6SupplierSaveBefore') && + $this->registerHook('actionIO6SupplierSaveAfter'); //TODO Aggiungere Hook actionCategoryDelete per pulire tabella ps_importerone6connect_category e anche per altre entità } @@ -181,12 +193,14 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface Configuration::deleteByName('IMPORTERONE6CONNECT_MANAGE_HTMLFEATURES'); Configuration::deleteByName('IMPORTERONE6CONNECT_TEMPLATE_HTMLFEATURES'); Configuration::deleteByName('IMPORTERONE6CONNECT_MANAGE_TAX_RULE_DEFAULT'); + Configuration::deleteByName('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS'); Configuration::deleteByName('IMPORTERONE6CONNECT_TAX_RULE_DEFAULT'); Configuration::deleteByName('IMPORTERONE6CONNECT_CONCAT_HTMLFEATURES'); Configuration::deleteByName('IMPORTERONE6CONNECT_EXCLUDE_NOIMAGE'); Configuration::deleteByName('IMPORTERONE6CONNECT_MANAGE_FACETEDSEARCH_MODELS'); Configuration::deleteByName('IMPORTERONE6CONNECT_EXCLUDE_AVAILLESSTHAN'); Configuration::deleteByName('IMPORTERONE6CONNECT_EXCLUDE_AVAILTYPE'); + Configuration::deleteByName('IMPORTERONE6CONNECT_CATALOGS'); include(dirname(__FILE__) . '/sql/uninstall.php'); @@ -217,10 +231,11 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $configuration['apitoken'] = Configuration::get('IMPORTERONE6CONNECT_API_TOKEN'); $configuration['apiendpoint'] = Configuration::get('IMPORTERONE6CONNECT_API_ENDPOINT'); $configuration['catalog'] = Configuration::get('IMPORTERONE6CONNECT_CATALOG'); + $configuration['catalogs'] = Configuration::get('IMPORTERONE6CONNECT_CATALOGS'); //$configuration['languagecode'] : ''; //CHIEDERE //$configuration['tempfolder'] : ''; //CHIEDERE - $configuration['price_list'] = Configuration::get('IMPORTERONE6CONNECT_PRICE_LIST'); + $configuration['price_lists'] = Configuration::get('IMPORTERONE6CONNECT_PRICE_LISTS'); $configuration['page_size'] = Configuration::get('IMPORTERONE6CONNECT_PAGESIZE'); $configuration['image_limit'] = Configuration::get('IMPORTERONE6CONNECT_IMAGELIMIT'); @@ -244,6 +259,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $configuration['manage_categories'] = Configuration::get('IMPORTERONE6CONNECT_MANAGE_CATEGORIES'); $configuration['manage_excerpt'] = Configuration::get('IMPORTERONE6CONNECT_MANAGE_SHORTDESCRIPTION'); $configuration['manage_tax_rule'] = Configuration::get('IMPORTERONE6CONNECT_MANAGE_TAX_RULE_DEFAULT'); + $configuration['manage_io6_suppliers'] = Configuration::get('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS'); $configuration['manage_features_html'] = Configuration::get('IMPORTERONE6CONNECT_MANAGE_HTMLFEATURES'); $configuration['concat_features_html'] = Configuration::get('IMPORTERONE6CONNECT_CONCAT_HTMLFEATURES'); $configuration['features_html_template'] = Configuration::get('IMPORTERONE6CONNECT_TEMPLATE_HTMLFEATURES'); @@ -275,9 +291,14 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface */ public function io6Sync($io6_id_product = 0) { + session_id(IO6_SESSION_ID); + session_start(); + $io6_configuration = new IO6ConnectConfiguration($this->getIO6ConnectConfiguration()); $io6Engine = new IO6ConnectEngine($io6_configuration); + $io6_catalogs = unserialize(Configuration::get('IMPORTERONE6CONNECT_CATALOGS')); + $catalogId = intval(Tools::getValue('catalogId', 0)); $currentPage = intval(Tools::getValue('page', 1)); $pageSize = intval(Tools::getValue('page_size', $io6_configuration->pageSize)); $syncFast = intval(Tools::getValue('fast', 0)); @@ -288,30 +309,54 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface // QUINDI SE ATTIVO LA SYNCRESUME E TUTTI I PRODOTTI HANNO SYNC_STATUS VALORIZZATO ALLORA DISATTIVO LA SYNCRESUME PERCHÈ NON NECESSARIA if ($currentPage == 1 && $syncResume){ $sql = "SELECT COUNT(id_product) FROM ". _DB_PREFIX_ ."importerone6connect_products iop - WHERE iop.sync_status = 0 OR iop.sync_status IS NULL"; + WHERE iop.sync_status = 0 AND iop.sync_exclude = 0"; $product_not_synced = Db::getInstance()->getValue($sql); if($product_not_synced == 0) $syncResume = false; } - if ($currentPage == 1 && empty($io6_id_product) && !$syncResume) { - $this->cleanImporterone6connectTable(); + if(!isset($io6_catalogs[$catalogId])){ + //RITORNA MESSAGGIO DI ERRORE. + } + + if ($currentPage == 1){ + $_SESSION['categories_cache'] = []; + $_SESSION['brands_cache'] = []; + $_SESSION['suppliers_cache'] = []; + $_SESSION['products_cache'] = []; + } - if (!$syncFast) { - $this->syncCategories($io6Engine); - Category::regenerateEntireNtree(); + if (!empty($io6_id_product)) + { + $_SESSION['categories_cache'] = $this->preloadImporteroneCategories(); + $_SESSION['brands_cache'] = $this->preloadImporteroneManufacturers(); + $_SESSION['suppliers_cache'] = $this->preloadImporteroneSuppliers(); + $_SESSION['products_cache'] = $this->preloadImporteroneProducts(); + } - $this->syncBrands($io6Engine); + if(!empty($io6_catalogs) && isset($io6_catalogs[$catalogId])){ + $catalog = $io6_catalogs[$catalogId]; + if ($currentPage == 1 && empty($io6_id_product) && !$syncResume) { + $this->cleanImporterone6connectTable(); + + if (!$syncFast) { + $this->syncCategories($io6Engine, $catalogId); + Category::regenerateEntireNtree(); + + $this->syncBrands($io6Engine, $catalogId); + } + + $this->syncSuppliers($io6Engine, $catalogId); } - $this->syncSuppliers($io6Engine); + //PASSA CATALOGID e PRICELISTID SEPARATI + //$this->io6_write_log(date('Y-m-d H:i:s') . " SyncProduct inizio", IO6_LOG_WARNING); + $results = $this->syncProducts($io6Engine, $io6_configuration, $catalogId, $catalog['price_list_id'], $currentPage, $pageSize, $syncFast, $syncResume, $io6_id_product); + //$this->io6_write_log(date('Y-m-d H:i:s') . " SyncProduct fine", IO6_LOG_WARNING); } - //$this->io6_write_log(date('Y-m-d H:i:s') . " SyncProduct inizio", IO6_LOG_WARNING); - $results = $this->syncProducts($io6Engine, $io6_configuration, $currentPage, $pageSize, $syncFast, $syncResume, $io6_id_product); - //$this->io6_write_log(date('Y-m-d H:i:s') . " SyncProduct fine", IO6_LOG_WARNING); - if (!empty($io6_id_product)){ + if (!empty($io6_id_product)){ return $results; } else { echo isset($results) ? json_encode($results) : '{}'; @@ -319,7 +364,6 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface } } - public function cleanImporterone6connectTable() { //Pulisco eventuali righe orfane senza corrispondenza nella tabella delle Catagorie Prestashop @@ -417,12 +461,15 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface return $retVal; } - private function preloadImporteroneProducts() + private function preloadImporteroneProducts($catalogId = 0) { //TODO 20210508 Valutare se in caso di cataloghi da diverse migliaia se può degradare le prestazioni (viene ricaricata ad ogni paginazione) $retVal = []; //$this->io6_write_log(date('Y-m-d H:i:s') . " Preload select inizio", IO6_LOG_WARNING); - $sql = 'SELECT io6_id_product, id_product FROM ' . _DB_PREFIX_ . 'importerone6connect_products WHERE io6_id_product > 0'; + $sql = 'SELECT io6_id_product, id_product FROM ' . _DB_PREFIX_ . 'importerone6connect_products WHERE io6_id_product > 0 '; + + if($catalogId > 0) + $sql .= " AND (catalog_id = ". $catalogId ." OR catalog_id IS NULL OR catalog_id = 0)"; $results = DB::getInstance()->executeS($sql); //$this->io6_write_log(date('Y-m-d H:i:s') . " Preload select fine", IO6_LOG_WARNING); @@ -473,23 +520,27 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $ps_category->id_shop_default = (int)Context::getContext()->shop->id; } - - if (empty($id_category)) { - $ps_category->date_add = date('Y-m-d H:i:s'); - $res = $ps_category->add(); - //$this->io6_write_log(date('Y-m-d H:i:s') . " Category add", IO6_LOG_WARNING); - } else - $res = !$categoryChanged || $ps_category->update(); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " Category res after add/update: " . $res , IO6_LOG_WARNING); - - if ($res) { - $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_categories (id_category, io6_category_code) - VALUES (" . $ps_category->id . ",'" . pSQL($io6_category_code) . "')"; - DB::getInstance()->execute($sql); - - $this->ps_categories_cache[$io6_category_code] = $ps_category->id; + $hookReturn = true; + Hook::exec('actionIO6CategorySaveBefore', ['ps_category' => &$ps_category, 'hookReturn' => &$hookReturn]); + if ($hookReturn){ + if (empty($id_category)) { + $ps_category->date_add = date('Y-m-d H:i:s'); + $res = $ps_category->add(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " Category add", IO6_LOG_WARNING); + } else + $res = !$categoryChanged || $ps_category->update(); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " Category res after add/update: " . $res , IO6_LOG_WARNING); + + if ($res) { + $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_categories (id_category, io6_category_code) + VALUES (" . $ps_category->id . ",'" . pSQL($io6_category_code) . "')"; + DB::getInstance()->execute($sql); + + $_SESSION['categories_cache'][$io6_category_code] = $ps_category->id; + } } + Hook::exec('actionIO6CategorySaveAfter', ['ps_category' => &$ps_category]); return $res ? $ps_category : false; } @@ -517,34 +568,42 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $ps_manufacturer->active = 1; } - if (empty($id_manufacturer)) { - $ps_manufacturer->date_add = date('Y-m-d H:i:s'); - $res = $ps_manufacturer->add(); - //$this->io6_write_log(date('Y-m-d H:i:s') . " Manufatcuter add" , IO6_LOG_WARNING); - } else - $res = !$brandChanged || $ps_manufacturer->update(); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " Manufatcuter res after add/update: " . $res , IO6_LOG_WARNING); - - if ($res) { - $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_manufacturers (id_manufacturer, io6_brand_code) - VALUES (" . $ps_manufacturer->id . ",'" . pSQL($io6_brand_code) . "')"; - DB::getInstance()->execute($sql); - - $this->ps_brands_cache[$io6_brand_code] = $ps_manufacturer->id; - } - - - $sql = "SELECT logo FROM " . _DB_PREFIX_ . "importerone6connect_manufacturers WHERE id_manufacturer = " . (int)$ps_manufacturer->id; - $old_logo = DB::getInstance()->getValue($sql); - if (!empty($logo) && $old_logo != $logo) { - if (@$this->generateImgIntoCms($ps_manufacturer->id, $logo, null, 'manufacturers')) { - $sql = "UPDATE " . _DB_PREFIX_ . "importerone6connect_manufacturers SET logo='" . pSQL($logo) . "' WHERE id_manufacturer = " . (int)$ps_manufacturer->id; + $hookReturn = true; + Hook::exec('actionIO6BrandSaveBefore', ['ps_manufacturer' => &$ps_manufacturer, 'hookReturn' => &$hookReturn]); + if ($hookReturn){ + if (empty($id_manufacturer)) { + $ps_manufacturer->date_add = date('Y-m-d H:i:s'); + $res = $ps_manufacturer->add(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " Manufatcuter add" , IO6_LOG_WARNING); + } else + $res = !$brandChanged || $ps_manufacturer->update(); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " Manufatcuter res after add/update: " . $res , IO6_LOG_WARNING); + + if ($res) { + $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_manufacturers (id_manufacturer, io6_brand_code) + VALUES (" . $ps_manufacturer->id . ",'" . pSQL($io6_brand_code) . "')"; DB::getInstance()->execute($sql); - } else { - $this->io6_write_log("Logo Manufacturer non salvato. logo: " . $logo, IO6_LOG_WARNING); + + $_SESSION['brands_cache'][$io6_brand_code] = $ps_manufacturer->id; + } + + + $sql = "SELECT logo FROM " . _DB_PREFIX_ . "importerone6connect_manufacturers WHERE id_manufacturer = " . (int)$ps_manufacturer->id; + $old_logo = DB::getInstance()->getValue($sql); + if (!empty($logo) && $old_logo != $logo) { + if (@$this->generateImgIntoCms($ps_manufacturer->id, $logo, null, 'manufacturers')) { + $sql = "UPDATE " . _DB_PREFIX_ . "importerone6connect_manufacturers SET logo='" . pSQL($logo) . "' WHERE id_manufacturer = " . (int)$ps_manufacturer->id; + DB::getInstance()->execute($sql); + } else { + $this->io6_write_log("Logo Manufacturer non salvato. logo: " . $logo, IO6_LOG_WARNING); + } } + } + + Hook::exec('actionIO6BrandSaveAfter', ['ps_manufacturer' => &$ps_manufacturer]); + return $res ? $ps_manufacturer : false; } @@ -573,34 +632,39 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $ps_supplier->active = 1; } - if (empty($id_supplier)) { - $ps_supplier->date_add = date('Y-m-d H:i:s'); - $res = $ps_supplier->add(); - //$this->io6_write_log(date('Y-m-d H:i:s') . " Supplier add" , IO6_LOG_WARNING); - } else - $res = !$supplierChanged || $ps_supplier->update(); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " Supplier res after add/update" . $res , IO6_LOG_WARNING); - - if ($res) { - $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_suppliers (id_supplier, io6_id_supplier) - VALUES (" . (int)$ps_supplier->id . "," . (int)$io6_id_supplier . ")"; - DB::getInstance()->execute($sql); - - $this->ps_suppliers_cache[$io6_id_supplier] = $ps_supplier->id; + $hookReturn = true; + Hook::exec('actionIO6SupplierSaveBefore', ['ps_supplier' => &$ps_supplier, 'hookReturn' => &$hookReturn]); + if($hookReturn){ + if (empty($id_supplier)) { + $ps_supplier->date_add = date('Y-m-d H:i:s'); + $res = $ps_supplier->add(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " Supplier add" , IO6_LOG_WARNING); + } else + $res = !$supplierChanged || $ps_supplier->update(); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " Supplier res after add/update" . $res , IO6_LOG_WARNING); + + if ($res) { + $sql = "REPLACE INTO " . _DB_PREFIX_ . "importerone6connect_suppliers (id_supplier, io6_id_supplier) + VALUES (" . (int)$ps_supplier->id . "," . (int)$io6_id_supplier . ")"; + DB::getInstance()->execute($sql); + + $_SESSION['suppliers_cache'][$io6_id_supplier] = $ps_supplier->id; + } } + Hook::exec('actionIO6SupplierSaveAfter', ['ps_supplier' => &$ps_supplier]); return $res ? $ps_supplier : false; } - public function syncCategories(IO6ConnectEngine $io6Engine, $categories = null) + public function syncCategories(IO6ConnectEngine $io6Engine, $catalogId, $categories = null) { $default_language = Configuration::get('PS_LANG_DEFAULT'); if (!isset($categories)) { - $categories = $io6Engine->GetIO6Categories(); + $categories = $io6Engine->GetIO6Categories($catalogId); //Precarico in array tutto l'elenco delle categorie associate ad ImpoterONE - $this->ps_categories_cache = $this->preloadImporteroneCategories(); + $_SESSION['categories_cache'] = $this->preloadImporteroneCategories(); $this->shopRootCategory = Context::getContext()->shop->getCategory(); } @@ -617,14 +681,14 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface if (empty($category->parentCode)) //Se Vuoto o 0, imposto nella root $ps_category_id_parent = $this->shopRootCategory; - else if (isset($this->ps_categories_cache[$category->parentCode])) { - $ps_category_id_parent = (int)$this->ps_categories_cache[$category->parentCode]; + else if (isset($_SESSION['categories_cache'][$category->parentCode])) { + $ps_category_id_parent = (int)$_SESSION['categories_cache'][$category->parentCode]; } else { //TODO: EM20210319 => almeno fare log. capire se saltare la categoria. } //Cerca Categoria tramite Codice IO6 - $ps_categoryId = !empty($this->ps_categories_cache[$category->code]) ? $this->ps_categories_cache[$category->code] : 0; + $ps_categoryId = !empty($_SESSION['categories_cache'][$category->code]) ? $_SESSION['categories_cache'][$category->code] : 0; if (empty($ps_categoryId)) { //Cerco per nome categoria $categoryFounded = Category::searchByNameAndParentCategoryId($default_language, $category->name, $ps_category_id_parent); @@ -644,16 +708,16 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface } if (count($category->subCategories) > 0) - $this->syncCategories($io6Engine, $category->subCategories); + $this->syncCategories($io6Engine, $catalogId, $category->subCategories); } } - public function syncBrands(IO6ConnectEngine $io6Engine) + public function syncBrands(IO6ConnectEngine $io6Engine, $catalogId) { - $brands = $io6Engine->GetIO6Brands(); + $brands = $io6Engine->GetIO6Brands($catalogId); //Precarico in array tutto l'elenco dei brand associati ad ImpoterONE - $this->ps_brands_cache = $this->preloadImporteroneManufacturers(); + $_SESSION['brands_cache'] = $this->preloadImporteroneManufacturers(); foreach ($brands as $brand) { $brand->name = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { @@ -663,7 +727,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface //Cerca Categoria tramite Codice IO6 - $ps_brandId = !empty($this->ps_brands_cache[$brand->code]) ? $this->ps_brands_cache[$brand->code] : 0; + $ps_brandId = !empty($_SESSION['brands_cache'][$brand->code]) ? $_SESSION['brands_cache'][$brand->code] : 0; if (empty($ps_brandId)) @@ -681,11 +745,11 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface } } - public function syncSuppliers(IO6ConnectEngine $io6Engine) + public function syncSuppliers(IO6ConnectEngine $io6Engine, $catalogId) { - $suppliers = $io6Engine->GetIO6Suppliers(); + $suppliers = $io6Engine->GetIO6Suppliers($catalogId); //Precarico in array tutto l'elenco dei suppliers associati ad ImpoterONE - $this->ps_suppliers_cache = $this->preloadImporteroneSuppliers(); + $_SESSION['suppliers_cache'] = $this->preloadImporteroneSuppliers(); foreach ($suppliers as $supplier) { $supplier->name = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { @@ -694,7 +758,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $supplier->name = substr(preg_replace('/[<>;=#{}]/', '', $supplier->name), 0, 64); //Cerca Categoria tramite Codice IO6 - $ps_supplierId = !empty($this->ps_suppliers_cache[$supplier->id]) ? $this->ps_suppliers_cache[$supplier->id] : 0; + $ps_supplierId = !empty($_SESSION['suppliers_cache'][$supplier->id]) ? $_SESSION['suppliers_cache'][$supplier->id] : 0; if (empty($ps_supplierId)) $ps_supplierId = Supplier::getIdByName($supplier->name); @@ -708,7 +772,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface } } - function syncProducts(IO6ConnectEngine $io6Engine, IO6ConnectConfiguration $io6_configuration, $currentPage = 1, $pageSize = 0, $fastSync = 0, $syncResume = 0, $io6_id_product_syngle_sync = 0) + function syncProducts(IO6ConnectEngine $io6Engine, IO6ConnectConfiguration $io6_configuration, $catalogId, $priceListId, $currentPage = 1, $pageSize = 0, $fastSync = 0, $syncResume = 0, $io6_id_product_syngle_sync = 0) { $this->io6_write_log("PRODUCT PAGE ". $currentPage ." BEGIN" , $fastSync ? "FAST" : "NOT FAST"); if (Shop::isFeatureActive()) @@ -716,31 +780,33 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface else Shop::setContext(Shop::CONTEXT_SHOP, (int) Context::getContext()->shop->id); - if ($currentPage == 1 && !$syncResume && empty($io6_id_product_syngle_sync)) { - //Resettare sync_date per individuare successivamente solo i prodotti sincronizzati in questa sincro - //Se sincro di Resume allora non resetto le sync_date altrimenti tutti i prodotti già importati perderebbero la data di sincronizzazione - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'importerone6connect_products` - SET `' . _DB_PREFIX_ . 'importerone6connect_products`.`sync_date` = NULL;'); - - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'importerone6connect_products` SET sync_status = 0'); - } + //Resettare sync_status per individuare successivamente solo i prodotti sincronizzati in questa sincro + Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'importerone6connect_products` SET sync_status = 0 + WHERE `' . _DB_PREFIX_ . 'importerone6connect_products`.catalog_id = '. $catalogId); + } $default_language = Configuration::get('PS_LANG_DEFAULT'); - $skuField = $io6_configuration->selectedSkuField; $skuProp = str_replace('io6_sku_', '', $skuField); $eanField = 'ean13'; //$io6_configuration->selectedEanField; $partNumberField = 'mpn'; //$io6_configuration->selectedPartNumberField; $brandField = 'id_manufacturer'; // $io6_configuration->selectedBrandField; - //$ean_product_to_sync = !empty($io6_id_product_syngle_sync) ? (new Product($io6_id_product_syngle_sync))->ean13 : 0; - - $io6_results = $io6Engine->GetIO6Products($currentPage, $pageSize, $io6_id_product_syngle_sync); - $this->ps_products_cache = $this->preloadImporteroneProducts(); + $io6_results = $io6Engine->GetIO6Products($currentPage, $pageSize, $catalogId, $priceListId, $io6_id_product_syngle_sync); + + if ($currentPage == 1 && empty($io6_id_product_syngle_sync)) + $_SESSION['products_cache'] = $this->preloadImporteroneProducts($catalogId); + + // Chiamata per conoscere i supplier agganciati a questo catalogo + if ($io6_configuration->manageIo6Suppliers) { + $catalog_suppliers = $io6Engine->GetIO6Suppliers($catalogId); + $catalog_suppliers = implode(',',array_map(function($supplier){ + return $supplier->id; + }, $catalog_suppliers)); - //TODO: EM20210330 => se il prodotto è obsoleto e nn esiste nemmeno lo creo, stessa cosa se con tutti i flag filtro risulta disattivato + } $categories_to_clean = []; @@ -748,6 +814,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $syncResults['pages'] = $io6_results['pages']; $syncResults['elementsFounds'] = $io6_results['elementsFounds']; $syncResults['products'] = array(); + foreach ($io6_results['products'] as $io6product) { //$this->io6_write_log(date('Y-m-d H:i:s') . " product inizio", IO6_LOG_WARNING); //TODO CT 20210511 Se gli passo $e va in errore di memory limit //Carico flag con valori di default del modulo @@ -767,15 +834,14 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $concat_features_html = $io6_configuration->concatFeaturesHTML; //TODO CT 20211016 Verificare, se non viene usato rimuovere anche da configuration //$excludeNoImage = $io6_configuration->excludeNoImage; $update_tax_rule = $io6_configuration->manageTaxRule; + $manage_io6_suppliers = $io6_configuration->manageIo6Suppliers; $manage_facetedsearch_models = Configuration::get('IMPORTERONE6CONNECT_MANAGE_FACETEDSEARCH_MODELS') == 1 && !$fastSync; - $retProduct = array('io6_id' => $io6product->id, 'ean' => $io6product->ean, 'partnumber' => $io6product->partNumber); + $retProduct = array('catalog_id' => $catalogId, 'io6_id' => $io6product->id, 'ps_product_id' => 0, 'ean' => $io6product->ean, 'partnumber' => $io6product->partNumber); $activeState = $io6product->isActive && $io6product->statusCode != 99; - - try { if (!$activeState) { $this->io6_write_log("Prodotto escluso perchè non attivo in ImporterONE. IO6 Product Id: " . $io6product->id, IO6_LOG_INFO); @@ -786,15 +852,13 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface // continue; } - $ps_product_id = isset($this->ps_products_cache[$io6product->id]) ? $this->ps_products_cache[$io6product->id] : 0; - $ps_brand_id = isset($this->ps_brands_cache[$io6product->brandCode]) ? $this->ps_brands_cache[$io6product->brandCode] : 0; - $ps_supplier_id = isset($this->ps_suppliers_cache[$io6product->supplierId]) ? $this->ps_suppliers_cache[$io6product->supplierId] : 0; - $ps_category_id = isset($this->ps_categories_cache[$io6product->categoryCode]) ? $this->ps_categories_cache[$io6product->categoryCode] : 0; - + $ps_product_id = isset($_SESSION['products_cache'][$io6product->id]) ? $_SESSION['products_cache'][$io6product->id] : 0; + $ps_brand_id = isset($_SESSION['brands_cache'][$io6product->brandCode]) ? $_SESSION['brands_cache'][$io6product->brandCode] : 0; + $ps_supplier_id = isset($_SESSION['suppliers_cache'][$io6product->supplierId]) ? $_SESSION['suppliers_cache'][$io6product->supplierId] : 0; + $ps_category_id = isset($_SESSION['categories_cache'][$io6product->categoryCode]) ? $_SESSION['categories_cache'][$io6product->categoryCode] : 0; $ps_brand = null; $ps_category = null; - if ($ps_product_id == 0) { if ($fastSync) { throw new Exception("Prodotto non aggiornabile con sincro VELOCE perchè non presente in Prestashop o non abbinato ad ImporterONE."); @@ -808,41 +872,72 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface // $ps_product_id = $results[0]->post_id; // } + + if ($ps_product_id == 0 && !empty($io6product->$skuProp)) { - - $sql = "SELECT id_product FROM " . _DB_PREFIX_ . "product p - WHERE p.reference = '" . pSQL($io6product->$skuProp) . "'"; + + $sql = "SELECT p.id_product FROM " . _DB_PREFIX_ . "product p + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_products ip ON ip.id_product = p.id_product + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_suppliers s ON s.id_supplier = p.id_supplier + WHERE p.reference = '" . pSQL($io6product->$skuProp) . "' AND (ip.catalog_id IS NULL OR ip.catalog_id = 0 OR ip.catalog_id = " . (int)$catalogId. ")"; if ($skuProp == 'partNumber') - $sql .= " AND id_manufacturer = " . (int)$ps_brand_id; + $sql .= " AND p.id_manufacturer = " . (int)$ps_brand_id; - $results = DB::getInstance()->getValue($sql); + if ($manage_io6_suppliers) + $sql .= " AND s.io6_id_supplier IN(".$catalog_suppliers.")"; + + //$this->io6_write_log("QUERY REFERENCE: " . $sql . " per io6product: " . $io6product->id, IO6_LOG_INFO); + + $results = Db::getInstance()->getValue($sql); if ($results !== false) { $ps_product_id = (int)$results; } } if ($ps_product_id == 0 && !empty($io6product->ean)) { - $sql = "SELECT id_product FROM " . _DB_PREFIX_ . "product WHERE " . pSQL($eanField) . " = '" . pSQL($io6product->ean) . "'"; - $results = DB::getInstance()->getValue($sql); + $sql = "SELECT p.id_product FROM " . _DB_PREFIX_ . "product p + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_products ip ON ip.id_product = p.id_product + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_suppliers s ON s.id_supplier = p.id_supplier + WHERE p." . pSQL($eanField) . " = '" . pSQL($io6product->ean) . "' AND (ip.catalog_id IS NULL OR ip.catalog_id = 0 OR ip.catalog_id = " . (int)$catalogId. ")"; + + if ($manage_io6_suppliers) + $sql .= " AND s.io6_id_supplier IN(".$catalog_suppliers.")"; + + //$this->io6_write_log("QUERY EAN: " . $sql . " per io6product: " . $io6product->id, IO6_LOG_INFO); + + $results = Db::getInstance()->getValue($sql); + if ($results !== false) { $ps_product_id = (int)$results; } + //$this->io6_write_log("QUERY EAN RESULT: " . $ps_product_id . " per io6product: " . $io6product->id, IO6_LOG_INFO); } - - + + if (version_compare(_PS_VERSION_, '1.7.7', '>=')) { if ($ps_product_id == 0 && !empty($io6product->partNumber)) { - $sql = "SELECT id_product FROM " . _DB_PREFIX_ . "product WHERE " . pSQL($partNumberField) . " = '" . pSQL($io6product->partNumber) . "' AND id_manufacturer = " . (int)$ps_brand_id; - $results = DB::getInstance()->getValue($sql); + $sql = "SELECT p.id_product FROM " . _DB_PREFIX_ . "product p + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_products ip ON ip.id_product = p.id_product + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_suppliers s ON s.id_supplier = p.id_supplier + WHERE p." . pSQL($partNumberField) . " = '" . pSQL($io6product->partNumber) . "' AND p.id_manufacturer = " . (int)$ps_brand_id . " + AND (ip.catalog_id IS NULL OR ip.catalog_id = 0 OR ip.catalog_id = " . (int)$catalogId. ")"; + + if ($manage_io6_suppliers) + $sql .= " AND s.io6_id_supplier IN(".$catalog_suppliers.")"; + + //$this->io6_write_log("QUERY MPN: " . $sql . " per io6product: " . $io6product->id, IO6_LOG_INFO); + + $results = Db::getInstance()->getValue($sql); + if ($results !== false) { $ps_product_id = (int)$results; } + //$this->io6_write_log("QUERY MPN RESULT: " . $ps_product_id . " per io6product: " . $io6product->id, IO6_LOG_INFO); } } } - //TODO: EM20210330 => verifica isactive, statuscode e altri filtri. Se condizione è false disattiva il prodotto. //SE nn esiste nn lo crea, se esiste nn lo aggiorna e mette qta = 0 @@ -853,7 +948,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $results = DB::getInstance()->getValue($sql); if ($results !== false) { $ps_brand_id = (int)$results; - $this->ps_brands_cache[$io6product->brandCode] = $ps_brand_id; + $_SESSION['brands_cache'][$io6product->brandCode] = $ps_brand_id; } } @@ -862,7 +957,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $results = DB::getInstance()->getValue($sql); if ($results !== false) { $ps_supplier_id = (int)$results; - $this->ps_suppliers_cache[$io6product->supplierId] = $ps_supplier_id; + $_SESSION['suppliers_cache'][$io6product->supplierId] = $ps_supplier_id; } } @@ -871,7 +966,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $results = DB::getInstance()->getValue($sql); if ($results !== false) { $ps_category_id = (int)$results; - $this->ps_categories_cache[$io6product->categoryCode] = $ps_category_id; + $_SESSION['categories_cache'][$io6product->categoryCode] = $ps_category_id; } } @@ -885,6 +980,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $isNewProduct = false; $has_cms_images = false; if ($ps_product_id) { + $retProduct['ps_product_id'] = $ps_product_id; $io6ConfigProduct = $this->getImporteroneConnectProduct($ps_product_id); if ($syncResume && !empty($io6ConfigProduct['sync_status'])) { @@ -895,7 +991,6 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface continue; } - if (!isset($io6ConfigProduct['sync_exclude']) || intval($io6ConfigProduct['sync_exclude']) == 1) { throw new Exception("Product $ps_product_id is not managed by " . $this->displayName); } @@ -914,6 +1009,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $manage_facetedsearch_models = $update_features ? $manage_facetedsearch_models : false; $update_features_html = isset($io6ConfigProduct['manage_htmlfeatures']) && intval($io6ConfigProduct['manage_htmlfeatures']) != 2 ? intval($io6ConfigProduct['manage_htmlfeatures']) : $update_features_html; $update_tax_rule = isset($io6ConfigProduct['manage_tax_rule']) && intval($io6ConfigProduct['manage_tax_rule']) != 2 ? intval($io6ConfigProduct['manage_tax_rule']) : $update_tax_rule; + $manage_io6_suppliers = isset($io6ConfigProduct['manage_io6_suppliers']) && intval($io6ConfigProduct['manage_io6_suppliers']) != 2 ? intval($io6ConfigProduct['manage_io6_suppliers']) : $manage_io6_suppliers; $ps_product = new Product($ps_product_id, false); $has_cms_images = (Product::getCover($ps_product_id) !== false); @@ -964,6 +1060,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface // // //TODO CT 20210521 Non va bene fare la continue, andrebbe aggiornata almeno la tabella ps_importerone6connect_products con lo sync_status e sync_message // // continue; // } + $ps_product->active = $activeState; if (!$fastSync) { @@ -1106,375 +1203,395 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface throw new Exception("Product fields value not valid: " . $validateFields . "-" . $validateFieldsLang); } - if ($isNewProduct) { - //$this->io6_write_log(date('Y-m-d H:i:s') . " product add inizio", IO6_LOG_WARNING); - $res = @$ps_product->add(); - //$this->io6_write_log(date('Y-m-d H:i:s') . " product add fine", IO6_LOG_WARNING); - } else { - //$this->io6_write_log(date('Y-m-d H:i:s') . " product update inizio", IO6_LOG_WARNING); - $res = @$ps_product->update(); - //$this->io6_write_log(date('Y-m-d H:i:s') . " product update fine", IO6_LOG_WARNING); - } - if (!$res) { - throw new Exception("Product Save not completed"); - } - - if ($update_categories && $categoryChanged) { - //Assegna prodotto a tutto albero delle categorie - $ps_category = new Category($ps_category_id); //TODO: 20210511 CT Per ottimizzare si potrebbe salvare le categorie già istanziate in un dictionary per evitare ogni volta questa query. - $tmp_id_categories = []; - if (is_array($parentsCats = $ps_category->getParentsCategories()) && count($parentsCats) > 0) { - foreach ($parentsCats as $a_p) - $tmp_id_categories[] = $a_p['id_category']; - } - - //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories select inizio", IO6_LOG_WARNING); - $result = Db::getInstance()->executeS( - 'SELECT c.`id_category`, cp.position - FROM `' . _DB_PREFIX_ . 'category_product` cp - LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.`id_category` = cp.`id_category`) - ' . Shop::addSqlAssociation('category', 'c', true, null, true) . ' - WHERE cp.`id_category` NOT IN (' . implode(',', array_map('intval', $tmp_id_categories)) . ') - AND cp.id_product = ' . (int) $ps_product->id - ); - //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories select fine", IO6_LOG_WARNING); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories delete inizio", IO6_LOG_WARNING); - foreach ($result as $cat) { - $return = Db::getInstance()->delete('category_product', 'id_product = ' . (int) $ps_product->id . ' AND id_category = ' . (int)$cat['id_category']); - $categories_to_clean[$cat['id_category']] = $cat; - //$ps_product->deleteCategory($cat['id_category']); + $hookReturn = true; + Hook::exec('actionIO6ProductSaveBefore', ['io6_product' => &$io6product, 'ps_product' => &$ps_product, 'hookReturn' => &$hookReturn]); + //Se nessun modulo si collega all'hook e quindi non viene chiamata nessuna funzione l'hook restituisce "null" quindi assegno a retVal solo se diverso da "null" + if ($hookReturn) { + if ($isNewProduct) { + //$this->io6_write_log(date('Y-m-d H:i:s') . " product add inizio", IO6_LOG_WARNING); + $res = @$ps_product->add(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product add fine", IO6_LOG_WARNING); + } else { + //$this->io6_write_log(date('Y-m-d H:i:s') . " product update inizio", IO6_LOG_WARNING); + $res = @$ps_product->update(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product update fine", IO6_LOG_WARNING); } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories delete fine", IO6_LOG_WARNING); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " product add categories inizio", IO6_LOG_WARNING); - if (!$ps_product->addToCategories($tmp_id_categories)) { - throw new Exception("Errore nell'assegnazione delle categorie al prodotto " . $io6product->code); + if (!$res) { + throw new Exception("Product Save not completed"); } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product add categories fine", IO6_LOG_WARNING); - - //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific rules inizio", IO6_LOG_WARNING); - SpecificPriceRule::applyAllRules([(int) $ps_product->id]); - //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific rules fine", IO6_LOG_WARNING); - - //$ps_product->updateCategories($tmp_id_categories); - } - - if (!empty($ps_supplier_id)) { - if (!$isNewProduct) { - //Rimuovo vecchi supplier associati - $product_supplier_del = new ProductSupplier(); - $product_supplier_del->id_product = $ps_product->id; - $product_supplier_del->id_product_attribute = 0; - $product_supplier_del->delete(); + + if ($update_categories && $categoryChanged) { + //Assegna prodotto a tutto albero delle categorie + $ps_category = new Category($ps_category_id); //TODO: 20210511 CT Per ottimizzare si potrebbe salvare le categorie già istanziate in un dictionary per evitare ogni volta questa query. + $tmp_id_categories = []; + if (is_array($parentsCats = $ps_category->getParentsCategories()) && count($parentsCats) > 0) { + foreach ($parentsCats as $a_p) + $tmp_id_categories[] = $a_p['id_category']; + } + + //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories select inizio", IO6_LOG_WARNING); + $result = Db::getInstance()->executeS( + 'SELECT c.`id_category`, cp.position + FROM `' . _DB_PREFIX_ . 'category_product` cp + LEFT JOIN `' . _DB_PREFIX_ . 'category` c ON (c.`id_category` = cp.`id_category`) + ' . Shop::addSqlAssociation('category', 'c', true, null, true) . ' + WHERE cp.`id_category` NOT IN (' . implode(',', array_map('intval', $tmp_id_categories)) . ') + AND cp.id_product = ' . (int) $ps_product->id + ); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories select fine", IO6_LOG_WARNING); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories delete inizio", IO6_LOG_WARNING); + foreach ($result as $cat) { + $return = Db::getInstance()->delete('category_product', 'id_product = ' . (int) $ps_product->id . ' AND id_category = ' . (int)$cat['id_category']); + $categories_to_clean[$cat['id_category']] = $cat; + //$ps_product->deleteCategory($cat['id_category']); + } + //$this->io6_write_log(date('Y-m-d H:i:s') . " product categories delete fine", IO6_LOG_WARNING); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " product add categories inizio", IO6_LOG_WARNING); + if (!$ps_product->addToCategories($tmp_id_categories)) { + throw new Exception("Errore nell'assegnazione delle categorie al prodotto " . $io6product->code); + } + //$this->io6_write_log(date('Y-m-d H:i:s') . " product add categories fine", IO6_LOG_WARNING); + + //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific rules inizio", IO6_LOG_WARNING); + SpecificPriceRule::applyAllRules([(int) $ps_product->id]); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific rules fine", IO6_LOG_WARNING); + + //$ps_product->updateCategories($tmp_id_categories); } - $ps_product->addSupplierReference($ps_supplier_id, 0, $io6product->code, ($io6product->promoPrice > 0 && $io6product->promoPrice < $io6product->dealerPrice) ? $io6product->promoPrice + $io6product->siaeAmount : $io6product->dealerPrice + $io6product->siaeAmount); - } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific price start", IO6_LOG_WARNING); - if ($update_prices && $update_specific_prices) { //Prezzi specifici, prezzi custom - $specificPricesNotImporterONE = []; - if (!$isNewProduct) { - //azzera eventuali prezzi speciale precedentemente impostati da IO6 - $specificPricesByImporterONE = $this->getSpecificPricesByImporterONE($ps_product->id); - foreach ($specificPricesByImporterONE as $id_specific_price) { - $specific_price = new SpecificPrice($id_specific_price); - $specific_price->delete(); + + if (!empty($ps_supplier_id)) { + if (!$isNewProduct) { + //Rimuovo vecchi supplier associati + $product_supplier_del = new ProductSupplier(); + $product_supplier_del->id_product = $ps_product->id; + $product_supplier_del->id_product_attribute = 0; + $product_supplier_del->delete(); } - - $specificPricesNotImporterONE = $this->getSpecificPricesCmsAll($ps_product->id); //CT Ho già rimosso quelli i IO6; $this->getSpecificPricesNotImporterONE($ps_product->id); + $ps_product->addSupplierReference($ps_supplier_id, 0, $io6product->code, ($io6product->promoPrice > 0 && $io6product->promoPrice < $io6product->dealerPrice) ? $io6product->promoPrice + $io6product->siaeAmount : $io6product->dealerPrice + $io6product->siaeAmount); } + //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific price start", IO6_LOG_WARNING); + if ($update_prices && $update_specific_prices) { //Prezzi specifici, prezzi custom + $specificPricesNotImporterONE = []; + if (!$isNewProduct) { + //azzera eventuali prezzi speciale precedentemente impostati da IO6 + $specificPricesByImporterONE = $this->getSpecificPricesByImporterONE($ps_product->id); + foreach ($specificPricesByImporterONE as $id_specific_price) { + $specific_price = new SpecificPrice($id_specific_price); + $specific_price->delete(); + } - if ($io6product->sellingCustomPrice > 0 && $io6product->sellingCustomPrice < $io6product->sellingPrice) { //TODO CT 20210517 Va aggiunta anche la verifica sulle date della promo - $sellingPrice = $io6product->sellingPrice + $io6product->siaeAmount; - $sellingCustomPrice = $io6product->sellingCustomPrice + $io6product->siaeAmount; - - $sellingCustomPriceUntil = '0000-00-00 00:00:00'; - // $this->io6_write_log("io6product->sellingCustomPriceUntil: ". $io6product->sellingCustomPriceUntil, IO6_LOG_INFO); - if (strtotime($io6product->sellingCustomPriceUntil) !== false) { - $sellingCustomPriceUntil = date("Y-m-d H:i:s", strtotime($io6product->sellingCustomPriceUntil)); - // $this->io6_write_log("sellingCustomPriceUntil: ". $sellingCustomPriceUntil, IO6_LOG_INFO); - $sellingCustomPriceUntil = Validate::isDate($sellingCustomPriceUntil) ? $sellingCustomPriceUntil : '0000-00-00 00:00:00'; - // $this->io6_write_log("sellingCustomPriceUntil: ". $sellingCustomPriceUntil, IO6_LOG_INFO); - } else { - $this->io6_write_log("sellingCustomPriceUntil: " . $io6product->sellingCustomPriceUntil . " NON valida per io6product: " . $io6product->id, IO6_LOG_INFO); + $specificPricesNotImporterONE = $this->getSpecificPricesCmsAll($ps_product->id); //CT Ho già rimosso quelli i IO6; $this->getSpecificPricesNotImporterONE($ps_product->id); } - - $id_shop_list = Shop::getShops(true, null, true); - foreach ($id_shop_list as $id_shop) { - //$this->echoDebug("updating reduction_price=" . $info['reduction_price'] . " - id product=" . $id . " in shop: " . $id_shop, IO_LEVEL_DEBUG); - - // $specific_price = SpecificPrice::getSpecificPrice($id, $id_shop, 0, 0, 0, 1, 0, 0, 0, 0); - // if (is_array($specific_price) && isset($specific_price['id_specific_price'])) - // $specific_price = new SpecificPrice((int)$specific_price['id_specific_price']); - // else - $specific_price = new SpecificPrice(); - $specific_price->id_product = (int)$ps_product->id; - $specific_price->id_specific_price_rule = 0; - $specific_price->id_shop = $id_shop; - $specific_price->id_currency = 0; - $specific_price->id_country = 0; - $specific_price->id_group = 0; - $specific_price->id_customer = 0; - $specific_price->from_quantity = 1; - - // //Riduzione in percentuale - // $specific_price->price = -1; - // $specific_price->reduction = round(((isset($info['reduction_price']) AND $info['reduction_price']) ? (1-($info['reduction_price']/$info['price'])): 0), 6); - // $specific_price->reduction_type = 'percentage'; - //Riduzione con sottrazione fissa - $specific_price->price = -1; - $specific_price->reduction = round(($sellingPrice - $sellingCustomPrice), 6); - $specific_price->reduction_type = 'amount'; - $specific_price->reduction_tax = 0; - - //$specific_price->from = (isset($info['reduction_from']) && ($info['reduction_from'] != '0001-01-01') && Validate::isDate($info['reduction_from'])) ? $info['reduction_from'] : '0000-00-00 00:00:00'; - $specific_price->from = '0000-00-00 00:00:00'; - $specific_price->to = $sellingCustomPriceUntil; - - if (!$specific_price->add()) { - // $this->echoDebug("error updating reduction_price=" . $info['reduction_price'] . " - reduction_from=" . $info['reduction_from'] . " - reduction_to=" . $info['reduction_to'] . " id product=" . $id . " in shop: " . $id_shop, IO_LEVEL_WARNING); + + if ($io6product->sellingCustomPrice > 0 && $io6product->sellingCustomPrice < $io6product->sellingPrice) { //TODO CT 20210517 Va aggiunta anche la verifica sulle date della promo + $sellingPrice = $io6product->sellingPrice + $io6product->siaeAmount; + $sellingCustomPrice = $io6product->sellingCustomPrice + $io6product->siaeAmount; + + $sellingCustomPriceUntil = '0000-00-00 00:00:00'; + // $this->io6_write_log("io6product->sellingCustomPriceUntil: ". $io6product->sellingCustomPriceUntil, IO6_LOG_INFO); + if (strtotime($io6product->sellingCustomPriceUntil) !== false) { + $sellingCustomPriceUntil = date("Y-m-d H:i:s", strtotime($io6product->sellingCustomPriceUntil)); + // $this->io6_write_log("sellingCustomPriceUntil: ". $sellingCustomPriceUntil, IO6_LOG_INFO); + $sellingCustomPriceUntil = Validate::isDate($sellingCustomPriceUntil) ? $sellingCustomPriceUntil : '0000-00-00 00:00:00'; + // $this->io6_write_log("sellingCustomPriceUntil: ". $sellingCustomPriceUntil, IO6_LOG_INFO); + } else { + $this->io6_write_log("sellingCustomPriceUntil: " . $io6product->sellingCustomPriceUntil . " NON valida per io6product: " . $io6product->id, IO6_LOG_INFO); + } + + $id_shop_list = Shop::getShops(true, null, true); + foreach ($id_shop_list as $id_shop) { + //$this->echoDebug("updating reduction_price=" . $info['reduction_price'] . " - id product=" . $id . " in shop: " . $id_shop, IO_LEVEL_DEBUG); + + // $specific_price = SpecificPrice::getSpecificPrice($id, $id_shop, 0, 0, 0, 1, 0, 0, 0, 0); + // if (is_array($specific_price) && isset($specific_price['id_specific_price'])) + // $specific_price = new SpecificPrice((int)$specific_price['id_specific_price']); + // else + $specific_price = new SpecificPrice(); + $specific_price->id_product = (int)$ps_product->id; + $specific_price->id_specific_price_rule = 0; + $specific_price->id_shop = $id_shop; + $specific_price->id_currency = 0; + $specific_price->id_country = 0; + $specific_price->id_group = 0; + $specific_price->id_customer = 0; + $specific_price->from_quantity = 1; + + // //Riduzione in percentuale + // $specific_price->price = -1; + // $specific_price->reduction = round(((isset($info['reduction_price']) AND $info['reduction_price']) ? (1-($info['reduction_price']/$info['price'])): 0), 6); + // $specific_price->reduction_type = 'percentage'; + //Riduzione con sottrazione fissa + $specific_price->price = -1; + $specific_price->reduction = round(($sellingPrice - $sellingCustomPrice), 6); + $specific_price->reduction_type = 'amount'; + $specific_price->reduction_tax = 0; + + //$specific_price->from = (isset($info['reduction_from']) && ($info['reduction_from'] != '0001-01-01') && Validate::isDate($info['reduction_from'])) ? $info['reduction_from'] : '0000-00-00 00:00:00'; + $specific_price->from = '0000-00-00 00:00:00'; + $specific_price->to = $sellingCustomPriceUntil; + + if (!$specific_price->add()) { + // $this->echoDebug("error updating reduction_price=" . $info['reduction_price'] . " - reduction_from=" . $info['reduction_from'] . " - reduction_to=" . $info['reduction_to'] . " id product=" . $id . " in shop: " . $id_shop, IO_LEVEL_WARNING); + } } } + + //Memorizzo specific_price inviati da ImpoterONE + $specificPricesAll = $this->getSpecificPricesCmsAll($ps_product->id); //Recupero nuovamente tutti i prezzi specifici dopo gli eventuali inserimenti fatti da IO6 + $specificPricesByImporterONENew = array_diff($specificPricesAll, $specificPricesNotImporterONE); //La differenza mi restituisce solo quelli appena inseriti da IO6 + $this->saveSpecificPricecsByImporterONE($ps_product->id, $specificPricesByImporterONENew); } - - //Memorizzo specific_price inviati da ImpoterONE - $specificPricesAll = $this->getSpecificPricesCmsAll($ps_product->id); //Recupero nuovamente tutti i prezzi specifici dopo gli eventuali inserimenti fatti da IO6 - $specificPricesByImporterONENew = array_diff($specificPricesAll, $specificPricesNotImporterONE); //La differenza mi restituisce solo quelli appena inseriti da IO6 - $this->saveSpecificPricecsByImporterONE($ps_product->id, $specificPricesByImporterONENew); - } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific price fine", IO6_LOG_WARNING); - - //StockAvailable::setQuantity($ps_product->id, 0, (int)$io6product->avail, (int)Context::getContext()->shop->id); - if($update_stock){ - $id_shop_list = Shop::getContextListShopID(); - - foreach ($id_shop_list as $id_shop) { - Shop::setContext(Shop::CONTEXT_SHOP, (int) $id_shop); //StockAvailable::setQuantity NECESSITA che il context sia un id_shop singolo - StockAvailable::setQuantity($ps_product->id, 0, (int)$io6product->avail, (int)$id_shop); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product specific price fine", IO6_LOG_WARNING); + + //StockAvailable::setQuantity($ps_product->id, 0, (int)$io6product->avail, (int)Context::getContext()->shop->id); + if($update_stock){ + $id_shop_list = Shop::getContextListShopID(); + + foreach ($id_shop_list as $id_shop) { + Shop::setContext(Shop::CONTEXT_SHOP, (int) $id_shop); //StockAvailable::setQuantity NECESSITA che il context sia un id_shop singolo + StockAvailable::setQuantity($ps_product->id, 0, (int)$io6product->avail, (int)$id_shop); + } + + if (Shop::isFeatureActive()) //Se necessario ripristino il CONTEXT_ALL + Context::getContext()->shop->setContext(Shop::CONTEXT_ALL); + else + Shop::setContext(Shop::CONTEXT_SHOP, (int) Context::getContext()->shop->id); } - if (Shop::isFeatureActive()) //Se necessario ripristino il CONTEXT_ALL - Context::getContext()->shop->setContext(Shop::CONTEXT_ALL); - else - Shop::setContext(Shop::CONTEXT_SHOP, (int) Context::getContext()->shop->id); - } - - if ($update_images) { - //$this->io6_write_log(date('Y-m-d H:i:s') . " product images start", IO6_LOG_WARNING); - $io6ConnectGallery = []; - - if (!$isNewProduct) { - $sql = 'SELECT id_product, id_image, image_uri, orderindex, lastupdate FROM ' . _DB_PREFIX_ . 'importerone6connect_images WHERE id_product = ' . (int)$ps_product->id; - $io6ConnectGallery = DB::getInstance()->executeS($sql); - } - foreach ($io6product->images as $key => $io6image) { - $to_download = true; - + if ($update_images) { + //$this->io6_write_log(date('Y-m-d H:i:s') . " product images start", IO6_LOG_WARNING); + $io6ConnectGallery = []; + if (!$isNewProduct) { - - $imageRows = array_filter( - $io6ConnectGallery, - function ($io6ConnectImage) use ($io6image) { - return $io6ConnectImage['image_uri'] == $io6image->imageUri; - } - ); - - - $imageRowExists = !empty($imageRows); - - if ($imageRowExists) { - $ps_image = reset($imageRows); - if ($io6image->lastUpdate > $ps_image['lastupdate']) { //immagine ricevuta più recente di quella caricata precedentemente, quindi aggiornare - //Controlla se id_image > 0, altrimenti vuol dire che non non è stata ancora scaricata e inserita in prestashop (postdownload), quindi non è necessario cancellare da prestashop - if ($ps_image['id_image'] > 0) { - //$this->echoDebug("Immagine inviata più recente di quella caricata in Prestashop, quindi rimuovo immagine precedente da Prestashop", IO_LEVEL_DEBUG); - $imageToDel = new Image((int)$ps_image['id_image']); - $resDel = $imageToDel->delete(); - //$this->echoDebug("Immagine precedente eliminata - res: " . $resDel, IO_LEVEL_DEBUG); - unset($imageToDel); + $sql = 'SELECT id_product, id_image, image_uri, orderindex, lastupdate FROM ' . _DB_PREFIX_ . 'importerone6connect_images WHERE id_product = ' . (int)$ps_product->id; + $io6ConnectGallery = DB::getInstance()->executeS($sql); + } + foreach ($io6product->images as $key => $io6image) { + $to_download = true; + + if (!$isNewProduct) { + + $imageRows = array_filter( + $io6ConnectGallery, + function ($io6ConnectImage) use ($io6image) { + return $io6ConnectImage['image_uri'] == $io6image->imageUri; + } + ); + + + $imageRowExists = !empty($imageRows); + + if ($imageRowExists) { + $ps_image = reset($imageRows); + if ($io6image->lastUpdate > $ps_image['lastupdate']) { //immagine ricevuta più recente di quella caricata precedentemente, quindi aggiornare + //Controlla se id_image > 0, altrimenti vuol dire che non non è stata ancora scaricata e inserita in prestashop (postdownload), quindi non è necessario cancellare da prestashop + if ($ps_image['id_image'] > 0) { + //$this->echoDebug("Immagine inviata più recente di quella caricata in Prestashop, quindi rimuovo immagine precedente da Prestashop", IO_LEVEL_DEBUG); + $imageToDel = new Image((int)$ps_image['id_image']); + $resDel = $imageToDel->delete(); + //$this->echoDebug("Immagine precedente eliminata - res: " . $resDel, IO_LEVEL_DEBUG); + unset($imageToDel); + } + + //Elimino riga da tabella importerone6connect_images + $res = Db::getInstance()->Execute('DELETE FROM `' . _DB_PREFIX_ . 'importerone6connect_images` + WHERE id_product =' . (int)$ps_product->id . ' AND image_uri=\'' . $ps_image['image_uri'] . '\' ; '); + } else { + // $this->echoDebug("Non è necessario aggiornare l'immagine", IO_LEVEL_DEBUG); + $to_download = false; + // continue; //TODO CT 20210512 si potrebbe anche fare il continue } - - //Elimino riga da tabella importerone6connect_images - $res = Db::getInstance()->Execute('DELETE FROM `' . _DB_PREFIX_ . 'importerone6connect_images` - WHERE id_product =' . (int)$ps_product->id . ' AND image_uri=\'' . $ps_image['image_uri'] . '\' ; '); - } else { - // $this->echoDebug("Non è necessario aggiornare l'immagine", IO_LEVEL_DEBUG); - $to_download = false; - // continue; //TODO CT 20210512 si potrebbe anche fare il continue } } - } - - if ($to_download) { - //Verificare parametro se fare il download subito oppure ritardato (realtime dal sito), se ritardato inserire solo la riga nella tabella io_images con id_image = 0 - if ($delayedDownloadsImages) { - //Inserisco riga in tabella io_images con id_image = 0 - Db::getInstance()->Execute('INSERT IGNORE INTO `' . _DB_PREFIX_ . 'importerone6connect_images` (id_product, image_uri, id_image, orderindex, lastupdate) - VALUES(' . (int)$ps_product->id . ', \'' . pSQL($io6image->imageUri) . '\', 0,' . (int)$io6image->orderIndex . ',' . date('YmdHis', strtotime($io6image->lastUpdate)) . ' ) ; '); - } else { - //scarica l'immagine - $image_data = $this->downloadImage($io6image->imageUri); // Get image data - if (!isset($image_data) || $image_data === false) continue; - - $image_filename = date('YmdHis') . '_' . basename($io6image->imageUri); - $image_filepath = IO6_IMAGES_DIRPATH . $image_filename; - - file_put_contents($image_filepath, $image_data); - - $cms_image = new Image(); - $cms_image->id_product = (int)$ps_product->id; - $cms_image->position = Image::getHighestPosition((int)$ps_product->id) + 1; - $cms_image->cover = ((bool)Image::getCover((int)$ps_product->id)) ? 0 : 1; - - if ($cms_image->add()) { - // $cms_image->associateTo((int)(Context::getContext()->shop->id)); //Non serve perchè il metodo ->add già associa in automatico a tutti gli shop - if (@$this->generateImgIntoCms((int)$ps_product->id, $image_filepath, $cms_image)) { - // $this->echoDebug("added image=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_DEBUG); - Db::getInstance()->Execute('INSERT IGNORE INTO `' . _DB_PREFIX_ . 'importerone6connect_images` (id_product, image_uri, id_image, orderindex, lastupdate) - VALUES(' . (int)$ps_product->id . ', \'' . pSQL($io6image->imageUri) . '\', ' . (int)$cms_image->id . ',' . (int)$io6image->orderIndex . ',' . date('YmdHis', strtotime($io6image->lastUpdate)) . ' ) ; '); + + if ($to_download) { + //Verificare parametro se fare il download subito oppure ritardato (realtime dal sito), se ritardato inserire solo la riga nella tabella io_images con id_image = 0 + if ($delayedDownloadsImages) { + //Inserisco riga in tabella io_images con id_image = 0 + Db::getInstance()->Execute('INSERT IGNORE INTO `' . _DB_PREFIX_ . 'importerone6connect_images` (id_product, image_uri, id_image, orderindex, lastupdate) + VALUES(' . (int)$ps_product->id . ', \'' . pSQL($io6image->imageUri) . '\', 0,' . (int)$io6image->orderIndex . ',' . date('YmdHis', strtotime($io6image->lastUpdate)) . ' ) ; '); + } else { + //scarica l'immagine + $image_data = $this->downloadImage($io6image->imageUri); // Get image data + if (!isset($image_data) || $image_data === false) continue; + + $finfo = new finfo(FILEINFO_MIME_TYPE); + $image_mime_type = $finfo->buffer($image_data); + + if (!str_contains($image_mime_type, 'image')) continue; + + if (str_contains($image_mime_type, 'bmp')) continue; + + $image_filename = date('YmdHis') . '_' . basename($io6image->imageUri); + $image_filepath = IO6_IMAGES_DIRPATH . $image_filename; + + file_put_contents($image_filepath, $image_data); + + $cms_image = new Image(); + $cms_image->id_product = (int)$ps_product->id; + $cms_image->position = Image::getHighestPosition((int)$ps_product->id) + 1; + $cms_image->cover = ((bool)Image::getCover((int)$ps_product->id)) ? 0 : 1; + + if ($cms_image->add()) { + // $cms_image->associateTo((int)(Context::getContext()->shop->id)); //Non serve perchè il metodo ->add già associa in automatico a tutti gli shop + if (@$this->generateImgIntoCms((int)$ps_product->id, $image_filepath, $cms_image)) { + // $this->echoDebug("added image=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_DEBUG); + Db::getInstance()->Execute('INSERT IGNORE INTO `' . _DB_PREFIX_ . 'importerone6connect_images` (id_product, image_uri, id_image, orderindex, lastupdate) + VALUES(' . (int)$ps_product->id . ', \'' . pSQL($io6image->imageUri) . '\', ' . (int)$cms_image->id . ',' . (int)$io6image->orderIndex . ',' . date('YmdHis', strtotime($io6image->lastUpdate)) . ' ) ; '); + } else { + $cms_image->delete(); //Rimuovo anche anagrafica immagine + // $this->echoDebug("generateImgIntoCms non riuscita. product_image_url=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_WARNING); + // $this->count_notsaved++; + } } else { - $cms_image->delete(); //Rimuovo anche anagrafica immagine - // $this->echoDebug("generateImgIntoCms non riuscita. product_image_url=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_WARNING); // $this->count_notsaved++; + // $this->echoDebug("errore image add=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_WARNING); } - } else { - // $this->count_notsaved++; - // $this->echoDebug("errore image add=" . $image_filepath . " id product=" . $id_product, IO_LEVEL_WARNING); + unlink($image_filepath); + + //usleep(1000000/3); } - unlink($image_filepath); - - //usleep(1000000/3); } } - } - - //pulizia immagini inversa - if (!$isNewProduct) { - // $sql = 'SELECT id_product, id_image, image_uri, lastupdate FROM '._DB_PREFIX_.'importerone6connect_images WHERE id_product = ' . (int)$ps_product->id; - $sql = 'SELECT ' . _DB_PREFIX_ . 'image.id_product, ' . _DB_PREFIX_ . 'image.id_image, ' . _DB_PREFIX_ . 'importerone6connect_images.image_uri as io6ImageUri FROM `' . _DB_PREFIX_ . 'image` - INNER JOIN `' . _DB_PREFIX_ . 'importerone6connect_images` ON `' . _DB_PREFIX_ . 'image`.id_product = `' . _DB_PREFIX_ . 'importerone6connect_images`.id_product AND `' . _DB_PREFIX_ . 'image`.id_image = `' . _DB_PREFIX_ . 'importerone6connect_images`.id_image - WHERE `' . _DB_PREFIX_ . 'image`.id_product = ' . (int)$ps_product->id; - $checkGallery = DB::getInstance()->executeS($sql); - - foreach ($checkGallery as $checkImage) { - $foundImage = !empty($checkImage['io6ImageUri']); - - $foundImage &= !empty(array_filter( - $io6product->images, - function ($image) use ($checkImage) { - return $checkImage['io6ImageUri'] == $image->imageUri; - } - )); - - if (!$foundImage) { - $idImageToDel = (int)$checkImage['id_image']; - if ($idImageToDel > 0) { - $imageToDel = new Image($idImageToDel); - $imageToDel->delete(); + + //pulizia immagini inversa + if (!$isNewProduct) { + // $sql = 'SELECT id_product, id_image, image_uri, lastupdate FROM '._DB_PREFIX_.'importerone6connect_images WHERE id_product = ' . (int)$ps_product->id; + $sql = 'SELECT ' . _DB_PREFIX_ . 'image.id_product, ' . _DB_PREFIX_ . 'image.id_image, ' . _DB_PREFIX_ . 'importerone6connect_images.image_uri as io6ImageUri FROM `' . _DB_PREFIX_ . 'image` + INNER JOIN `' . _DB_PREFIX_ . 'importerone6connect_images` ON `' . _DB_PREFIX_ . 'image`.id_product = `' . _DB_PREFIX_ . 'importerone6connect_images`.id_product AND `' . _DB_PREFIX_ . 'image`.id_image = `' . _DB_PREFIX_ . 'importerone6connect_images`.id_image + WHERE `' . _DB_PREFIX_ . 'image`.id_product = ' . (int)$ps_product->id; + $checkGallery = DB::getInstance()->executeS($sql); + + foreach ($checkGallery as $checkImage) { + $foundImage = !empty($checkImage['io6ImageUri']); + + $foundImage &= !empty(array_filter( + $io6product->images, + function ($image) use ($checkImage) { + return $checkImage['io6ImageUri'] == $image->imageUri; + } + )); + + if (!$foundImage && !empty($checkImage['io6ImageUri'])) { + $idImageToDel = (int)$checkImage['id_image']; + if ($idImageToDel > 0) { + $imageToDel = new Image($idImageToDel); + $imageToDel->delete(); + } + //Elimino riga da tabella importerone6connect_images + $res = Db::getInstance()->Execute('DELETE FROM `' . _DB_PREFIX_ . 'importerone6connect_images` + WHERE id_product =' . (int)$checkImage['id_product'] . ' AND image_uri=\'' . pSQL($checkImage['io6ImageUri']) . '\';'); } - //Elimino riga da tabella importerone6connect_images - $res = Db::getInstance()->Execute('DELETE FROM `' . _DB_PREFIX_ . 'importerone6connect_images` - WHERE id_product =' . (int)$checkImage['id_product'] . ' AND image_uri=\'' . pSQL($checkImage['io6ImageUri']) . '\';'); } } + + //$this->io6_write_log(date('Y-m-d H:i:s') . " product images fine", IO6_LOG_WARNING); + //TODO CT 20210515 Fare controllo che ci sia una immagine con flag Cover=1, altrimenti impostarne una. } - - //$this->io6_write_log(date('Y-m-d H:i:s') . " product images fine", IO6_LOG_WARNING); - //TODO CT 20210515 Fare controllo che ci sia una immagine con flag Cover=1, altrimenti impostarne una. - } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product features start", IO6_LOG_WARNING); - if ($update_features) { - // $serialized_attributes = []; - // $position = 0; - foreach ($io6product->features as $feature) { - if (!$feature->searchable) continue; - - $attribute_label = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { - return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); - }, $feature->name); - $attribute_value = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { - return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); - }, $feature->value); - if (strlen($attribute_value) > 255) - $attribute_value = substr($attribute_value, 0, 255); - - if (empty($attribute_label) || empty($attribute_value) || !Validate::isGenericName($attribute_label) || !Validate::isGenericName($attribute_value)) { - //$this->echoDebug("Valori non validi per feature - attribute_label: " . $attribute_label . " - attribute_value: " . $attribute_value, IO_LEVEL_WARNING); - continue; - } - - $id_feature = Feature::addFeatureImport($attribute_label); - $custom = false; //forzo sempre a false per far abilitare le combo - $id_feature_value = (int)FeatureValue::addFeatureValueImport($id_feature, $attribute_value, $ps_product->id, $default_language, $custom); - $res = Product::addFeatureProductImport($ps_product->id, $id_feature, $id_feature_value); - if (!$res) { - throw new Exception("Caratteristica " . $attribute_label . " non salvata per il prodotto " . $ps_product->id); - } - - if ($manage_facetedsearch_models && $ps_product->id_category_default) { - - $defaultCategory = new Category($ps_product->id_category_default); - - // INIZIO CREAZIONE TEMPLATE PER LE CARATTERISTICHE - require_once('classes/ImporterOneFeature.php'); - $filtersData = array(); - // Creazione dei dati da inserire nel template - $filtersData['shop_list'] = Shop::getContextListShopID(); // array(Context::getContext()->shop->id); - $filtersData['categories'] = array($ps_product->id_category_default); - $filtersData['layered_selection_feat_' . $id_feature] = array('filter_type' => 0, 'filter_show_limit' => 0); - - $templateData = [ - 'name' => pSQL("modello-filtri-cat-" . $ps_product->id_category_default . "-" . $defaultCategory->getName()), - 'filters' => $filtersData, // andrà poi serializzato - 'n_categories' => (int) count($filtersData['categories']) - ]; - - if (ImporterOneFeature::saveTemplate($templateData, $this)) { - $this->io6_write_log("Il template " . $templateData['name'] . " è stato salvato con successo.", IO6_LOG_INFO); - } else { //TODO CT Non c'è nessun log nel metodo saveTemplate e quindi se ritorna False non si capisce il motivo - $this->io6_write_log("Non è stato possibile salvare il template " . $templateData['name'], IO6_LOG_ERROR); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product features start", IO6_LOG_WARNING); + if ($update_features) { + // $serialized_attributes = []; + // $position = 0; + foreach ($io6product->features as $feature) { + if (!$feature->searchable) continue; + + $attribute_label = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { + return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); + }, $feature->name); + $attribute_value = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { + return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); + }, $feature->value); + if (strlen($attribute_value) > 255) + $attribute_value = substr($attribute_value, 0, 255); + + if (empty($attribute_label) || empty($attribute_value) || !Validate::isGenericName($attribute_label) || !Validate::isGenericName($attribute_value)) { + //$this->echoDebug("Valori non validi per feature - attribute_label: " . $attribute_label . " - attribute_value: " . $attribute_value, IO_LEVEL_WARNING); + continue; + } + + $id_feature = Feature::addFeatureImport($attribute_label); + $custom = false; //forzo sempre a false per far abilitare le combo + $id_feature_value = (int)FeatureValue::addFeatureValueImport($id_feature, $attribute_value, $ps_product->id, $default_language, $custom); + $res = Product::addFeatureProductImport($ps_product->id, $id_feature, $id_feature_value); + if (!$res) { + throw new Exception("Caratteristica " . $attribute_label . " non salvata per il prodotto " . $ps_product->id); + } + + if ($manage_facetedsearch_models && $ps_product->id_category_default) { + + $defaultCategory = new Category($ps_product->id_category_default); + + // INIZIO CREAZIONE TEMPLATE PER LE CARATTERISTICHE + require_once('classes/ImporterOneFeature.php'); + $filtersData = array(); + // Creazione dei dati da inserire nel template + $filtersData['shop_list'] = Shop::getContextListShopID(); // array(Context::getContext()->shop->id); + $filtersData['categories'] = array($ps_product->id_category_default); + $filtersData['layered_selection_feat_' . $id_feature] = array('filter_type' => 0, 'filter_show_limit' => 0); + + $templateData = [ + 'name' => pSQL("modello-filtri-cat-" . $ps_product->id_category_default . "-" . $defaultCategory->getName()), + 'filters' => $filtersData, // andrà poi serializzato + 'n_categories' => (int) count($filtersData['categories']) + ]; + + if (ImporterOneFeature::saveTemplate($templateData, $this)) { + $this->io6_write_log("Il template " . $templateData['name'] . " è stato salvato con successo.", IO6_LOG_INFO); + } else { //TODO CT Non c'è nessun log nel metodo saveTemplate e quindi se ritorna False non si capisce il motivo + $this->io6_write_log("Non è stato possibile salvare il template " . $templateData['name'], IO6_LOG_ERROR); + } + // FINE CREAZIONE TEMPLATE PER LE CARATTERISTICHE } - // FINE CREAZIONE TEMPLATE PER LE CARATTERISTICHE } } - } - //$this->io6_write_log(date('Y-m-d H:i:s') . " product features fine", IO6_LOG_WARNING); - - $retProduct['activeState'] = $activeState; - $retProduct['status'] = 'OK'; - $retProduct['status_message'] = "Ok"; - $sync_status = 1; - $sync_message = $retProduct['status_message']; - - if (isset($ps_product->id) && $ps_product->id > 0) { - $retProduct['ps_product_id'] = $ps_product->id; - - //TODO CT 20210510 Il salvataggio del prodotto scatena anche l'hook che già fa la insert, quindi si potrebbe pensare di fare solo l'update o cercare di non far eseguire quell'hook - $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'importerone6connect_products` - (`id_product`, `io6_id_product`, `sync_status`, `sync_message`, `sync_exclude`, `sync_date`, `manage_title`, `manage_shortdescription`, `manage_description`, - `manage_categories`, `manage_prices`, `manage_stock`, `manage_images`, `manage_features`, `manage_dimensions`, `manage_weight`, `manage_htmlfeatures`, `manage_tax_rule`, `htmlfeatures`, `official_price`) - VALUES ( - ' . (int)$ps_product->id . ', - ' . (int)$io6product->id . ', - ' . (int)$sync_status . ', - \'' . pSQL($sync_message) . '\', - 0, - ' . date('YmdHis') . ', - 2,2,2,2,2,2,2,2,2,2,2,2, - \'' . pSQL(htmlentities($htmlfeatures)) . '\', - ' . floatval($official_price) . ' - ) ON DUPLICATE KEY UPDATE - `io6_id_product` = ' . (int)$io6product->id . ', - `sync_status` = ' . (int)$sync_status . ', - `sync_message` = \'' . pSQL($sync_message) . '\', - `sync_date` = ' . date('YmdHis') . ', - `official_price` = ' . floatval($official_price) . ' - ' . ($update_features_html ? ', `htmlfeatures` = \'' . pSQL(htmlentities($htmlfeatures)) . '\' ' : ';'); - //$this->io6_write_log($sql, IO6_LOG_INFO); - if (!Db::getInstance()->execute($sql)) { - $this->context->controller->errors[] = Tools::displayError('Error: ') . Db::getInstance()->getNumberError() . Db::getInstance()->getMsgError(); + //$this->io6_write_log(date('Y-m-d H:i:s') . " product features fine", IO6_LOG_WARNING); + + $retProduct['activeState'] = $activeState; + $retProduct['status'] = 'OK'; + $retProduct['status_message'] = "Ok"; + $sync_status = 1; + $sync_message = $retProduct['status_message']; + + if (isset($ps_product->id) && $ps_product->id > 0) { + $retProduct['ps_product_id'] = $ps_product->id; + + //TODO CT 20210510 Il salvataggio del prodotto scatena anche l'hook che già fa la insert, quindi si potrebbe pensare di fare solo l'update o cercare di non far eseguire quell'hook + $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'importerone6connect_products` + (`id_product`, `catalog_id`, `io6_id_product`, `sync_status`, `sync_message`, `sync_exclude`, `sync_date`, `manage_title`, `manage_shortdescription`, `manage_description`, + `manage_categories`, `manage_prices`, `manage_stock`, `manage_images`, `manage_features`, `manage_dimensions`, `manage_weight`, `manage_htmlfeatures`, `manage_tax_rule`, `htmlfeatures`, `official_price`) + VALUES ( + ' . (int)$ps_product->id . ', + ' . (int)$catalogId . ', + ' . (int)$io6product->id . ', + ' . (int)$sync_status . ', + \'' . pSQL($sync_message) . '\', + 0, + ' . date('YmdHis') . ', + 2,2,2,2,2,2,2,2,2,2,2,2, + \'' . pSQL(htmlentities($htmlfeatures)) . '\', + ' . floatval($official_price) . ' + ) ON DUPLICATE KEY UPDATE + `catalog_id` = '. (int)$catalogId.', + `io6_id_product` = ' . (int)$io6product->id . ', + `sync_status` = ' . (int)$sync_status . ', + `sync_message` = \'' . pSQL($sync_message) . '\', + `sync_date` = ' . date('YmdHis') . ', + `official_price` = ' . floatval($official_price) . ' + ' . ($update_features_html ? ', `htmlfeatures` = \'' . pSQL(htmlentities($htmlfeatures)) . '\' ' : ';'); + //$this->io6_write_log($sql, IO6_LOG_INFO); + if (!Db::getInstance()->execute($sql)) { + $this->io6_write_log($sql, IO6_LOG_INFO); + $this->io6_write_log("Errore salvataggio tabella appoggio", IO6_LOG_INFO); + $this->context->controller->errors[] = Tools::displayError('Error: ') . Db::getInstance()->getNumberError() . Db::getInstance()->getMsgError(); + } + //Riga commentata perchè non necessario salvare in cache il prodotto appena importato + //Durante l'attuale sincro potrà essere importato 1 volta sola + //$_SESSION['products_cache'][$io6product->id] = $ps_product->id; } - $this->ps_products_cache[$io6product->id] = $ps_product->id; + + Hook::exec('actionIO6ProductSaveAfter', ['io6_product' => &$io6product, 'ps_product' => &$ps_product]); } } catch (Exception $e) { $retProduct['status'] = 'KO'; @@ -1484,6 +1601,9 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface array_push($syncResults['products'], $retProduct); //$this->io6_write_log(date('Y-m-d H:i:s') . " product fine", IO6_LOG_WARNING); //TODO CT 20210511 Se gli passo $e va in errore di memory limit } + + + //$this->io6_write_log("clean positions inizio", IO6_LOG_WARNING); //TODO CT 20210511 Se gli passo $e va in errore di memory limit if(!empty($categories_to_clean)){ @@ -1496,17 +1616,23 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface //$this->io6_write_log("clean positions fine", IO6_LOG_WARNING); //TODO CT 20210511 Se gli passo $e va in errore di memory limit //resetCatalog e Rebuild indici se arrivati all'ultima pagina - if ($currentPage == $io6_results['pages'] && empty($io6_id_product_syngle_sync)) { + if ($currentPage == $io6_results['pages'] && empty($io6_id_product_syngle_sync)) { + $_SESSION['categories_cache'] = []; + $_SESSION['brands_cache'] = []; + $_SESSION['suppliers_cache'] = []; + $_SESSION['products_cache'] = []; + //Resettare solo i prodotti gestiti da ImporterONE, ovvero presenti in importerone6connect_products e con flag sync_exclude <> 1 Db::getInstance()->Execute('UPDATE `' . _DB_PREFIX_ . 'product` product INNER JOIN `' . _DB_PREFIX_ . 'importerone6connect_products` ioprod ON product.id_product = ioprod.id_product SET product.`active` = 0 - WHERE product.`active` = 1 and ioprod.`sync_exclude` = 0 AND ioprod.io6_id_product > 0 AND IFNULL(ioprod.sync_status, 0) <> 1;'); + WHERE product.`active` = 1 and ioprod.`sync_exclude` = 0 AND ioprod.io6_id_product > 0 AND IFNULL(ioprod.sync_status, 0) <> 1 + AND ioprod.catalog_id = '.(int)$catalogId.';'); Db::getInstance()->Execute('UPDATE `' . _DB_PREFIX_ . 'stock_available` sa - INNER JOIN `' . _DB_PREFIX_ . 'product` p ON p.id_product = sa.id_product + INNER JOIN `' . _DB_PREFIX_ . 'product` p ON p.id_product = sa.id_product INNER JOIN `' . _DB_PREFIX_ . 'importerone6connect_products` ioprod ON p.id_product = ioprod.id_product - SET sa.`quantity` = 0 - WHERE p.`active` = 0 and ioprod.`sync_exclude` = 0 AND ioprod.io6_id_product > 0;'); + SET sa.`quantity` = 0 + WHERE p.`active` = 0 and ioprod.`sync_exclude` = 0 AND ioprod.io6_id_product > 0 AND sa.quantity > 0;'); Db::getInstance()->Execute('UPDATE `' . _DB_PREFIX_ . 'product_shop` p_shop INNER JOIN `' . _DB_PREFIX_ . 'product` p ON p_shop.id_product = p.id_product SET p_shop.active = p.active @@ -1528,11 +1654,11 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $image_data = curl_exec($ch); - + if (!empty($image_data)) return $image_data; - } - + } + if (!function_exists('curl_version')){ $image_data = @file_get_contents($image_uri); if (!empty($image_data)) @@ -1605,50 +1731,52 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface if ($checkApiSettings) { $io6Catalogs = $io6Engine->GetIO6Catalogs(); - - $io6CatalogsMatchingSelected = array_filter( - $io6Catalogs, - function ($e) use ($io6_configuration) { - return $e->id == $io6_configuration->catalogId; + $hasCatalogSelected = false; + $hasPriceSelected = false; + foreach ($io6Catalogs as $catalogId => $catalog) { + if (isset($io6_configuration->catalogsData[$catalogId]) && !empty($io6_configuration->catalogsData[$catalogId])){ + $catalog->selected = true; + $hasCatalogSelected = true; } - ); - - if (count($io6Catalogs) > 0 && empty($io6_configuration->catalogId) || count($io6CatalogsMatchingSelected) == 0) - array_unshift($io6Catalogs, array('id' => '0', 'name' => 'Selezionare un catalogo')); - if (count($io6Catalogs) == 0) - $io6Catalogs = array(array('id' => '0', 'name' => 'Nessun Catalogo disponibile')); - $io6Pricelists = []; - if ($io6_configuration->catalogId > 0 && count($io6CatalogsMatchingSelected) > 0) { - $io6Pricelists = $io6Engine->GetIO6PriceLists(); + $catalog->priceLists = $io6Engine->GetIO6PriceLists($catalog->id); - $io6PricelistsMatchingSelected = array_filter( - $io6Pricelists, - function ($e) use ($io6_configuration) { - return $e->id == $io6_configuration->priceListId; + foreach($catalog->priceLists as $priceList){ + if ($priceList->id == $io6_configuration->catalogsData[$catalogId]['price_list_id']){ + $priceList->selected = true; + $hasPriceSelected = true; } - ); - if (empty($io6_configuration->priceListId) || count($io6PricelistsMatchingSelected) == 0) - array_unshift($io6Pricelists, array('id' => '0', 'name' => 'Selezionare un listino')); - if (count($io6Pricelists) == 0) - $io6Pricelists = array(array('id' => '0', 'name' => 'Nessun listino disponibile')); - } - + } + if (!isset($catalog->priceLists) || count($catalog->priceLists) == 0){ + $catalog->priceLists = array(new Io6PriceList(['id' => '0', 'name' => 'Nessun listino disponibile'])); + } else { + array_unshift($catalog->priceLists, new Io6PriceList(['id' => '0', 'name' => 'Selezionare un listino'])); + } + } - /*$io6Catalogs = array( //Per test - array('id' => '1', 'name' => 'Catalogo 1'), - array('id' => '2', 'name' => 'Catalogo 2') - ); - $io6Pricelists = array(//Per test - array('id' => '1', 'name' => 'Listino 1'), - array('id' => '2', 'name' => 'Listino 2'), - array('id' => '3', 'name' => 'Listino 3') - );*/ + $productInDisabledCatalog = []; + $hasProductInDisabledCatalog = false; + if(isset($io6_configuration->catalogsData) && !empty($io6_configuration->catalogsData)){ + //Check for products not in catalogs from ImporterONE + $sql = "SELECT ip.catalog_id, COUNT(p.id_product) as products_count FROM ". _DB_PREFIX_ ."importerone6connect_products ip + LEFT JOIN ". _DB_PREFIX_ ."product p ON p.id_product = ip.id_product + WHERE p.active = 1 AND ip.catalog_id NOT IN (".implode(',', array_keys($io6_configuration->catalogsData)).") AND ip.catalog_id != 0 + GROUP BY ip.catalog_id"; + $productsNotInEnabledCatalogs = Db::getInstance()->executeS($sql); + + foreach ($productsNotInEnabledCatalogs as $product) { + if(!$hasProductInDisabledCatalog) + $hasProductInDisabledCatalog = true; + + $productInDisabledCatalog[$product['catalog_id']]['catalog_name'] = isset($io6Catalogs[$product['catalog_id']]) ? $io6Catalogs[$product['catalog_id']]->name : ''; + $productInDisabledCatalog[$product['catalog_id']]['products_count'] = $product['products_count']; + } + } - $output .= $this->renderFormGeneralSettings($io6Catalogs, $io6Pricelists); + $output .= $this->renderFormGeneralSettings($io6Catalogs, $productInDisabledCatalog); - if (!empty(Configuration::get('IMPORTERONE6CONNECT_CATALOG')) && count($io6CatalogsMatchingSelected) > 0 && count($io6PricelistsMatchingSelected) > 0) { + if (!empty(Configuration::get('IMPORTERONE6CONNECT_CATALOGS')) && $hasCatalogSelected && $hasPriceSelected) { $output .= $this->renderFormProductsSettings(); @@ -1656,6 +1784,8 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $output .= $this->renderFormExecute(); + $output .= $this->renderFormCron(); + $output .= $this->renderFormStatistiche(); } } @@ -1808,31 +1938,21 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface /* <-- Form di Api Settings Fine */ - - /* Form di General Settings Inizio --> */ - protected function renderFormGeneralSettings(array $io6Catalogs = [], array $io6Pricelists = []) - { - $helper = new HelperForm(); - - $helper->show_toolbar = false; - $helper->table = $this->table; - $helper->module = $this; - $helper->default_form_language = $this->context->language->id; - $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0); - - $helper->identifier = $this->identifier; - $helper->submit_action = 'submitImporterone6connectModule_GeneralSettings'; - $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) - . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name; - $helper->token = Tools::getAdminTokenLite('AdminModules'); - - $helper->tpl_vars = array( - 'fields_value' => $this->getConfigFormValuesGeneralSettings(), /* Add values for your inputs */ - 'languages' => $this->context->controller->getLanguages(), - 'id_language' => $this->context->language->id, + protected function renderFormGeneralSettings(array $io6Catalogs = [], array $productInDisabledCatalog = []){ + //$executeUrl = Context::getContext()->link->getModuleLink($this->name, 'actions', array('action' => 'expandStatisticInfo')); + $exportCategoriesUrl = $this->context->link->getModuleLink($this->name, 'actions', ['action' => 'exportCategoriesTree']); + + $this->context->smarty->assign( + array( + 'moduleName' => $this->name, + 'io6Catalogs' => $io6Catalogs, + 'productsInDisabledCatalogs' => $productInDisabledCatalog, + 'exportCategoriesUrl' => $exportCategoriesUrl + ) ); - return $helper->generateForm(array($this->getConfigFormGeneralSettings($io6Catalogs, $io6Pricelists))); + $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/configure_general.tpl'); + return $output; } /** @@ -1858,7 +1978,18 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface 'name' => 'name' ), ), - + array( + 'type' => 'select', + 'multiple' => true, + 'label' => $this->l('Cataloghi'), + 'name' => 'IMPORTERONE6CONNECT_CATALOGS', + 'desc' => $this->l('Seleziona i Cataloghi ImporeterONE da cui importare i prodotti'), + 'options' => array( + 'query' => $io6Catalogs, + 'id' => 'id', + 'name' => 'name' + ), + ), ), 'submit' => array( 'title' => $this->l('Save'), @@ -1901,10 +2032,17 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface { $output = ""; $result = true; - $form_values = $this->getConfigFormValuesGeneralSettings(); - foreach (array_keys($form_values) as $key) { - $result &= Configuration::updateValue($key, Tools::getValue($key)); + $catalogSaved = []; + if (!empty(Tools::getValue("IMPORTERONE6CONNECT_CATALOGS"))){ + $catalogs = Tools::getValue("IMPORTERONE6CONNECT_CATALOGS"); + + foreach ($catalogs as $key => $value) { + if (!empty($value['price_list_id'])) + $catalogSaved[$key] = ["catalog_id" => $key, "catalog_name" => $value['catalog_name'] ,"price_list_id" => (int)$value['price_list_id']]; + } + + $result &= Configuration::updateValue("IMPORTERONE6CONNECT_CATALOGS", serialize($catalogSaved)); } if ($result) @@ -1939,6 +2077,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface 'id_language' => $this->context->language->id, ); + return $helper->generateForm(array($this->getConfigFormProductsSettings())); } @@ -1972,6 +2111,25 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface 'name' => 'name' ), ), + array( + 'type' => 'switch', + 'label' => $this->l('Utilizza i fornitori come filtro per la ricerca'), + 'name' => 'IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS', + 'is_bool' => true, + 'desc' => $this->l('Verranno presi in considerazione solo i prodotti associati con fornitori ImporterONE.'), + 'values' => array( + array( + 'id' => 'manage_io6_suppliers', + 'value' => true, + 'label' => $this->l('Enabled') + ), + array( + 'id' => 'manage_io6_suppliers', + 'value' => false, + 'label' => $this->l('Disabled') + ) + ), + ), array( 'type' => 'switch', 'label' => $this->l('Aggiorna i titoli'), @@ -2337,6 +2495,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface 'IMPORTERONE6CONNECT_MANAGE_FACETEDSEARCH_MODELS' => Configuration::get('IMPORTERONE6CONNECT_MANAGE_FACETEDSEARCH_MODELS'), 'IMPORTERONE6CONNECT_MANAGE_TAX_RULE_DEFAULT' => Configuration::get('IMPORTERONE6CONNECT_MANAGE_TAX_RULE_DEFAULT'), 'IMPORTERONE6CONNECT_TAX_RULE_DEFAULT' => Configuration::get('IMPORTERONE6CONNECT_TAX_RULE_DEFAULT'), + 'IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS' => Configuration::get('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS'), ); } @@ -2389,6 +2548,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface 'languages' => $this->context->controller->getLanguages(), 'id_language' => $this->context->language->id, ); + return $helper->generateForm(array($this->getConfigFormImportSettings())); } @@ -2614,30 +2774,43 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface */ protected function renderFormExecute() { - $executeUrl = Context::getContext()->link->getModuleLink($this->name, 'actions', array('action' => 'executeSync')); //, 'token' => Tools::getToken(false) - $cronCommand = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '"'; - $cronCommandFast = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '&fast=1"'; - $cronCommandWarning = $cronCommand . '&accettoAvvisoRequisiti=1"'; - $cronCommandFastWarning = $cronCommandFast . '&accettoAvvisoRequisiti=1"'; + $server_requirements = $this->checkServerRequirements(); - $cronCommandDownloadImages = 'curl -s "'.Context::getContext()->link->getModuleLink($this->name, 'downloadImages', array('limit' => '10000')).'"'; + $lastProductSyncDate = ''; + $sql = "SELECT COUNT(iop.id_product) FROM ". _DB_PREFIX_ ."importerone6connect_products iop + INNER JOIN ". _DB_PREFIX_ ."product p ON p.id_product = iop.id_product + WHERE iop.sync_status = 0 AND iop.sync_exclude = 0 AND p.active = 1"; + $product_not_synced = Db::getInstance()->getValue($sql); - $server_requirements = $this->checkServerRequirements(); + if($product_not_synced > 0){ + $sql = "SELECT MAX(iop.sync_date) FROM ". _DB_PREFIX_ ."importerone6connect_products iop"; + $lastProductSyncDate = Db::getInstance()->getValue($sql); + } + + $sql = "SELECT COUNT(p.id_product) FROM ". _DB_PREFIX_ ."product p + LEFT JOIN ". _DB_PREFIX_ ."importerone6connect_products ip ON ip.id_product = p.id_product + WHERE ip.id_product IS NULL"; + $productNotInIo6Tables = Db::getInstance()->getValue($sql); if (Tools::getValue('execute') == '1') { $this->io6Sync(); } + //Funzionalità per convertire la data alla timezone del client + if (!empty($lastProductSyncDate)){ + $lastProductSyncDate = $this->convertDateToCurrentTimezone($lastProductSyncDate); + } + + $executeUrl = Context::getContext()->link->getModuleLink($this->name, 'actions', array('action' => 'executeSync')); //, 'token' => Tools::getToken(false) + $this->context->smarty->assign( array( + 'syncResume' => $product_not_synced > 0 ? true : false, + 'lastProductSyncDate' => $lastProductSyncDate, + 'productNotInIo6Tables' => $productNotInIo6Tables, 'executePageSize' => Configuration::get("IMPORTERONE6CONNECT_PAGESIZE"), 'executeUrl' => $executeUrl, - 'cronCommand' => $cronCommand, - 'cronCommandFast' => $cronCommandFast, - 'cronCommandWarning' => $cronCommandWarning, - 'cronCommandFastWarning' => $cronCommandFastWarning, - 'cronCommandDownloadImages' => $cronCommandDownloadImages, 'serverRequirements' => $server_requirements, //'cronUrl' => Tools::getHttpHost(true). "/modules/icecool/cron.php?icecoolCron=1" //"?token=".Tools::hash("icecool/cron") //'cronUrl' => _PS_BASE_URL_ . "/modules/icecool/cron.php?icecoolCron=1" //"?token=".Tools::hash("icecool/cron") @@ -2648,6 +2821,50 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface return $output; } + function convertDateToCurrentTimezone($lastProductSyncDate){ + $oldTimezone = date_default_timezone_get(); + $newTimezone = new DateTimeZone("Europe/Rome"); + $dateToConvert = date_create($lastProductSyncDate, new DateTimeZone($oldTimezone)); + $dateToConvert->setTimezone($newTimezone); + + return $dateToConvert->format('d/m/Y H:i:s'); + } + + /** + * Form Execute and Cron + */ + protected function renderFormCron() + { + $io6_catalogs = unserialize(Configuration::get('IMPORTERONE6CONNECT_CATALOGS')); + + $cronCommands = []; + $cronCommandsFast = []; + $cronCommandsWarning = []; + $cronCommandsFastWarning = []; + foreach ($io6_catalogs as $key => $catalog) { + $executeUrl = Context::getContext()->link->getModuleLink($this->name, 'actions', array('action' => 'executeSync', "catalogId" => $catalog['catalog_id'])); //, 'token' => Tools::getToken(false) + $cronCommands[$catalog['catalog_name']] = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '"'; + $cronCommandsFast[$catalog['catalog_name']] = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '&fast=1"'; + $cronCommandsWarning[$catalog['catalog_name']] = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '&accettoAvvisoRequisiti=1"'; + $cronCommandsFastWarning[$catalog['catalog_name']] = "php " . dirname(__FILE__) . '/cron.php "' . $executeUrl . '&fast=1&accettoAvvisoRequisiti=1"'; + } + + $cronCommandDownloadImages = 'curl -s "'.Context::getContext()->link->getModuleLink($this->name, 'downloadImages', array('limit' => '10000')).'"'; + + $this->context->smarty->assign( + array( + 'cronCommands' => $cronCommands, + 'cronCommandsFast' => $cronCommandsFast, + 'cronCommandsWarning' => $cronCommandsWarning, + 'cronCommandsFastWarning' => $cronCommandsFastWarning, + 'cronCommandDownloadImages' => $cronCommandDownloadImages, + ) + ); + + $output = $this->context->smarty->fetch($this->local_path . 'views/templates/admin/cron_section.tpl'); + return $output; + } + /** * Form Execute and Cron */ @@ -2734,6 +2951,7 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface $this->context->smarty->assign( array( 'importerone6connect_io6_id_product' => $results[0]['io6_id_product'], + 'importerone6connect_catalog_id' => $results[0]['catalog_id'], 'importerone6connect_sync_exclude' => $results[0]['sync_exclude'], 'importerone6connect_sync_status' => $results[0]['sync_status'], 'importerone6connect_sync_message' => $results[0]['sync_message'], @@ -3060,12 +3278,23 @@ class Ps_Connect_Io6 extends Module implements WidgetInterface } } + function formatByte($size) + { + $unit = array('b', 'KB', 'MB', 'GB', 'TB', 'PB'); + $ram = number_format(@round($size / pow(1024, ($i = floor(log($size, 1024)))), 2),2); + return $ram . ' ' . $unit[$i]; + } + public function io6_write_log($log, $level) { $logFile = IO6_LOG_DIRPATH . date('Ymd') . ".txt"; $time = date('Y-m-d H:i:s'); - $logMessage = sprintf("%s - %s: %s\r\n", $time, $level, (is_array($log) || is_object($log) ? print_r($log, true) : $log)); + $ram = $this->formatByte(memory_get_peak_usage()) . " - " . $this->formatByte(memory_get_usage()); + + $logMessage = sprintf("ram: %s - %s - %s: %s\r\n", $ram, $time, $level, (is_array($log) || is_object($log) ? print_r($log, true) : $log)); error_log($logMessage, 3, $logFile); } + + } diff --git a/sql/install.php b/sql/install.php index 76481f4587044bf2fd91b0fe50cd090979c6b582..30aa72ec33b45c926be413ab703a448abb379f15 100644 --- a/sql/install.php +++ b/sql/install.php @@ -27,6 +27,7 @@ $sql = array(); $sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'importerone6connect_products` ( `id_product` int UNSIGNED NOT NULL, + `catalog_id` int unsigned DEFAULT \'0\', `io6_id_product` int UNSIGNED NULL, `sync_status` int DEFAULT NULL, `sync_message` text, diff --git a/src/Form/Modifier/ProductFormModifier.php b/src/Form/Modifier/ProductFormModifier.php old mode 100644 new mode 100755 index fa0ee9d498c2fb914e1c3799e12eadf13e798daa..0b772b9e358eccf09438ca4e8e417b3dff53099b --- a/src/Form/Modifier/ProductFormModifier.php +++ b/src/Form/Modifier/ProductFormModifier.php @@ -86,7 +86,7 @@ final class ProductFormModifier ); if (!empty($io6_data['io6_id_product'])){ - $single_sync_url = Context::getContext()->link->getAdminLink('AdminPsConnectIo6ActionsController', true, array('route' => 'admin_io6_productsync', 'io6_id_product' => $io6_data['io6_id_product'], 'new_product_page' => true)); + $single_sync_url = Context::getContext()->link->getAdminLink('AdminPsConnectIo6ActionsController', true, array('route' => 'admin_io6_productsync', 'io6_id_product' => $io6_data['io6_id_product'], 'catalogId' => $io6_data['catalog_id'], 'new_product_page' => true)); $this->formBuilderModifier->addAfter( $descriptionTabFormBuilder, // the tab 'importerone_info', // the input/form from which to insert after/before diff --git a/upgrade/upgrade-2.0.0.php b/upgrade/upgrade-2.0.0.php new file mode 100644 index 0000000000000000000000000000000000000000..05833734ed5516dbdad0614215b2ecd07e0fc02d --- /dev/null +++ b/upgrade/upgrade-2.0.0.php @@ -0,0 +1,55 @@ +<?php +/** +* 2007-2020 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA <contact@prestashop.com> +* @copyright 2007-2020 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ +if (!defined('_PS_VERSION_')) { + exit; +} + +function upgrade_module_2_0_0($module) +{ + $result = true; + + if (!Configuration::hasKey('IMPORTERONE6CONNECT_CATALOGS')) + $result &= Configuration::updateValue('IMPORTERONE6CONNECT_CATALOGS', serialize([])); + if (!Configuration::hasKey('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS')) + $result &= Configuration::updateValue('IMPORTERONE6CONNECT_MANAGE_IO6_SUPPLIERS', 1); + + $sql = "ALTER TABLE "._DB_PREFIX_."importerone6connect_products ADD COLUMN catalog_id int UNSIGNED DEFAULT 0 AFTER id_product"; + $result &= Db::getInstance()->execute($sql); + + $result &= $module->registerHook('actionIO6ProductSaveBefore'); + $result &= $module->registerHook('actionIO6ProductSaveAfter'); + $result &= $module->registerHook('actionIO6CategorySaveBefore'); + $result &= $module->registerHook('actionIO6CategorySaveAfter'); + $result &= $module->registerHook('actionIO6BrandSaveBefore'); + $result &= $module->registerHook('actionIO6BrandSaveAfter'); + $result &= $module->registerHook('actionIO6SupplierSaveBefore'); + $result &= $module->registerHook('actionIO6SupplierSaveAfter'); + + $result &= $module->uninstallOverrides(); + $result &= $module->installOverrides(); + + return $result; +} diff --git a/vendor/.htaccess b/vendor/.htaccess old mode 100644 new mode 100755 index 3de9e4008bd960a5b589911c311332b266288ed9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 --- a/vendor/.htaccess +++ b/vendor/.htaccess @@ -1,10 +0,0 @@ -# Apache 2.2 -<IfModule !mod_authz_core.c> - Order deny,allow - Deny from all -</IfModule> - -# Apache 2.4 -<IfModule mod_authz_core.c> - Require all denied -</IfModule> diff --git a/vendor/autoload.php b/vendor/autoload.php old mode 100644 new mode 100755 index af4eafedc6c5df3941be227fb7045e251856b799..e373bbeaf5f66149383275d5611eabf020524d3c --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInita5a6e2bb0a11e75425aaca6316dc467d::getLoader(); +return ComposerAutoloaderInit8bda4515f096db9c6abfe2b891767c21::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php old mode 100644 new mode 100755 diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php old mode 100644 new mode 100755 index b6a89e526086d7f27120156766c781a62a5eeb1d..a06d87584279c4ce25c9b4714145c95d8f9644a1 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInita5a6e2bb0a11e75425aaca6316dc467d +class ComposerAutoloaderInit8bda4515f096db9c6abfe2b891767c21 { private static $loader; @@ -22,12 +22,12 @@ class ComposerAutoloaderInita5a6e2bb0a11e75425aaca6316dc467d return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInita5a6e2bb0a11e75425aaca6316dc467d', 'loadClassLoader'), true, false); + spl_autoload_register(array('ComposerAutoloaderInit8bda4515f096db9c6abfe2b891767c21', 'loadClassLoader'), true, false); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInita5a6e2bb0a11e75425aaca6316dc467d', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit8bda4515f096db9c6abfe2b891767c21', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit8bda4515f096db9c6abfe2b891767c21::getInitializer($loader)); $loader->register(false); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php old mode 100644 new mode 100755 index b9a0ffa45ff3bebddd289c752dfae191bc625a1d..4548c064d53c7a7dc2aa41410cc2cefc3d9743dd --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d +class ComposerStaticInit8bda4515f096db9c6abfe2b891767c21 { public static $prefixLengthsPsr4 = array ( 'I' => @@ -32,9 +32,9 @@ class ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInita5a6e2bb0a11e75425aaca6316dc467d::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit8bda4515f096db9c6abfe2b891767c21::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit8bda4515f096db9c6abfe2b891767c21::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit8bda4515f096db9c6abfe2b891767c21::$classMap; }, null, ClassLoader::class); } diff --git a/views/css/back.css b/views/css/back.css index 909a6ebc3573434b527379032f4e397e7be44d08..30c73178156589f45780fec5c72d73cb17377d05 100755 --- a/views/css/back.css +++ b/views/css/back.css @@ -82,3 +82,56 @@ div[id^="io6_info_"]{ #statistic_info_container{ font-size: 14px; } + +#generalSettingsForm select { + max-width: 300px; +} + +#generalSettingsForm h4{ + font-weight: 700; +} + +div[id^='io6-container-catalog-']{ + display: flex; + align-items: center; +} + +div[id^='io6-container-catalog-'] label{ + margin: 0px 0px 0px 5px; +} + +div[id^='price-selection-catalog-']{ + padding: 0px 0px 20px 20px; +} + +div[id^='warnings-catalog-'] li{ + margin-top: 10px; +} + +div[id^='warnings-catalog-'] .move-products-container{ + display: flex; +} + +#export-categories-io6 .form-group { + padding: 10px; +} + +#generalSettingsForm .catalogs .catalog-data{ + margin: 0px 10px; +} + +#catalogs-table td { + padding: 10px; +} + +#download-not-io6-product{ + display: flex; + align-items: center; + float: right; +} + +#download-not-io6-product i{ + font-size: 1.2rem; + margin-right: 5px; +} + diff --git a/views/js/ps_connect_io6.js b/views/js/ps_connect_io6.js old mode 100644 new mode 100755 index d8d8ed6ab381a96d48216f6d14b8b7f6bc94a6e1..df9630fec53321a03060c0738308890d5d5d1a02 --- a/views/js/ps_connect_io6.js +++ b/views/js/ps_connect_io6.js @@ -27,6 +27,17 @@ */ $(document).ready(function () { + if ($("input[id^='io6-catalog-'").length > 0){ + $("input[id^='io6-catalog-'").each(function(e){ + var price_select = $(this).prop('id').replace('io6-catalog-', 'io6-price-catalog-'); + var price_select_container = $(this).prop('id').replace('io6-catalog-', 'price-selection-catalog-'); + if (!$(this).is(":checked")){ + $('#'+price_select).prop("disabled", true); + } + }); + } + +}) $(document).on('click', '#product_description_importerone_single_sync', async function(e) { e.preventDefault(); @@ -48,10 +59,9 @@ $(document).ready(function () { complete: function() { } }); - }); + }); - $("#io6-test-api").unbind(); - $("#io6-test-api").on('click', async function(e) { + $(document).on('click', '#io6-test-api', async function(e) { e.preventDefault(); var endPoint = $('#IMPORTERONE6CONNECT_API_ENDPOINT').val(); var token = $('#IMPORTERONE6CONNECT_API_TOKEN').val(); @@ -73,11 +83,128 @@ $(document).ready(function () { $('#api-settings_form .form-wrapper').append('<div class="module_confirmation alert alert-' + (data.response.passed ? data.response.iswarning ? 'warning' : 'success' : 'danger') + '"><h4 style="margin-bottom:0;">'+ data.response.message + '</h4></div>'); }, error: function (error) { - console.log("ERROR " + error.toString()); + console.log("ERROR " + error.toString()); }, complete: function() { } }); - }); + }); + + $(document).on("change","input[id^='io6-catalog-']", function(e) { + var price_select = $(this).prop('id').replace('io6-catalog-', 'io6-price-catalog-'); + var price_select_container = $(this).prop('id').replace('io6-catalog-', 'price-selection-catalog-'); + + if ($(this).is(":checked")){ + $("#"+price_select).prop("disabled", false); + } else { + $("#"+price_select).prop("disabled", true); + $("#"+price_select).prop("value", 0); + } + }); + + + $(document).on("click","div[id^='warnings-catalog-'] .btn-move-products", async function(e) { + e.preventDefault(); + + $(this).attr('href', $(this).attr('href').concat('&newCatalogId=' + e.target.dataset.newCatalogId)); + + await $.ajax({ + method: "post", + async: true, + url: $(this).attr('href'), + success: function (data) { + window.location.href = window.location.href; + }, + error: function (error) { + $('#generalSettingsErrorSection').append('<span class="alert alert-danger' + '">'+ error.status + ' ' + error.responseText + '</span>'); + }, + }); + + + }) + + $(document).on("change",".move-products-container select", function(e) { + if (e.target.selectedOptions[0].value != 0){ + $(this).siblings('.btn-move-products')[0].dataset.newCatalogId = e.target.selectedOptions[0].value; + $(this).siblings('.btn-move-products')[0].classList.remove('disabled'); + } else { + $(this).siblings('.btn-move-products')[0].classList.add('disabled'); + } + }) + + $(document).on("click","div[id^='warnings-catalog-'] .btn-disable-products", async function(e) { + e.preventDefault(); + + await $.ajax({ + method: "post", + async: true, + url: $(this).attr('href'), + success: function (data) { + window.location.href = window.location.href; + }, + error: function (error) { + $('#generalSettingsErrorSection').append('<span class="alert alert-danger' + '">'+ error.status + ' ' + error.responseText + '</span>'); + }, + }); + + }) + + $(document).on("click","#download-not-io6-product", async function(e) { + e.preventDefault(); + + await $.ajax({ + method: "post", + async: true, + url: $(this).attr('href'), + success: function (data) { + var downloadLink = document.createElement("a"); + downloadLink.download = "product_not_in_io6_tables.csv"; + var fileData = ['\ufeff'+data]; + var blobObject = new Blob(fileData,{ + type: "text/csv;charset=utf-8;" + }); + + var url = URL.createObjectURL(blobObject); + downloadLink.href = url; + + document.body.appendChild(downloadLink); + downloadLink.click(); + document.body.removeChild(downloadLink); + }, + error: function (error) { + $('#generalSettingsErrorSection').append('<span class="alert alert-danger' + '">'+ error.status + ' ' + error.responseText + '</span>'); + }, + }); + + }) + + $(document).on("click","#io6-export-categories", async function(e) { + e.preventDefault(); + + await $.ajax({ + method: "post", + async: true, + url: $(this).attr('href'), + success: function (data) { + var downloadLink = document.createElement("a"); + downloadLink.download = "prestashop_categories_tree.csv"; + var fileData = ['\ufeff'+data]; + var blobObject = new Blob(fileData,{ + type: "text/csv;charset=utf-8;" + }); + + var url = URL.createObjectURL(blobObject); + downloadLink.href = url; + + document.body.appendChild(downloadLink); + downloadLink.click(); + document.body.removeChild(downloadLink); + }, + error: function (error) { + $('#generalSettingsErrorSection').append('<span class="alert alert-danger' + '">'+ error.status + ' ' + error.responseText + '</span>'); + }, + }); + + }) + -}); diff --git a/views/templates/admin/configure_actions.tpl b/views/templates/admin/configure_actions.tpl index c82e126385dab872f9142faa9b43222232f7c9ef..62e0040b2c9169b59ce7c8f532081ec98468c13c 100644 --- a/views/templates/admin/configure_actions.tpl +++ b/views/templates/admin/configure_actions.tpl @@ -25,89 +25,190 @@ <script type="text/javascript"> -$(document).ready(function () { $cancel = false; - - $("#io6-exec-sync").unbind(); - $("#io6-exec-cancel-sync").on('click', function() { + + $(document).on('click', '#io6-exec-cancel-sync', function() { $cancel = true; $('#io6-exec-sync-info').html("Annullamento in corso..."); }); - - - $("#io6-exec-sync").unbind(); - $("#io6-exec-sync").on('click', async function() { - $cancel = false; - $(this).prop('disabled', true); - $("#io6-exec-cancel-sync").removeClass("display-none"); - var resumeSync = $("#io6-resume-sync").is(':checked') ? 1 : 0; - var fastSync = $("#io6-fast-sync").is(':checked') ? 1 : 0; - - var currentPage = 1; - var totalPages = 1; - - - $('#io6-exec-sync-info').html('Inizio sincronizzazione...'); - $('#io6-exec-sync-info').show(); - $('#io6-exec-sync-status').hide(); - $('#io6-exec-sync-status').html(''); + $(document).on('click', '#io6-exclude-products',async function(e){ + var href = $(this).attr('href'); + await $.ajax({ + method: "get", + async: true, + dataType: 'json', + url: href, + + success: function (data) { + if (data.success){ + $('#io6-exclude-products').prop("disabled", true); + $('#io6-include-products').prop("disabled", true); + $("#io6-exec-sync").prop("disabled", false); + } + $('#io6-exclude-include-info').html('<b>Procedura completata: '+ data.message +'</b>'); - - while (currentPage <= totalPages && !$cancel) { - await $.ajax({ + }, + error: function (error) { + $('#io6-exclude-include-info').html('<div class="module_confirmation alert alert-danger' + '"><h4 style="margin-bottom:0;">'+ error.message +'</h4></div>'); + }, + complete: function() { + } + }); + }); + + $(document).on('click', '#io6-include-products',async function(e){ + var href = $(this).attr('href'); + await $.ajax({ method: "get", async: true, dataType: 'json', //url: window.location.protocol + '//' + window.location.hostname + '/wp-admin/admin-ajax.php?action=io6-sync&page=' + currentPage, - url: '{$executeUrl}&page=' + currentPage + '&fast=' + fastSync + '&resume=' + resumeSync, - + url: href, + success: function (data) { - totalPages = data.pages; - - $('#io6-exec-sync-info').html('Totale prodotti: ' + data.elementsFounds + ". Pagine: " + currentPage + " di " + data.pages); - $('#io6-exec-sync-status').show(); - data.products.forEach(element => { - $('#io6-exec-sync-status').prepend("<p class='status-message " + element.status + "' >Prodotto: " + element.io6_id + " - EAN: " + element.ean + " - PARTNUMBER: " + element.partnumber + " - Status: " + element.status_message + "</p>"); - }); + if (data.success){ + $('#io6-exclude-products').prop("disabled", true); + $('#io6-include-products').prop("disabled", true); + $("#io6-exec-sync").prop("disabled", false); + } + $('#io6-exclude-include-info').html('<b>Procedura completata: '+ data.message +'</b>'); }, error: function (error) { - $('#io6-exec-sync-info').html('<div class="module_confirmation alert alert-danger' + '"><h4 style="margin-bottom:0;">'+ error.status + ' ' + error.responseText + '. Ultima pagina importata: '+ currentPage +'</h4></div>'); - //$('#io6-exec-sync-info').html(error.statusText + "<br/>" + error.status); + $('#io6-exclude-include-info').html('<div class="module_confirmation alert alert-danger' + '"><h4 style="margin-bottom:0;">'+ error.message +'</h4></div>'); }, complete: function() { } }); - currentPage++; + }); + + + $(document).on('click', "#io6-exec-sync",async function(e){ + $cancel = false; + $(this).prop('disabled', true); + $("#io6-exec-cancel-sync").removeClass("display-none"); + var resumeSync = $("#io6-resume-sync").is(':checked') ? 1 : 0; + var fastSync = $("#io6-fast-sync").is(':checked') ? 1 : 0; + var catalogsSelected = $("input[id^='io6-catalog-'"); + + $('#io6-exec-sync-info').html('Inizio sincronizzazione...'); + $('#io6-exec-sync-info').show(); + + $('#io6-exec-sync-status').hide(); + $('#io6-exec-sync-status').html(''); + + for (i = 0; i < catalogsSelected.length; i++) { + if(catalogsSelected[i].checked){ + var currentPage = 1; + var totalPages = 1; + + while (currentPage <= totalPages && !$cancel) { + await $.ajax({ + method: "get", + async: true, + dataType: 'json', + //url: window.location.protocol + '//' + window.location.hostname + '/wp-admin/admin-ajax.php?action=io6-sync&page=' + currentPage, + url: '{$executeUrl}&catalogId='+catalogsSelected[i].value+'&page=' + currentPage + '&fast=' + fastSync + '&resume=' + resumeSync, + + success: function (data) { + totalPages = data.pages; + + $('#io6-exec-sync-info').html('Catalogo "'+catalogsSelected[i].dataset.catalogName +'", Totale prodotti: ' + data.elementsFounds + ". Pagine: " + currentPage + " di " + data.pages); + $('#io6-exec-sync-status').show(); + + if(currentPage == 1){ + $('#io6-exec-sync-status').prepend("<p class='status-message'><b>INIZIO IMPORTAZIONE CATALOGO: "+catalogsSelected[i].dataset.catalogName+"</b></p>") + } + + data.products.forEach(element => { + $('#io6-exec-sync-status').prepend("<p class='status-message " + element.status + "' >Catalogo: "+ element.catalog_id +" - ID Prodotto IO6: " + element.io6_id + " - ID Prodotto Prestashop: "+ element.ps_product_id +" - EAN: " + element.ean + " - PARTNUMBER: " + element.partnumber + " - Status: " + element.status_message + "</p>"); + }); + + if(currentPage == totalPages){ + $('#io6-exec-sync-status').prepend("<p class='status-message'><b>FINE IMPORTAZIONE CATALOGO: "+catalogsSelected[i].dataset.catalogName+"</b></p>") + $('#io6-exec-sync-status').prepend("<span><b>-------------------------------------------------------</b></span>") + } + }, + error: function (error) { + $('#io6-exec-sync-info').html('<div class="module_confirmation alert alert-danger' + '"><h4 style="margin-bottom:0;">'+ error.status + ' ' + error.responseText + '. Ultima pagina importata: '+ currentPage +' di '+ totalPages +'</h4></div>'); + //$('#io6-exec-sync-info').html(error.statusText + "<br/>" + error.status); + }, + complete: function() { + } + }); + currentPage++; + } + } } + if($cancel) $('#io6-exec-sync-info').append('<br/>Sincronizzazione interrotta.'); else - $('#io6-exec-sync-info').append('<br/>Sincronizzazione terminata.'); + $('#io6-exec-sync-info').append('<br/>Sincronizzazione terminata.'); $(this).prop('disabled', false); $("#io6-exec-cancel-sync").addClass("display-none"); - - }); - }); + + }); + </script> <div class="panel"> <h3><i class="icon icon-cogs"></i> {l s='Actions' mod='importerone6connect'}</h3> <p>{l s='Avvio della procedura di sincronizzazione del catalogo da ImporterONE Cloud' mod='importerone6connect'}</p> - + <div class="form-group"> + {if $productNotInIo6Tables > 0} + <div class="alert alert-warning"> + <h4><b>{$productNotInIo6Tables} prodotti presenti nel catalogo risultano non associati ad ImporterONE</b></h4> + <strong>N.B. queste azioni sono irreversibili, si consiglia di effettuare un backup del database prima di procedere</strong> + <p> + <ul> + <li> + Se desideri che questi prodotti siano ignorati, dovrai escluderli dalla sincronizzazione (Questi prodotti non saranno gestiti da ImporterONE). + </li> + <li> + Se desideri che tutti i prodotti già presenti nel sito vengano associati ad ImporterONE, dovrai includerli nella sincronizzazione (Assume rilevanza la scelta inserita nella configurazione in Product Settings --> Utilizzare i fornitori IO6). + </li> + </ul> + </p> + <p>Per maggiori informazioni consultare la <a href="https://www.imprimis.it/importerone/help/plugin-prestashop-1-7/#prodotti-non-associati">guida.</a></p> + <div class="row" style="margin-top: 10px;"> + <div class="col-md-9"> + <button class="btn btn-secondary" id="io6-exclude-products" + href="{url entity='module' name='ps_connect_io6' controller='actions' params = ['action' => 'excludeProducts']}"> + {l s='Escludi i prodotti dalla sincronizzazione' mod='importerone6connect'} + </button> + <button class="btn btn-secondary" id="io6-include-products" + href="{url entity='module' name='ps_connect_io6' controller='actions' params = ['action' => 'includeProducts']}"> + {l s='Includi i prodotti nella sincronizzazione' mod='importerone6connect'} + </button> + <br> + <span id="io6-exclude-include-info" class="text-center"></span> + </div> + <div class="col-md-3"> + <button class="btn btn-secondary" id="download-not-io6-product" + href="{url entity='module' name='ps_connect_io6' controller='actions' params = ['action' => 'downloadNotIO6Catalog']}"> + <i class="icon icon-download"></i><span>{l s='Scarica prodotti' mod='importerone6connect'}</span> + </button> + </div> + </div> + </div> + {/if} <br/> - <label> - <input type="checkbox" class="" name="io6-resume-sync" id="io6-resume-sync" value="1"/> - {l s='Riprendere sincronizzazione precedente' mod='importerone6connect'} - <br /> - <small>({l s='Se la precedente sincronizzazione non è stata completata, i prodotti già importati verranno ignorati durante questa sincronizzazione' mod='importerone6connect'})</small> - </label> + {if $syncResume} + <label> + <input type="checkbox" class="" name="io6-resume-sync" id="io6-resume-sync" value="1"/> + {l s='Riprendere sincronizzazione precedente' mod='importerone6connect'} + <br /> + <small>({l s='Presente una sincronizzazione avviata ma non completata. Con questa configurazione i prodotti già importati verranno ignorati. Data ultimo prodotto importato: ' mod='importerone6connect'} {$lastProductSyncDate}) </small> + + </label> <br/> + {/if} <label> <input type="checkbox" class="" name="io6-fast-sync" id="io6-fast-sync" value="1"/> {l s='Esegui sincronizzazione veloce' mod='importerone6connect'} @@ -115,29 +216,16 @@ $(document).ready(function () { <small>({l s='Verranno aggiornati solamente prezzo e quantità dei prodotti esistenti, i prodotti nuovi verranno scartati' mod='importerone6connect'})</small> </label> <br/> - <button class="btn btn-primary" id="io6-exec-sync"> + <button class="btn btn-primary" id="io6-exec-sync" {if $productNotInIo6Tables} disabled {/if}> {l s='Aggiorna catalogo da ImporterONE ...' mod='importerone6connect'} - </button> + </button> <button class="btn btn-cancel display-none" id="io6-exec-cancel-sync" > {l s='Annulla' mod='importerone6connect'} - </button> + </button> </div> <div class="wrap"> <div id="io6-exec-sync-info" class="sync-info"></div> - <div id="io6-exec-sync-status" class="sync-status"></div> - </div> - <div class="form-group"> - <br/> - <strong>{l s='Comando CRON sincronizzazione normale' mod='importerone6connect'}</strong> - <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommand}</div> - <p class="help-block">{l s='Puoi configurare un CRON per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico del catalogo' mod='importerone6connect'}</p> - <br/> - <strong>{l s='Comando CRON sincronizzazione veloce' mod='importerone6connect'}</strong> - <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommandFast}</div> - <p class="help-block">{l s='Puoi configurare un CRON Fast per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico del catalogo, verranno aggiornati solamente prezzo e quantità dei prodotti esistenti, i prodotti nuovi verranno scartati' mod='importerone6connect'}</p> - <strong>{l s='Comando CRON download immagini' mod='importerone6connect'}</strong> - <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommandDownloadImages}</div> - <p class="help-block">{l s='Puoi configurare un CRON per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico delle immagini del catalogo.' mod='importerone6connect'}</p> + <div id="io6-exec-sync-status" class="sync-status"></div> </div> </div> @@ -156,4 +244,4 @@ $(document).ready(function () { </div> </div> </div> -</div> *} \ No newline at end of file +</div> *} diff --git a/views/templates/admin/configure_general.tpl b/views/templates/admin/configure_general.tpl new file mode 100755 index 0000000000000000000000000000000000000000..1ffbe996dafe40d614a1fec164426bb68b611daa --- /dev/null +++ b/views/templates/admin/configure_general.tpl @@ -0,0 +1,110 @@ +{* +* 2007-2021 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA <contact@prestashop.com> +* @copyright 2007-2021 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + +<form id="generalSettingsForm" name="generalSettingsForm" action="{Context::getContext()->link->getAdminLink('AdminModules', true, null, array('configure' => $moduleName))}" method="post"> + <div class="panel"> + <h3><i class="icon process-icon-stats"></i> {l s='Impostazioni Generali' mod='importerone6connect'}</h3> + <div class="row"> + <div class="col-md-6"> + <div id="general-settings"> + <h4>{l s='Seleziona cataloghi da importare' mod='importerone6connect'}</h4> + <table id="catalogs-table"> + {foreach from=$io6Catalogs item=catalog key=key name=name} + <tr id="io6-container-catalog-{$catalog->id}" class="catalog-data"> + <td> + <input type="checkbox" id="io6-catalog-{$catalog->id}" name="IMPORTERONE6CONNECT_CATALOGS[{$catalog->id}]" value="{$catalog->id}" data-catalog-name="{$catalog->name}" {if $catalog->selected}checked{/if}> + <input type="hidden" id="io6-catalog-{$catalog->id}-name" name="IMPORTERONE6CONNECT_CATALOGS[{$catalog->id}][catalog_name]" value="{$catalog->name}"> + <label for="io6-catalog-{$catalog->id}">{$catalog->name}</label> + </td> + <td id="price-selection-catalog-{$catalog->id}"> + {if !empty($catalog->priceLists)} + <span>{l s='Seleziona il listino da importare:' mod='importerone6connect'}</span> + <select id="io6-price-catalog-{$catalog->id}" name="IMPORTERONE6CONNECT_CATALOGS[{$catalog->id}][price_list_id]"> + {foreach from=$catalog->priceLists item=priceList} + <option value="{$priceList->id}" {if $priceList->selected}selected{/if}>{$priceList->name}</option> + {/foreach} + </select> + {/if} + </td> + </tr> + {/foreach} + </table> + </div> + {if $productsInDisabledCatalogs|count > 0} + <div id="catalog-product-warnings" class="alert alert-warning"> + {foreach from=$productsInDisabledCatalogs item=disabledCatalog key=catalogId} + {if $disabledCatalog['products_count'] > 0} + <div id="warnings-catalog-{$catalogId}"> + <h4>{l s='Problematica con catalogo ' mod='importerone6connect'} {if !empty($disabledCatalog['catalog_name'])}{$disabledCatalog['catalog_name']}{else}{$catalogId} {l s='(Catalogo non più presente in ImporterONE)' mod='importerone6connect'}{/if}</h4> + <span>{l s='Nel database di Prestashop sono presenti %s prodotti assegnati ad un catalogo non abilitato. Scegli l\'azione da effettuare:' mod='importerone6connect' sprintf=[$disabledCatalog['products_count']]}</span> + <div> + <ul> + <li>{l s='Disattiva i prodotti interessati' mod='importerone6connect'} <a class="btn btn-primary btn-sm btn-disable-products" href="{Context::getContext()->link->getModuleLink('ps_connect_io6', 'actions', array('action' => "disableProducts", 'catalogId' => $catalogId))}">{l s='Disattiva' mod='importerone6connect'}</a></li> + <li>{l s='Sposta i prodotti in un nuovo catalogo' mod='importerone6connect'} + <div class="move-products-container"> + <select> + {foreach from=$io6Catalogs item=catalog name="newCatalogOptions"} + {if $smarty.foreach.newCatalogOptions.first} + <option value="0">{l s='Selezionare un catalogo' mod='importerone6connect'}</option> + {/if} + {if $catalog->id != $catalogId} + <option value="{$catalog->id}">{$catalog->name}</option> + {/if} + {/foreach} + </select> + <a data-new-catalog-id="" class="btn btn-primary btn-sm btn-move-products disabled" href="{Context::getContext()->link->getModuleLink('ps_connect_io6', 'actions', array('action' => "moveProducts", 'oldCatalogId' => $catalogId))}">{l s='Sposta' mod='importerone6connect'}</a> + </div> + </li> + </ul> + </div> + </div> + {/if} + {/foreach} + </div> + {/if} + + <div id="generalSettingsErrorSection"></div> + </div> + <div id="export-categories-io6" class="col-md-6"> + <h4>{l s='Esporta categorie per mapping' mod='importerone6connect'}</h4> + <p> + Scarica l'albero categorie in formato CSV per popolare le categorie di un catalogo personale in ImporterONE.<br/> + Verranno estratte solo le categorie attive. + </p> + <div class="form-group p-2"> + <button class="btn btn-secondary" id="io6-export-categories" href="{$exportCategoriesUrl}">Esporta categorie</button> + + </div> + </div> + </div> + + <div class="panel-footer"> + <button form="generalSettingsForm" type="submit" id="submitImporterone6connectModule_GeneralSettings" name="submitImporterone6connectModule_GeneralSettings" value="1" class="btn btn-default pull-right"> + <i class="process-icon-save"></i> Salva + </button> + </div> + </div> +</form> + diff --git a/views/templates/admin/cron_section.tpl b/views/templates/admin/cron_section.tpl new file mode 100755 index 0000000000000000000000000000000000000000..9b8be80ed43e8fbbc6d8e8441421da56ba1f21ef --- /dev/null +++ b/views/templates/admin/cron_section.tpl @@ -0,0 +1,53 @@ +{* +* 2007-2021 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA <contact@prestashop.com> +* @copyright 2007-2021 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} + +<div class="panel"> + <h3><i class="icon process-icon-cogs"></i> {l s='Cron' mod='importerone6connect'}</h3> + <h4><strong>Verificare con il proprio provider che sia possibile configurare il cron come suggerito.</strong></h4> + <br/> + <div class="form-group"> + <strong>{l s='Comando CRON sincronizzazione normale' mod='importerone6connect'}</strong> + <br/> + {foreach from=$cronCommands item=cronCommand key=catalog_name name=name} + <span>{l s='CRON catalogo: ' mod='importerone6connect'} {$catalog_name}</span> + <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommand}</div> + <p class="help-block">{l s='Puoi configurare un CRON per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico del catalogo' mod='importerone6connect'}</p> + <br/> + {/foreach} + <br/> + <strong>{l s='Comando CRON sincronizzazione veloce' mod='importerone6connect'}</strong> + <br/> + {foreach from=$cronCommandsFast item=cronCommandFast key=catalog_name name=name} + <span>{l s='CRON catalogo: ' mod='importerone6connect'} {$catalog_name}</span> + <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommandFast}</div> + <p class="help-block">{l s='Puoi configurare un CRON Fast per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico del catalogo, verranno aggiornati solamente prezzo e quantità dei prodotti esistenti, i prodotti nuovi verranno scartati' mod='importerone6connect'}</p> + <br/> + {/foreach} + <br/> + <strong>{l s='Comando CRON download immagini' mod='importerone6connect'}</strong> + <div class="" style="border: none;border-left: 3px solid #fcc94f;padding: 10px;position: relative;background-color: #fff3d7;color: #d2a63c;">{$cronCommandDownloadImages}</div> + <p class="help-block">{l s='Puoi configurare un CRON per l\'esecuzione del comando PHP con i parametri sopra indicati per eseguire l\'aggiornamento automatico delle immagini del catalogo.' mod='importerone6connect'}</p> + </div> +</div> \ No newline at end of file diff --git a/views/templates/admin/displayAdminProductsExtra.tpl b/views/templates/admin/displayAdminProductsExtra.tpl index d5067533cadf77c82f64a6cd6a16ea7eca72a432..991d4eeff8b936ff77007e5a2f3780c8e0c793da 100644 --- a/views/templates/admin/displayAdminProductsExtra.tpl +++ b/views/templates/admin/displayAdminProductsExtra.tpl @@ -36,6 +36,13 @@ </div> </div> <div class="col-lg-12"> + <div class="row form-group"> + <div class="col-md-4"> + <div class="checkbox"> + <label>{l s='ID Catalogo ImporterONE' mod='importerone6connect'} <span>{$importerone6connect_catalog_id}</span></label> + </div> + </div> + </div> <div class="row form-group"> <div class="col-md-4"> <div class="checkbox"> diff --git a/views/templates/admin/displayAdminProductsMainStepLeftColumnMiddle.tpl b/views/templates/admin/displayAdminProductsMainStepLeftColumnMiddle.tpl old mode 100644 new mode 100755 index 6759b3041b7c6a8a36ffa14c0747b6edcbe4941a..4e278efd03d5e47c0b3e682fd9247c6f923bb64a --- a/views/templates/admin/displayAdminProductsMainStepLeftColumnMiddle.tpl +++ b/views/templates/admin/displayAdminProductsMainStepLeftColumnMiddle.tpl @@ -32,21 +32,19 @@ {if $importerone6connect_sync_status == 1} <span class="p-1">{l s='Sincronizzato il: [1]sync_date[/1]' mod='importerone6connect' sprintf=['sync_date' => $importerone6connect_sync_date] tags=['<strong>']}</span> {else} - <span class="bg-warning p-1"> - {if !empty($importerone6connect_sync_message)} - {$importerone6connect_sync_message} + {if !empty($importerone6connect_sync_message) && !empty($importerone6connect_sync_date)} + <span class="p-1">{l s='Sincronizzato il: [1]sync_date[/1] - sync_message' mod='importerone6connect' sprintf=['sync_date' => $importerone6connect_sync_date, 'sync_message' => $importerone6connect_sync_message] tags=['<strong>']}</span> {else} - {l s='Non ancora sincronizzato' mod='importerone6connect'} + <span class="bg-warning p-1">{l s='Non ancora sincronizzato' mod='importerone6connect'}</span> {/if} - </span> {/if} {else} <span class="bg-warning p-1">{l s='Prodotto non sincronizzato con ImporterONE.' mod='importerone6connect'}</span> {/if} - {if !empty($importerone6connect_io6_id_product)} + {if !empty($importerone6connect_io6_id_product) && $importerone6connect_catalog_id > 0} <div> <a id="io6-single-prod-sync" class="btn btn-primary" - href="{url entity='sf' route='admin_io6_productsync' sf-params=['io6_id_product' => $importerone6connect_io6_id_product]}"> + href="{url entity='sf' route='admin_io6_productsync' sf-params=['io6_id_product' => $importerone6connect_io6_id_product, 'catalogId' => $importerone6connect_catalog_id]}"> {l s='Sincronizza con ImporterONE' mod='importerone6connect'}</a> </div> {/if} diff --git a/views/templates/admin/statistic_info.tpl b/views/templates/admin/statistic_info.tpl index 4a32d993528481158a607866f458366d1d3516eb..7f9a6427776b73ee249aaf03ba7892f0b3bfffd3 100755 --- a/views/templates/admin/statistic_info.tpl +++ b/views/templates/admin/statistic_info.tpl @@ -122,9 +122,8 @@ </div> <script type="text/javascript"> - -$(document).ready(function () { - $("a[id^=btnShow_]").on('click', async function(e) { + + $(document).on('click', 'a[id^=btnShow_]', async function(e) { e.preventDefault(); var info_container = $(this).prop('id').replace('btnShow_', 'io6_info_'); $('#'+info_container).html(''); @@ -149,8 +148,7 @@ $(document).ready(function () { }); }); - $("button[id^=io6_downloadCSV_]").on('click', async function(e) { - debugger; + $(document).on('click', 'button[id^=io6_downloadCSV_]', async function(e) { e.preventDefault(); var download_info_container = $(this).prop('id').replace('io6_downloadCSV_', 'io6_download_info_'); @@ -159,7 +157,6 @@ $(document).ready(function () { async: true, url: $(this).attr('href'), success: function (data) { - debugger; var downloadLink = document.createElement("a"); var fileData = ['\ufeff'+data]; var blobObject = new Blob(fileData,{ @@ -180,6 +177,5 @@ $(document).ready(function () { }, }); }); - }); </script> diff --git a/views/templates/admin/statistic_section.tpl b/views/templates/admin/statistic_section.tpl index 4e89e9d701650bb42ba733541d2b612846cfe615..969080c7ecbfee6932e8e6a689d6672e00e17c77 100755 --- a/views/templates/admin/statistic_section.tpl +++ b/views/templates/admin/statistic_section.tpl @@ -31,8 +31,7 @@ <script type="text/javascript"> -$(document).ready(function () { - $("#show_statistic_info").on('click', async function(e) { + $(document).on('click', '#show_statistic_info', async function(e) { e.preventDefault(); await $.ajax({ @@ -50,6 +49,5 @@ $(document).ready(function () { }, }); }); - }); </script> \ No newline at end of file