public function hookHeader($params)
 {
     $shop_id = $this->getShopId();
     $buttons_code = $this->client->getButtonsCode();
     if (Configuration::get('ADDSHOPPERS_OPENGRAPH') == '1') {
         $this->context->smarty->assign('buttons_opengraph', $buttons_code['buttons']['open-graph']);
     }
     if (Configuration::get('ADDSHOPPERS_BUTTONS') == '1') {
         $this->context->smarty->assign('buttons_social', $buttons_code['buttons']['button2']);
     }
     $id_lang = (int) Tools::getValue('id_lang', (int) Configuration::get('PS_LANG_DEFAULT'));
     $this->context->smarty->assign(array('shop_id' => Tools::safeOutput($shop_id), 'default_account' => $shop_id == $this->client->getDefaultShopId(), 'social' => Tools::safeOutput(Configuration::get('ADDSHOPPERS_BUTTONS')), 'opengraph' => Tools::safeOutput(Configuration::get('ADDSHOPPERS_OPENGRAPH')), 'actual_url' => Tools::safeOutput($this->_getCurrentUrl()), 'absolute_base_url' => Tools::safeOutput($this->_getAbsoluteBaseUrl()), 'id_lang' => (int) $id_lang));
     if (Tools::isSubmit('id_product')) {
         $product = new Product((int) Tools::getValue('id_product'));
         if (Validate::isLoadedObject($product)) {
             $currency = new Currency((int) $this->context->cookie->id_currency);
             $this->context->smarty->assign(array('id_product' => (int) $product->id, 'stock' => isset($product->available_now) ? Tools::safeOutput(AddshoppersClient::WIDGET_STOCK_IN_STOCK) : Tools::safeOutput(AddshoppersClient::WIDGET_STOCK_OUT_OF_STOCK), 'price' => Tools::safeOutput($currency->sign) . number_format((double) $product->getPrice(), 2), 'product_name' => Tools::safeOutput($product->name[$id_lang]), 'product_description' => Tools::safeOutput($product->description[$id_lang]), 'is_product_page' => true));
             $quantity = (int) StockAvailable::getQuantityAvailableByProduct((int) $product->id);
             if ($quantity > 0) {
                 $this->context->smarty->assign('instock', (int) $quantity);
             }
             $images = Image::getImages((int) $id_lang, (int) $product->id);
             if (is_array($images) && isset($images[0])) {
                 $this->context->smarty->assign('id_image', (int) $images[0]['id_image']);
             }
         } else {
             $this->context->smarty->assign('is_product_page', false);
         }
     } else {
         $this->context->smarty->assign('is_product_page', false);
     }
     return $this->display(__FILE__, 'header.tpl');
 }
 /**
  * This will update a Pack quantity and will decrease the quantity of containing Products if needed.
  *
  * @param Product $product A product pack object to update its quantity
  * @param StockAvailable $stock_available the stock of the product to fix with correct quantity
  * @param integer $delta_quantity The movement of the stock (negative for a decrease)
  * @param integer|null $id_shop Opional shop ID
  */
 public function updatePackQuantity($product, $stock_available, $delta_quantity, $id_shop = null)
 {
     $configuration = Adapter_ServiceLocator::get('Core_Business_ConfigurationInterface');
     if ($product->pack_stock_type == 1 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && $configuration->get('PS_PACK_STOCK_TYPE') > 0) {
         $packItemsManager = Adapter_ServiceLocator::get('Adapter_PackItemsManager');
         $products_pack = $packItemsManager->getPackItems($product);
         $stockAvailable = new Core_Business_Stock_StockManager();
         $stockManager = Adapter_ServiceLocator::get('Adapter_StockManager');
         $cacheManager = Adapter_ServiceLocator::get('Adapter_CacheManager');
         foreach ($products_pack as $product_pack) {
             $productStockAvailable = $stockManager->getStockAvailableByProduct($product_pack, $product_pack->id_pack_product_attribute, $id_shop);
             $productStockAvailable->quantity = $productStockAvailable->quantity + $delta_quantity * $product_pack->pack_quantity;
             $productStockAvailable->update();
             $cacheManager->clean('StockAvailable::getQuantityAvailableByProduct_' . (int) $product_pack->id . '*');
         }
     }
     $stock_available->quantity = $stock_available->quantity + $delta_quantity;
     if ($product->pack_stock_type == 0 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && ($configuration->get('PS_PACK_STOCK_TYPE') == 0 || $configuration->get('PS_PACK_STOCK_TYPE') == 2)) {
         $stock_available->update();
     }
 }
Example #3
0
 public function delete()
 {
     if (!parent::delete()) {
         return false;
     }
     // Removes the product from StockAvailable, for the current shop
     StockAvailable::removeProductFromStockAvailable((int) $this->id_product, (int) $this->id);
     if (!$this->hasMultishopEntries() && !$this->deleteAssociations()) {
         return false;
     }
     return true;
 }
 public function add($autodate = true, $null_values = false)
 {
     if (!parent::add($autodate, $null_values)) {
         return false;
     }
     $product = new Product((int) $this->id_product);
     if ($product->getType() == Product::PTYPE_VIRTUAL) {
         StockAvailable::setProductOutOfStock((int) $this->id_product, 1, null, (int) $this->id);
     } else {
         StockAvailable::setProductOutOfStock((int) $this->id_product, StockAvailable::outOfStock((int) $this->id_product), null, $this->id);
     }
     SpecificPriceRule::applyAllRules(array((int) $this->id_product));
     return true;
 }
Example #5
0
 protected function checkProductStock($product, $id_order_state)
 {
     if ($id_order_state != Configuration::get('PS_OS_CANCELED') && $id_order_state != Configuration::get('PS_OS_ERROR')) {
         $update_quantity = true;
         $qty = PP::resolveQty($product['cart_quantity'], $product['cart_quantity_fractional']);
         if (!StockAvailable::dependsOnStock($product['id_product'])) {
             $update_quantity = StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -$qty);
         }
         if ($update_quantity) {
             $product['stock_quantity'] -= $qty;
         }
         if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
             $this->outOfStock = true;
         }
         Product::updateDefaultAttribute($product['id_product']);
     }
 }
 /**
  * Check the order status
  * @param array $product
  * @param int $id_order_state
  */
 protected function checkProductStock($product, $id_order_state)
 {
     $this->outOfStock = false;
     return;
     //TODO
     if ($id_order_state != Configuration::get('PS_OS_CANCELED') && $id_order_state != Configuration::get('PS_OS_ERROR')) {
         $update_quantity = false;
         if (!StockAvailable::dependsOnStock($product['id_product'])) {
             $update_quantity = StockAvailable::updateQuantity($product['id_product'], $product['id_product_attribute'], -(int) $product['cart_quantity']);
         }
         if ($update_quantity) {
             $product['stock_quantity'] -= $product['cart_quantity'];
         }
         if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
             $this->outOfStock = true;
         }
         Product::updateDefaultAttribute($product['id_product']);
     }
 }
 public function processGenerate()
 {
     if (!is_array(Tools::getValue('options'))) {
         $this->errors[] = Tools::displayError('Please select at least one attribute.');
     } else {
         $tab = array_values(Tools::getValue('options'));
         if (count($tab) && Validate::isLoadedObject($this->product)) {
             AdminAttributeGeneratorController::setAttributesImpacts($this->product->id, $tab);
             $this->combinations = array_values(AdminAttributeGeneratorController::createCombinations($tab));
             $values = array_values(array_map(array($this, 'addAttribute'), $this->combinations));
             // @since 1.5.0
             if ($this->product->depends_on_stock == 0) {
                 $attributes = Product::getProductAttributesIds($this->product->id, true);
                 foreach ($attributes as $attribute) {
                     StockAvailable::removeProductFromStockAvailable($this->product->id, $attribute['id_product_attribute'], Context::getContext()->shop);
                 }
             }
             SpecificPriceRule::disableAnyApplication();
             $this->product->deleteProductAttributes();
             $this->product->generateMultipleCombinations($values, $this->combinations);
             // @since 1.5.0
             if ($this->product->depends_on_stock == 0) {
                 $attributes = Product::getProductAttributesIds($this->product->id, true);
                 $quantity = str_replace(',', '.', Tools::getValue('quantity'));
                 foreach ($attributes as $attribute) {
                     StockAvailable::setQuantity($this->product->id, $attribute['id_product_attribute'], $quantity);
                 }
             } else {
                 StockAvailable::synchronize($this->product->id);
             }
             SpecificPriceRule::enableAnyApplication();
             SpecificPriceRule::applyAllRules(array((int) $this->product->id));
             Tools::redirectAdmin($this->context->link->getAdminLink('AdminProducts') . '&id_product=' . (int) Tools::getValue('id_product') . '&updateproduct&key_tab=Combinations&conf=4');
         } else {
             $this->errors[] = Tools::displayError('Unable to initialize these parameters. A combination is missing or an object cannot be loaded.');
         }
     }
 }
Example #8
0
 public function resetStockAvailable()
 {
     $products = WarehouseProductLocation::getProducts((int) $this->id);
     foreach ($products as $product) {
         StockAvailable::synchronize((int) $product['id_product']);
     }
 }
Example #9
0
 public function createEntityStockAvailable($identifier, array $data, array $data_lang)
 {
     $stock_available = new StockAvailable();
     $stock_available->updateQuantity($data['id_product'], $data['id_product_attribute'], $data['quantity'], $data['id_shop']);
 }
 private function _checkProducts($productsNode)
 {
     $available = true;
     foreach ($productsNode->Product as $product) {
         if (strpos($product->SKU, '_') !== false) {
             $skus = explode('_', $product->SKU);
             $quantity = StockAvailable::getQuantityAvailableByProduct((int) $skus[0], (int) $skus[1]);
             if ($quantity - $product->Quantity < 0) {
                 StockAvailable::updateQuantity((int) $skus[0], (int) $skus[1], (int) $product->Quantity);
             }
         } else {
             $quantity = StockAvailable::getQuantityAvailableByProduct((int) $product->SKU);
             if ($quantity - $product->Quantity < 0) {
                 StockAvailable::updateQuantity((int) $skus[0], 0, (int) $product->Quantity);
             }
         }
     }
     return $available;
 }
 /**
  * AdminController::postProcess() override
  * @see AdminController::postProcess()
  */
 public function postProcess()
 {
     parent::postProcess();
     // Checks access
     if (Tools::isSubmit('addStock') && !($this->tabAccess['add'] === '1')) {
         $this->errors[] = Tools::displayError('You do not have the required permission to add stock.');
     }
     if (Tools::isSubmit('removeStock') && !($this->tabAccess['delete'] === '1')) {
         $this->errors[] = Tools::displayError('You do not have the required permission to delete stock');
     }
     if (Tools::isSubmit('transferStock') && !($this->tabAccess['edit'] === '1')) {
         $this->errors[] = Tools::displayError('You do not have the required permission to transfer stock.');
     }
     if (count($this->errors)) {
         return;
     }
     // Global checks when add / remove / transfer product
     if ((Tools::isSubmit('addstock') || Tools::isSubmit('removestock') || Tools::isSubmit('transferstock')) && Tools::isSubmit('is_post')) {
         // get product ID
         $id_product = (int) Tools::getValue('id_product', 0);
         if ($id_product <= 0) {
             $this->errors[] = Tools::displayError('The selected product is not valid.');
         }
         // get product_attribute ID
         $id_product_attribute = (int) Tools::getValue('id_product_attribute', 0);
         // check the product hash
         $check = Tools::getValue('check', '');
         $check_valid = md5(_COOKIE_KEY_ . $id_product . $id_product_attribute);
         if ($check != $check_valid) {
             $this->errors[] = Tools::displayError('The selected product is not valid.');
         }
         // get quantity and check that the post value is really an integer
         // If it's not, we have nothing to do
         $quantity = Tools::getValue('quantity', 0);
         if (!is_numeric($quantity) || (int) $quantity <= 0) {
             $this->errors[] = Tools::displayError('The quantity value is not valid.');
         }
         $quantity = (int) $quantity;
         $token = Tools::getValue('token') ? Tools::getValue('token') : $this->token;
         $redirect = self::$currentIndex . '&token=' . $token;
     }
     // Global checks when add / remove product
     if ((Tools::isSubmit('addstock') || Tools::isSubmit('removestock')) && Tools::isSubmit('is_post')) {
         // get warehouse id
         $id_warehouse = (int) Tools::getValue('id_warehouse', 0);
         if ($id_warehouse <= 0 || !Warehouse::exists($id_warehouse)) {
             $this->errors[] = Tools::displayError('The selected warehouse is not valid.');
         }
         // get stock movement reason id
         $id_stock_mvt_reason = (int) Tools::getValue('id_stock_mvt_reason', 0);
         if ($id_stock_mvt_reason <= 0 || !StockMvtReason::exists($id_stock_mvt_reason)) {
             $this->errors[] = Tools::displayError('The reason is not valid.');
         }
         // get usable flag
         $usable = Tools::getValue('usable', null);
         if (is_null($usable)) {
             $this->errors[] = Tools::displayError('You have to specify whether the product quantity is usable for sale on shops or not.');
         }
         $usable = (bool) $usable;
     }
     if (Tools::isSubmit('addstock') && Tools::isSubmit('is_post')) {
         // get product unit price
         $price = str_replace(',', '.', Tools::getValue('price', 0));
         if (!is_numeric($price)) {
             $this->errors[] = Tools::displayError('The product price is not valid.');
         }
         $price = round(floatval($price), 6);
         // get product unit price currency id
         $id_currency = (int) Tools::getValue('id_currency', 0);
         if ($id_currency <= 0 || (!($result = Currency::getCurrency($id_currency)) || empty($result))) {
             $this->errors[] = Tools::displayError('The selected currency is not valid.');
         }
         // if all is ok, add stock
         if (count($this->errors) == 0) {
             $warehouse = new Warehouse($id_warehouse);
             // convert price to warehouse currency if needed
             if ($id_currency != $warehouse->id_currency) {
                 // First convert price to the default currency
                 $price_converted_to_default_currency = Tools::convertPrice($price, $id_currency, false);
                 // Convert the new price from default currency to needed currency
                 $price = Tools::convertPrice($price_converted_to_default_currency, $warehouse->id_currency, true);
             }
             // add stock
             $stock_manager = StockManagerFactory::getManager();
             if ($stock_manager->addProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $price, $usable)) {
                 // Create warehouse_product_location entry if we add stock to a new warehouse
                 $id_wpl = (int) WarehouseProductLocation::getIdByProductAndWarehouse($id_product, $id_product_attribute, $id_warehouse);
                 if (!$id_wpl) {
                     $wpl = new WarehouseProductLocation();
                     $wpl->id_product = (int) $id_product;
                     $wpl->id_product_attribute = (int) $id_product_attribute;
                     $wpl->id_warehouse = (int) $id_warehouse;
                     $wpl->save();
                 }
                 StockAvailable::synchronize($id_product);
                 if (Tools::isSubmit('addstockAndStay')) {
                     $redirect = self::$currentIndex . '&id_product=' . (int) $id_product;
                     if ($id_product_attribute) {
                         $redirect .= '&id_product_attribute=' . (int) $id_product_attribute;
                     }
                     $redirect .= '&addstock&token=' . $token;
                 }
                 Tools::redirectAdmin($redirect . '&conf=1');
             } else {
                 $this->errors[] = Tools::displayError('An error occurred. No stock was added.');
             }
         }
     }
     if (Tools::isSubmit('removestock') && Tools::isSubmit('is_post')) {
         // if all is ok, remove stock
         if (count($this->errors) == 0) {
             $warehouse = new Warehouse($id_warehouse);
             // remove stock
             $stock_manager = StockManagerFactory::getManager();
             $removed_products = $stock_manager->removeProduct($id_product, $id_product_attribute, $warehouse, $quantity, $id_stock_mvt_reason, $usable);
             if (count($removed_products) > 0) {
                 StockAvailable::synchronize($id_product);
                 Tools::redirectAdmin($redirect . '&conf=2');
             } else {
                 $physical_quantity_in_stock = (int) $stock_manager->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), false);
                 $usable_quantity_in_stock = (int) $stock_manager->getProductPhysicalQuantities($id_product, $id_product_attribute, array($warehouse->id), true);
                 $not_usable_quantity = $physical_quantity_in_stock - $usable_quantity_in_stock;
                 if ($usable_quantity_in_stock < $quantity) {
                     $this->errors[] = sprintf(Tools::displayError('You don\'t have enough usable quantity. Cannot remove %d items out of %d.'), (int) $quantity, (int) $usable_quantity_in_stock);
                 } elseif ($not_usable_quantity < $quantity) {
                     $this->errors[] = sprintf(Tools::displayError('You don\'t have enough usable quantity. Cannot remove %d items out of %d.'), (int) $quantity, (int) $not_usable_quantity);
                 } else {
                     $this->errors[] = Tools::displayError('It is not possible to remove the specified quantity. Therefore no stock was removed.');
                 }
             }
         }
     }
     if (Tools::isSubmit('transferstock') && Tools::isSubmit('is_post')) {
         // get source warehouse id
         $id_warehouse_from = (int) Tools::getValue('id_warehouse_from', 0);
         if ($id_warehouse_from <= 0 || !Warehouse::exists($id_warehouse_from)) {
             $this->errors[] = Tools::displayError('The source warehouse is not valid.');
         }
         // get destination warehouse id
         $id_warehouse_to = (int) Tools::getValue('id_warehouse_to', 0);
         if ($id_warehouse_to <= 0 || !Warehouse::exists($id_warehouse_to)) {
             $this->errors[] = Tools::displayError('The destination warehouse is not valid.');
         }
         // get usable flag for source warehouse
         $usable_from = Tools::getValue('usable_from', null);
         if (is_null($usable_from)) {
             $this->errors[] = Tools::displayError('You have to specify whether the product quantity in your source warehouse(s) is ready for sale or not.');
         }
         $usable_from = (bool) $usable_from;
         // get usable flag for destination warehouse
         $usable_to = Tools::getValue('usable_to', null);
         if (is_null($usable_to)) {
             $this->errors[] = Tools::displayError('You have to specify whether the product quantity in your destination warehouse(s) is ready for sale or not.');
         }
         $usable_to = (bool) $usable_to;
         // if we can process stock transfers
         if (count($this->errors) == 0) {
             // transfer stock
             $stock_manager = StockManagerFactory::getManager();
             $is_transfer = $stock_manager->transferBetweenWarehouses($id_product, $id_product_attribute, $quantity, $id_warehouse_from, $id_warehouse_to, $usable_from, $usable_to);
             StockAvailable::synchronize($id_product);
             if ($is_transfer) {
                 Tools::redirectAdmin($redirect . '&conf=3');
             } else {
                 $this->errors[] = Tools::displayError('It is not possible to transfer the specified quantity. No stock was transferred.');
             }
         }
     }
 }
Example #12
0
 public function renderView()
 {
     if (!($cart = $this->loadObject(true))) {
         return;
     }
     $customer = new Customer($cart->id_customer);
     $currency = new Currency($cart->id_currency);
     $this->context->cart = $cart;
     $this->context->currency = $currency;
     $this->context->customer = $customer;
     $this->toolbar_title = sprintf($this->l('Cart #%06d'), $this->context->cart->id);
     $products = $cart->getProducts();
     $customized_datas = Product::getAllCustomizedDatas((int) $cart->id);
     Product::addCustomizationPrice($products, $customized_datas);
     $summary = $cart->getSummaryDetails();
     /* Display order information */
     $id_order = (int) Order::getOrderByCartId($cart->id);
     $order = new Order($id_order);
     if (Validate::isLoadedObject($order)) {
         $tax_calculation_method = $order->getTaxCalculationMethod();
         $id_shop = (int) $order->id_shop;
     } else {
         $id_shop = (int) $cart->id_shop;
         $tax_calculation_method = Group::getPriceDisplayMethod(Group::getCurrent()->id);
     }
     if ($tax_calculation_method == PS_TAX_EXC) {
         $total_products = $summary['total_products'];
         $total_discounts = $summary['total_discounts_tax_exc'];
         $total_wrapping = $summary['total_wrapping_tax_exc'];
         $total_price = $summary['total_price_without_tax'];
         $total_shipping = $summary['total_shipping_tax_exc'];
     } else {
         $total_products = $summary['total_products_wt'];
         $total_discounts = $summary['total_discounts'];
         $total_wrapping = $summary['total_wrapping'];
         $total_price = $summary['total_price'];
         $total_shipping = $summary['total_shipping'];
     }
     foreach ($products as $k => &$product) {
         if ($tax_calculation_method == PS_TAX_EXC) {
             $product['product_price'] = $product['price'];
             $product['product_total'] = $product['total'];
         } else {
             $product['product_price'] = $product['price_wt'];
             $product['product_total'] = $product['total_wt'];
         }
         $image = array();
         if (isset($product['id_product_attribute']) && (int) $product['id_product_attribute']) {
             $image = Db::getInstance()->getRow('SELECT id_image FROM ' . _DB_PREFIX_ . 'product_attribute_image WHERE id_product_attribute = ' . (int) $product['id_product_attribute']);
         }
         if (!isset($image['id_image'])) {
             $image = Db::getInstance()->getRow('SELECT id_image FROM ' . _DB_PREFIX_ . 'image WHERE id_product = ' . (int) $product['id_product'] . ' AND cover = 1');
         }
         $product_obj = new Product($product['id_product']);
         $product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, (int) $id_shop);
         $image_product = new Image($image['id_image']);
         $product['image'] = isset($image['id_image']) ? ImageManager::thumbnail(_PS_IMG_DIR_ . 'p/' . $image_product->getExistingImgPath() . '.jpg', 'product_mini_' . (int) $product['id_product'] . (isset($product['id_product_attribute']) ? '_' . (int) $product['id_product_attribute'] : '') . '.jpg', 45, 'jpg') : '--';
     }
     $helper = new HelperKpi();
     $helper->id = 'box-kpi-cart';
     $helper->icon = 'icon-shopping-cart';
     $helper->color = 'color1';
     $helper->title = $this->l('Total Cart', null, null, false);
     $helper->subtitle = sprintf($this->l('Cart #%06d', null, null, false), $cart->id);
     $helper->value = Tools::displayPrice($total_price, $currency);
     $kpi = $helper->generate();
     $this->tpl_view_vars = array('kpi' => $kpi, 'products' => $products, 'discounts' => $cart->getCartRules(), 'order' => $order, 'cart' => $cart, 'currency' => $currency, 'customer' => $customer, 'customer_stats' => $customer->getStats(), 'total_products' => $total_products, 'total_discounts' => $total_discounts, 'total_wrapping' => $total_wrapping, 'total_price' => $total_price, 'total_shipping' => $total_shipping, 'customized_datas' => $customized_datas);
     return parent::renderView();
 }
Example #13
0
 /**
  *
  * This method allow to add stock information on a product detail
  *
  * If advanced stock management is active, get physical stock of this product in the warehouse associated to the ptoduct for the current order
  * Else get the available quantity of the product in fucntion of the shop associated to the order
  *
  * @param array &$product
  */
 protected function setProductCurrentStock(&$product)
 {
     if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int) $product['advanced_stock_management'] == 1 && (int) $product['id_warehouse'] > 0) {
         $product['current_stock'] = StockManagerFactory::getManager()->getProductPhysicalQuantities($product['product_id'], $product['product_attribute_id'], (int) $product['id_warehouse'], true);
     } else {
         $product['current_stock'] = StockAvailable::getQuantityAvailableByProduct($product['product_id'], $product['product_attribute_id'], (int) $this->id_shop);
     }
 }
Example #14
0
    public function getFilterBlock($selected_filters = array())
    {
        global $cookie;
        static $cache = null;
        $id_lang = Context::getContext()->language->id;
        $currency = Context::getContext()->currency;
        $id_shop = (int) Context::getContext()->shop->id;
        $alias = 'product_shop';
        if (is_array($cache)) {
            return $cache;
        }
        $home_category = Configuration::get('PS_HOME_CATEGORY');
        $id_parent = (int) Tools::getValue('id_category', Tools::getValue('id_category_layered', $home_category));
        if ($id_parent == $home_category) {
            return;
        }
        $parent = new Category((int) $id_parent, $id_lang);
        /* Get the filters for the current category */
        $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
			SELECT * FROM ' . _DB_PREFIX_ . 'layered_category
			WHERE id_category = ' . (int) $id_parent . '
				AND id_shop = ' . $id_shop . '
			GROUP BY `type`, id_value ORDER BY position ASC');
        // Remove all empty selected filters
        foreach ($selected_filters as $key => $value) {
            switch ($key) {
                case 'price':
                case 'weight':
                    if ($value[0] === '' && $value[1] === '') {
                        unset($selected_filters[$key]);
                    }
                    break;
                default:
                    if ($value == '') {
                        unset($selected_filters[$key]);
                    }
                    break;
            }
        }
        $filter_blocks = array();
        foreach ($filters as $filter) {
            $sql_query = array('select' => '', 'from' => '', 'join' => '', 'where' => '', 'group' => '', 'second_query' => '');
            switch ($filter['type']) {
                // conditions + quantities + weight + price
                case 'price':
                case 'weight':
                case 'condition':
                case 'quantity':
                    $sql_query['select'] = 'SELECT p.`id_product`, product_shop.`condition`, p.`id_manufacturer`, sa.`quantity`, p.`weight` ';
                    $sql_query['from'] = '
					FROM ' . _DB_PREFIX_ . 'product p ';
                    $sql_query['join'] = '
					INNER JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product)
					INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND
					' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . '
					AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . '
					AND c.active = 1) ';
                    $sql_query['join'] .= 'LEFT JOIN `' . _DB_PREFIX_ . 'stock_available` sa
						ON (sa.id_product = p.id_product AND sa.id_shop = ' . (int) $this->context->shop->id . ') ';
                    $sql_query['where'] = 'WHERE product_shop.`active` = 1 AND product_shop.`visibility` IN ("both", "catalog") ';
                    $sql_query['group'] = ' GROUP BY p.id_product ';
                    break;
                case 'manufacturer':
                    $sql_query['select'] = 'SELECT m.name, COUNT(DISTINCT p.id_product) nbr, m.id_manufacturer ';
                    $sql_query['from'] = '
					FROM `' . _DB_PREFIX_ . 'category_product` cp
					INNER JOIN  `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category)
					INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product)
					INNER JOIN ' . _DB_PREFIX_ . 'manufacturer m ON (m.id_manufacturer = p.id_manufacturer) ';
                    $sql_query['where'] = 'WHERE
					' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . '
					AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . '
					AND c.active = 1
					AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")';
                    $sql_query['group'] = ' GROUP BY p.id_manufacturer ORDER BY m.name';
                    if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) {
                        $sql_query['second_query'] = '
							SELECT m.name, 0 nbr, m.id_manufacturer

							FROM `' . _DB_PREFIX_ . 'category_product` cp' . Shop::addSqlAssociation('product', 'cp') . '
							INNER JOIN  `' . _DB_PREFIX_ . 'category` c ON (c.id_category = cp.id_category)
							INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product)
							INNER JOIN ' . _DB_PREFIX_ . 'manufacturer m ON (m.id_manufacturer = p.id_manufacturer)

							WHERE ' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . '
							AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . '
							AND c.active = 1
							AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
							GROUP BY p.id_manufacturer ORDER BY m.name';
                    }
                    break;
                case 'id_attribute_group':
                    // attribute group
                    $sql_query['select'] = '
					SELECT COUNT(DISTINCT p.id_product) nbr, lpa.id_attribute_group,
					a.color, al.name attribute_name, agl.public_name attribute_group_name , lpa.id_attribute, ag.is_color_group,
					liagl.url_name name_url_name, liagl.meta_title name_meta_title, lial.url_name value_url_name, lial.meta_title value_meta_title';
                    $sql_query['from'] = '
					FROM ' . _DB_PREFIX_ . 'layered_product_attribute lpa
					INNER JOIN ' . _DB_PREFIX_ . 'attribute a
					ON a.id_attribute = lpa.id_attribute
					INNER JOIN ' . _DB_PREFIX_ . 'attribute_lang al
					ON al.id_attribute = a.id_attribute
					AND al.id_lang = ' . (int) $id_lang . '
					INNER JOIN ' . _DB_PREFIX_ . 'product as p
					ON p.id_product = lpa.id_product
					INNER JOIN ' . _DB_PREFIX_ . 'attribute_group ag
					ON ag.id_attribute_group = lpa.id_attribute_group
					INNER JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl
					ON agl.id_attribute_group = lpa.id_attribute_group
					AND agl.id_lang = ' . (int) $id_lang . '
					LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_group_lang_value liagl
					ON (liagl.id_attribute_group = lpa.id_attribute_group AND liagl.id_lang = ' . (int) $id_lang . ')
					LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_lang_value lial
					ON (lial.id_attribute = lpa.id_attribute AND lial.id_lang = ' . (int) $id_lang . ') ';
                    $sql_query['where'] = 'WHERE a.id_attribute_group = ' . (int) $filter['id_value'];
                    $sql_query['where'] .= ' AND lpa.`id_shop` = ' . (int) Context::getContext()->shop->id;
                    $sql_query['where'] .= ' AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
					AND p.id_product IN (
						SELECT id_product
						FROM ' . _DB_PREFIX_ . 'category_product cp
						INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND
						' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . '
						AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . '
						AND c.active = 1)
					) ';
                    $sql_query['group'] = '
					GROUP BY lpa.id_attribute
					ORDER BY ag.`position` ASC, a.`position` ASC';
                    if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) {
                        $sql_query['second_query'] = '
							SELECT 0 nbr, lpa.id_attribute_group,
								a.color, al.name attribute_name, agl.public_name attribute_group_name , lpa.id_attribute, ag.is_color_group,
								liagl.url_name name_url_name, liagl.meta_title name_meta_title, lial.url_name value_url_name, lial.meta_title value_meta_title
							FROM ' . _DB_PREFIX_ . 'layered_product_attribute lpa' . Shop::addSqlAssociation('product', 'lpa') . '
							INNER JOIN ' . _DB_PREFIX_ . 'attribute a
								ON a.id_attribute = lpa.id_attribute
							INNER JOIN ' . _DB_PREFIX_ . 'attribute_lang al
								ON al.id_attribute = a.id_attribute AND al.id_lang = ' . (int) $id_lang . '
							INNER JOIN ' . _DB_PREFIX_ . 'product as p
								ON p.id_product = lpa.id_product
							INNER JOIN ' . _DB_PREFIX_ . 'attribute_group ag
								ON ag.id_attribute_group = lpa.id_attribute_group
							INNER JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl
								ON agl.id_attribute_group = lpa.id_attribute_group
							AND agl.id_lang = ' . (int) $id_lang . '
							LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_group_lang_value liagl
								ON (liagl.id_attribute_group = lpa.id_attribute_group AND liagl.id_lang = ' . (int) $id_lang . ')
							LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_attribute_lang_value lial
								ON (lial.id_attribute = lpa.id_attribute AND lial.id_lang = ' . (int) $id_lang . ')
							WHERE ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
							AND a.id_attribute_group = ' . (int) $filter['id_value'] . '
							AND lpa.`id_shop` = ' . (int) Context::getContext()->shop->id . '
							GROUP BY lpa.id_attribute
							ORDER BY id_attribute_group, id_attribute';
                    }
                    break;
                case 'id_feature':
                    $sql_query['select'] = 'SELECT fl.name feature_name, fp.id_feature, fv.id_feature_value, fvl.value,
					COUNT(DISTINCT p.id_product) nbr,
					lifl.url_name name_url_name, lifl.meta_title name_meta_title, lifvl.url_name value_url_name, lifvl.meta_title value_meta_title ';
                    $sql_query['from'] = '
					FROM ' . _DB_PREFIX_ . 'feature_product fp
					INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = fp.id_product)
					LEFT JOIN ' . _DB_PREFIX_ . 'feature_lang fl ON (fl.id_feature = fp.id_feature AND fl.id_lang = ' . $id_lang . ')
					INNER JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.id_feature_value = fp.id_feature_value AND (fv.custom IS NULL OR fv.custom = 0))
					LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang fvl ON (fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . $id_lang . ')
					LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_lang_value lifl
					ON (lifl.id_feature = fp.id_feature AND lifl.id_lang = ' . $id_lang . ')
					LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_value_lang_value lifvl
					ON (lifvl.id_feature_value = fp.id_feature_value AND lifvl.id_lang = ' . $id_lang . ') ';
                    $sql_query['where'] = 'WHERE ' . $alias . '.`active` = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
					AND fp.id_feature = ' . (int) $filter['id_value'] . '
					AND p.id_product IN (
					SELECT id_product
					FROM ' . _DB_PREFIX_ . 'category_product cp
					INNER JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category AND
					' . (Configuration::get('PS_LAYERED_FULL_TREE') ? 'c.nleft >= ' . (int) $parent->nleft . '
					AND c.nright <= ' . (int) $parent->nright : 'c.id_category = ' . (int) $id_parent) . '
					AND c.active = 1)) ';
                    $sql_query['group'] = 'GROUP BY fv.id_feature_value';
                    if (!Configuration::get('PS_LAYERED_HIDE_0_VALUES')) {
                        $sql_query['second_query'] = '
							SELECT fl.name feature_name, fp.id_feature, fv.id_feature_value, fvl.value,
							0 nbr,
							lifl.url_name name_url_name, lifl.meta_title name_meta_title, lifvl.url_name value_url_name, lifvl.meta_title value_meta_title

							FROM ' . _DB_PREFIX_ . 'feature_product fp' . Shop::addSqlAssociation('product', 'fp') . '
							INNER JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = fp.id_product)
							LEFT JOIN ' . _DB_PREFIX_ . 'feature_lang fl ON (fl.id_feature = fp.id_feature AND fl.id_lang = ' . (int) $id_lang . ')
							INNER JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.id_feature_value = fp.id_feature_value AND (fv.custom IS NULL OR fv.custom = 0))
							LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang fvl ON (fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . (int) $id_lang . ')
							LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_lang_value lifl
								ON (lifl.id_feature = fp.id_feature AND lifl.id_lang = ' . (int) $id_lang . ')
							LEFT JOIN ' . _DB_PREFIX_ . 'layered_indexable_feature_value_lang_value lifvl
								ON (lifvl.id_feature_value = fp.id_feature_value AND lifvl.id_lang = ' . (int) $id_lang . ')
							WHERE ' . $alias . '.`active` = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")
							AND fp.id_feature = ' . (int) $filter['id_value'] . '
							GROUP BY fv.id_feature_value';
                    }
                    break;
                case 'category':
                    if (Group::isFeatureActive()) {
                        $this->user_groups = $this->context->customer->isLogged() ? $this->context->customer->getGroups() : array(Configuration::get('PS_UNIDENTIFIED_GROUP'));
                    }
                    $depth = Configuration::get('PS_LAYERED_FILTER_CATEGORY_DEPTH');
                    if ($depth === false) {
                        $depth = 1;
                    }
                    $sql_query['select'] = '
					SELECT c.id_category, c.id_parent, cl.name, (SELECT count(DISTINCT p.id_product) # ';
                    $sql_query['from'] = '
					FROM ' . _DB_PREFIX_ . 'category_product cp
					LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = cp.id_product) ';
                    $sql_query['where'] = '
					WHERE cp.id_category = c.id_category
					AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog")';
                    $sql_query['group'] = ') count_products
					FROM ' . _DB_PREFIX_ . 'category c
					LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = c.id_category AND cl.`id_shop` = ' . (int) Context::getContext()->shop->id . ' and cl.id_lang = ' . (int) $id_lang . ') ';
                    if (Group::isFeatureActive()) {
                        $sql_query['group'] .= 'RIGHT JOIN ' . _DB_PREFIX_ . 'category_group cg ON (cg.id_category = c.id_category AND cg.`id_group` IN (' . implode(', ', $this->user_groups) . ')) ';
                    }
                    $sql_query['group'] .= 'WHERE c.nleft > ' . (int) $parent->nleft . '
					AND c.nright < ' . (int) $parent->nright . '
					' . ($depth ? 'AND c.level_depth <= ' . ($parent->level_depth + (int) $depth) : '') . '
					AND c.active = 1
					GROUP BY c.id_category ORDER BY c.nleft, c.position';
            }
            foreach ($filters as $filter_tmp) {
                $method_name = 'get' . ucfirst($filter_tmp['type']) . 'FilterSubQuery';
                if (method_exists('BlockLayered', $method_name) && (!in_array($filter['type'], array('price', 'weight')) && $filter['type'] != $filter_tmp['type'] || $filter['type'] == $filter_tmp['type'])) {
                    if ($filter['type'] == $filter_tmp['type'] && $filter['id_value'] == $filter_tmp['id_value']) {
                        $sub_query_filter = self::$method_name(array(), true);
                    } else {
                        if (!is_null($filter_tmp['id_value'])) {
                            $selected_filters_cleaned = $this->cleanFilterByIdValue(@$selected_filters[$filter_tmp['type']], $filter_tmp['id_value']);
                        } else {
                            $selected_filters_cleaned = @$selected_filters[$filter_tmp['type']];
                        }
                        $sub_query_filter = self::$method_name($selected_filters_cleaned, $filter['type'] == $filter_tmp['type']);
                    }
                    foreach ($sub_query_filter as $key => $value) {
                        $sql_query[$key] .= $value;
                    }
                }
            }
            $products = false;
            if (!empty($sql_query['from'])) {
                $sql_query['from'] .= Shop::addSqlAssociation('product', 'p');
                $products = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql_query['select'] . "\n" . $sql_query['from'] . "\n" . $sql_query['join'] . "\n" . $sql_query['where'] . "\n" . $sql_query['group']);
            }
            foreach ($filters as $filter_tmp) {
                $method_name = 'filterProductsBy' . ucfirst($filter_tmp['type']);
                if (method_exists('BlockLayered', $method_name) && (!in_array($filter['type'], array('price', 'weight')) && $filter['type'] != $filter_tmp['type'] || $filter['type'] == $filter_tmp['type'])) {
                    if ($filter['type'] == $filter_tmp['type']) {
                        $products = self::$method_name(array(), $products);
                    } else {
                        $products = self::$method_name(@$selected_filters[$filter_tmp['type']], $products);
                    }
                }
            }
            if (!empty($sql_query['second_query'])) {
                $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql_query['second_query']);
                if ($res) {
                    $products = array_merge($products, $res);
                }
            }
            switch ($filter['type']) {
                case 'price':
                    if ($this->showPriceFilter()) {
                        $price_array = array('type_lite' => 'price', 'type' => 'price', 'id_key' => 0, 'name' => $this->l('Price'), 'slider' => true, 'max' => '0', 'min' => null, 'values' => array('1' => 0), 'unit' => $currency->sign, 'format' => $currency->format, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                        if (isset($products) && $products) {
                            foreach ($products as $product) {
                                if (is_null($price_array['min'])) {
                                    $price_array['min'] = $product['price_min'];
                                    $price_array['values'][0] = $product['price_min'];
                                } else {
                                    if ($price_array['min'] > $product['price_min']) {
                                        $price_array['min'] = $product['price_min'];
                                        $price_array['values'][0] = $product['price_min'];
                                    }
                                }
                                if ($price_array['max'] < $product['price_max']) {
                                    $price_array['max'] = $product['price_max'];
                                    $price_array['values'][1] = $product['price_max'];
                                }
                            }
                        }
                        if ($price_array['max'] != $price_array['min'] && $price_array['min'] != null) {
                            if ($filter['filter_type'] == 2) {
                                $price_array['list_of_values'] = array();
                                $nbr_of_value = $filter['filter_show_limit'];
                                if ($nbr_of_value < 2) {
                                    $nbr_of_value = 4;
                                }
                                $delta = ($price_array['max'] - $price_array['min']) / $nbr_of_value;
                                $current_step = $price_array['min'];
                                for ($i = 0; $i < $nbr_of_value; $i++) {
                                    $price_array['list_of_values'][] = array((int) ($price_array['min'] + $i * $delta), (int) ($price_array['min'] + ($i + 1) * $delta));
                                }
                            }
                            if (isset($selected_filters['price']) && isset($selected_filters['price'][0]) && isset($selected_filters['price'][1])) {
                                $price_array['values'][0] = $selected_filters['price'][0];
                                $price_array['values'][1] = $selected_filters['price'][1];
                            }
                            $filter_blocks[] = $price_array;
                        }
                    }
                    break;
                case 'weight':
                    $weight_array = array('type_lite' => 'weight', 'type' => 'weight', 'id_key' => 0, 'name' => $this->l('Weight'), 'slider' => true, 'max' => '0', 'min' => null, 'values' => array('1' => 0), 'unit' => Configuration::get('PS_WEIGHT_UNIT'), 'format' => 5, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                    if (isset($products) && $products) {
                        foreach ($products as $product) {
                            if (is_null($weight_array['min'])) {
                                $weight_array['min'] = $product['weight'];
                                $weight_array['values'][0] = $product['weight'];
                            } else {
                                if ($weight_array['min'] > $product['weight']) {
                                    $weight_array['min'] = $product['weight'];
                                    $weight_array['values'][0] = $product['weight'];
                                }
                            }
                            if ($weight_array['max'] < $product['weight']) {
                                $weight_array['max'] = $product['weight'];
                                $weight_array['values'][1] = $product['weight'];
                            }
                        }
                    }
                    if ($weight_array['max'] != $weight_array['min'] && $weight_array['min'] != null) {
                        if (isset($selected_filters['weight']) && isset($selected_filters['weight'][0]) && isset($selected_filters['weight'][1])) {
                            $weight_array['values'][0] = $selected_filters['weight'][0];
                            $weight_array['values'][1] = $selected_filters['weight'][1];
                        }
                        $filter_blocks[] = $weight_array;
                    }
                    break;
                case 'condition':
                    $condition_array = array('new' => array('name' => $this->l('New'), 'nbr' => 0), 'used' => array('name' => $this->l('Used'), 'nbr' => 0), 'refurbished' => array('name' => $this->l('Refurbished'), 'nbr' => 0));
                    if (isset($products) && $products) {
                        foreach ($products as $product) {
                            if (isset($selected_filters['condition']) && in_array($product['condition'], $selected_filters['condition'])) {
                                $condition_array[$product['condition']]['checked'] = true;
                            }
                        }
                    }
                    foreach ($condition_array as $key => $condition) {
                        if (isset($selected_filters['condition']) && in_array($key, $selected_filters['condition'])) {
                            $condition_array[$key]['checked'] = true;
                        }
                    }
                    if (isset($products) && $products) {
                        foreach ($products as $product) {
                            if (isset($condition_array[$product['condition']])) {
                                $condition_array[$product['condition']]['nbr']++;
                            }
                        }
                    }
                    $filter_blocks[] = array('type_lite' => 'condition', 'type' => 'condition', 'id_key' => 0, 'name' => $this->l('Condition'), 'values' => $condition_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                    break;
                case 'quantity':
                    $quantity_array = array(0 => array('name' => $this->l('Not available'), 'nbr' => 0), 1 => array('name' => $this->l('In stock'), 'nbr' => 0));
                    foreach ($quantity_array as $key => $quantity) {
                        if (isset($selected_filters['quantity']) && in_array($key, $selected_filters['quantity'])) {
                            $quantity_array[$key]['checked'] = true;
                        }
                    }
                    if (isset($products) && $products) {
                        foreach ($products as $product) {
                            //If oosp move all not available quantity to available quantity
                            if ((int) $product['quantity'] > 0 || Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($product['id_product']))) {
                                $quantity_array[1]['nbr']++;
                            } else {
                                $quantity_array[0]['nbr']++;
                            }
                        }
                    }
                    $filter_blocks[] = array('type_lite' => 'quantity', 'type' => 'quantity', 'id_key' => 0, 'name' => $this->l('Availability'), 'values' => $quantity_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                    break;
                case 'manufacturer':
                    if (isset($products) && $products) {
                        $manufaturers_array = array();
                        foreach ($products as $manufacturer) {
                            if (!isset($manufaturers_array[$manufacturer['id_manufacturer']])) {
                                $manufaturers_array[$manufacturer['id_manufacturer']] = array('name' => $manufacturer['name'], 'nbr' => $manufacturer['nbr']);
                            }
                            if (isset($selected_filters['manufacturer']) && in_array((int) $manufacturer['id_manufacturer'], $selected_filters['manufacturer'])) {
                                $manufaturers_array[$manufacturer['id_manufacturer']]['checked'] = true;
                            }
                        }
                        $filter_blocks[] = array('type_lite' => 'manufacturer', 'type' => 'manufacturer', 'id_key' => 0, 'name' => $this->l('Manufacturer'), 'values' => $manufaturers_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                    }
                    break;
                case 'id_attribute_group':
                    $attributes_array = array();
                    if (isset($products) && $products) {
                        foreach ($products as $attributes) {
                            if (!isset($attributes_array[$attributes['id_attribute_group']])) {
                                $attributes_array[$attributes['id_attribute_group']] = array('type_lite' => 'id_attribute_group', 'type' => 'id_attribute_group', 'id_key' => (int) $attributes['id_attribute_group'], 'name' => $attributes['attribute_group_name'], 'is_color_group' => (bool) $attributes['is_color_group'], 'values' => array(), 'url_name' => $attributes['name_url_name'], 'meta_title' => $attributes['name_meta_title'], 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                            }
                            if (!isset($attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']])) {
                                $attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']] = array('color' => $attributes['color'], 'name' => $attributes['attribute_name'], 'nbr' => (int) $attributes['nbr'], 'url_name' => $attributes['value_url_name'], 'meta_title' => $attributes['value_meta_title']);
                            }
                            if (isset($selected_filters['id_attribute_group'][$attributes['id_attribute']])) {
                                $attributes_array[$attributes['id_attribute_group']]['values'][$attributes['id_attribute']]['checked'] = true;
                            }
                        }
                        $filter_blocks = array_merge($filter_blocks, $attributes_array);
                    }
                    break;
                case 'id_feature':
                    $feature_array = array();
                    if (isset($products) && $products) {
                        foreach ($products as $feature) {
                            if (!isset($feature_array[$feature['id_feature']])) {
                                $feature_array[$feature['id_feature']] = array('type_lite' => 'id_feature', 'type' => 'id_feature', 'id_key' => (int) $feature['id_feature'], 'values' => array(), 'name' => $feature['feature_name'], 'url_name' => $feature['name_url_name'], 'meta_title' => $feature['name_meta_title'], 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                            }
                            if (!isset($feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']])) {
                                $feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']] = array('nbr' => (int) $feature['nbr'], 'name' => $feature['value'], 'url_name' => $feature['value_url_name'], 'meta_title' => $feature['value_meta_title']);
                            }
                            if (isset($selected_filters['id_feature'][$feature['id_feature_value']])) {
                                $feature_array[$feature['id_feature']]['values'][$feature['id_feature_value']]['checked'] = true;
                            }
                        }
                        //Natural sort
                        foreach ($feature_array as $key => $value) {
                            $temp = array();
                            foreach ($feature_array[$key]['values'] as $keyint => $valueint) {
                                $temp[$keyint] = $valueint['name'];
                            }
                            natcasesort($temp);
                            $temp2 = array();
                            foreach ($temp as $keytemp => $valuetemp) {
                                $temp2[$keytemp] = $feature_array[$key]['values'][$keytemp];
                            }
                            $feature_array[$key]['values'] = $temp2;
                        }
                        $filter_blocks = array_merge($filter_blocks, $feature_array);
                    }
                    break;
                case 'category':
                    $tmp_array = array();
                    if (isset($products) && $products) {
                        $categories_with_products_count = 0;
                        foreach ($products as $category) {
                            $tmp_array[$category['id_category']] = array('name' => $category['name'], 'nbr' => (int) $category['count_products']);
                            if ((int) $category['count_products']) {
                                $categories_with_products_count++;
                            }
                            if (isset($selected_filters['category']) && in_array($category['id_category'], $selected_filters['category'])) {
                                $tmp_array[$category['id_category']]['checked'] = true;
                            }
                        }
                        if ($categories_with_products_count || !Configuration::get('PS_LAYERED_HIDE_0_VALUES')) {
                            $filter_blocks[] = array('type_lite' => 'category', 'type' => 'category', 'id_key' => 0, 'name' => $this->l('Categories'), 'values' => $tmp_array, 'filter_show_limit' => $filter['filter_show_limit'], 'filter_type' => $filter['filter_type']);
                        }
                    }
                    break;
            }
        }
        // All non indexable attribute and feature
        $non_indexable = array();
        // Get all non indexable attribute groups
        foreach (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT public_name
		FROM `' . _DB_PREFIX_ . 'attribute_group_lang` agl
		LEFT JOIN `' . _DB_PREFIX_ . 'layered_indexable_attribute_group` liag
		ON liag.id_attribute_group = agl.id_attribute_group
		WHERE indexable IS NULL OR indexable = 0
		AND id_lang = ' . (int) $id_lang) as $attribute) {
            $non_indexable[] = Tools::link_rewrite($attribute['public_name']);
        }
        // Get all non indexable features
        foreach (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT name
		FROM `' . _DB_PREFIX_ . 'feature_lang` fl
		LEFT JOIN  `' . _DB_PREFIX_ . 'layered_indexable_feature` lif
		ON lif.id_feature = fl.id_feature
		WHERE indexable IS NULL OR indexable = 0
		AND id_lang = ' . (int) $id_lang) as $attribute) {
            $non_indexable[] = Tools::link_rewrite($attribute['name']);
        }
        //generate SEO link
        $param_selected = '';
        $param_product_url = '';
        $option_checked_array = array();
        $param_group_selected_array = array();
        $title_values = array();
        $meta_values = array();
        //get filters checked by group
        foreach ($filter_blocks as $type_filter) {
            $filter_name = !empty($type_filter['url_name']) ? $type_filter['url_name'] : $type_filter['name'];
            $filter_meta = !empty($type_filter['meta_title']) ? $type_filter['meta_title'] : $type_filter['name'];
            $attr_key = $type_filter['type'] . '_' . $type_filter['id_key'];
            $param_group_selected = '';
            if (in_array(strtolower($type_filter['type']), array('price', 'weight')) && (double) $type_filter['values'][0] > (double) $type_filter['min'] && (double) $type_filter['values'][1] > (double) $type_filter['max']) {
                $param_group_selected .= $this->getAnchor() . str_replace($this->getAnchor(), '_', $type_filter['values'][0]) . $this->getAnchor() . str_replace($this->getAnchor(), '_', $type_filter['values'][1]);
                $param_group_selected_array[Tools::link_rewrite($filter_name)][] = Tools::link_rewrite($filter_name);
                if (!isset($title_values[$filter_meta])) {
                    $title_values[$filter_meta] = array();
                }
                $title_values[$filter_meta][] = $filter_meta;
                if (!isset($meta_values[$attr_key])) {
                    $meta_values[$attr_key] = array('title' => $filter_meta, 'values' => array());
                }
                $meta_values[$attr_key]['values'][] = $filter_meta;
            } else {
                foreach ($type_filter['values'] as $key => $value) {
                    if (is_array($value) && array_key_exists('checked', $value)) {
                        $value_name = !empty($value['url_name']) ? $value['url_name'] : $value['name'];
                        $value_meta = !empty($value['meta_title']) ? $value['meta_title'] : $value['name'];
                        $param_group_selected .= $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name));
                        $param_group_selected_array[Tools::link_rewrite($filter_name)][] = Tools::link_rewrite($value_name);
                        if (!isset($title_values[$filter_meta])) {
                            $title_values[$filter_meta] = array();
                        }
                        $title_values[$filter_meta][] = $value_name;
                        if (!isset($meta_values[$attr_key])) {
                            $meta_values[$attr_key] = array('title' => $filter_meta, 'values' => array());
                        }
                        $meta_values[$attr_key]['values'][] = $value_meta;
                    } else {
                        $param_group_selected_array[Tools::link_rewrite($filter_name)][] = array();
                    }
                }
            }
            if (!empty($param_group_selected)) {
                $param_selected .= '/' . str_replace($this->getAnchor(), '_', Tools::link_rewrite($filter_name)) . $param_group_selected;
                $option_checked_array[Tools::link_rewrite($filter_name)] = $param_group_selected;
            }
            // select only attribute and group attribute to display an unique product combination link
            if (!empty($param_group_selected) && $type_filter['type'] == 'id_attribute_group') {
                $param_product_url .= '/' . str_replace($this->getAnchor(), '_', Tools::link_rewrite($filter_name)) . $param_group_selected;
            }
        }
        if ($this->page > 1) {
            $param_selected .= '/page-' . $this->page;
        }
        $blacklist = array('weight', 'price');
        if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CDT')) {
            $blacklist[] = 'condition';
        }
        if (!Configuration::get('PS_LAYERED_FILTER_INDEX_QTY')) {
            $blacklist[] = 'quantity';
        }
        if (!Configuration::get('PS_LAYERED_FILTER_INDEX_MNF')) {
            $blacklist[] = 'manufacturer';
        }
        if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CAT')) {
            $blacklist[] = 'category';
        }
        $global_nofollow = false;
        foreach ($filter_blocks as &$type_filter) {
            $filter_name = !empty($type_filter['url_name']) ? $type_filter['url_name'] : $type_filter['name'];
            if (count($type_filter) > 0 && !isset($type_filter['slider'])) {
                foreach ($type_filter['values'] as $key => $values) {
                    $nofollow = false;
                    if (!empty($values['checked']) && in_array($type_filter['type'], $blacklist)) {
                        $global_nofollow = true;
                    }
                    $option_checked_clone_array = $option_checked_array;
                    // If not filters checked, add parameter
                    $value_name = !empty($values['url_name']) ? $values['url_name'] : $values['name'];
                    if (!in_array(Tools::link_rewrite($value_name), $param_group_selected_array[Tools::link_rewrite($filter_name)])) {
                        // Update parameter filter checked before
                        if (array_key_exists(Tools::link_rewrite($filter_name), $option_checked_array)) {
                            $option_checked_clone_array[Tools::link_rewrite($filter_name)] = $option_checked_clone_array[Tools::link_rewrite($filter_name)] . $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name));
                            if (in_array($type_filter['type'], $blacklist)) {
                                $nofollow = true;
                            }
                        } else {
                            $option_checked_clone_array[Tools::link_rewrite($filter_name)] = $this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name));
                        }
                    } else {
                        // Remove selected parameters
                        $option_checked_clone_array[Tools::link_rewrite($filter_name)] = str_replace($this->getAnchor() . str_replace($this->getAnchor(), '_', Tools::link_rewrite($value_name)), '', $option_checked_clone_array[Tools::link_rewrite($filter_name)]);
                        if (empty($option_checked_clone_array[Tools::link_rewrite($filter_name)])) {
                            unset($option_checked_clone_array[Tools::link_rewrite($filter_name)]);
                        }
                    }
                    $parameters = '';
                    ksort($option_checked_clone_array);
                    // Order parameters
                    foreach ($option_checked_clone_array as $key_group => $value_group) {
                        $parameters .= '/' . str_replace($this->getAnchor(), '_', $key_group) . $value_group;
                    }
                    // Add nofollow if any blacklisted filters ins in parameters
                    foreach ($filter_blocks as $filter) {
                        $name = Tools::link_rewrite(!empty($filter['url_name']) ? $filter['url_name'] : $filter['name']);
                        if (in_array($filter['type'], $blacklist) && strpos($parameters, $name . '-') !== false) {
                            $nofollow = true;
                        }
                    }
                    // Check if there is an non indexable attribute or feature in the url
                    foreach ($non_indexable as $value) {
                        if (strpos($parameters, '/' . $value) !== false) {
                            $nofollow = true;
                        }
                    }
                    $type_filter['values'][$key]['link'] = Context::getContext()->link->getCategoryLink($parent, null, null) . '#' . ltrim($parameters, '/');
                    $type_filter['values'][$key]['rel'] = $nofollow ? 'nofollow' : '';
                }
            }
        }
        $n_filters = 0;
        if (isset($selected_filters['price'])) {
            if ($price_array['min'] == $selected_filters['price'][0] && $price_array['max'] == $selected_filters['price'][1]) {
                unset($selected_filters['price']);
            }
        }
        if (isset($selected_filters['weight'])) {
            if ($weight_array['min'] == $selected_filters['weight'][0] && $weight_array['max'] == $selected_filters['weight'][1]) {
                unset($selected_filters['weight']);
            }
        }
        foreach ($selected_filters as $filters) {
            $n_filters += count($filters);
        }
        $cache = array('layered_show_qties' => (int) Configuration::get('PS_LAYERED_SHOW_QTIES'), 'id_category_layered' => (int) $id_parent, 'selected_filters' => $selected_filters, 'n_filters' => (int) $n_filters, 'nbr_filterBlocks' => count($filter_blocks), 'filters' => $filter_blocks, 'title_values' => $title_values, 'meta_values' => $meta_values, 'current_friendly_url' => $param_selected, 'param_product_url' => $param_product_url, 'no_follow' => !empty($param_selected) || $global_nofollow);
        return $cache;
    }
Example #15
0
    protected function attributeImportOne($info, $default_language, &$groups, &$attributes, $regenerate, $shop_is_feature_active, $validateOnly = false)
    {
        AdminImportController::setDefaultValues($info);
        if (!$shop_is_feature_active) {
            $info['shop'] = 1;
        } elseif (!isset($info['shop']) || empty($info['shop'])) {
            $info['shop'] = implode($this->multiple_value_separator, Shop::getContextListShopID());
        }
        // Get shops for each attributes
        $info['shop'] = explode($this->multiple_value_separator, $info['shop']);
        $id_shop_list = array();
        if (is_array($info['shop']) && count($info['shop'])) {
            foreach ($info['shop'] as $shop) {
                if (!empty($shop) && !is_numeric($shop)) {
                    $id_shop_list[] = Shop::getIdByName($shop);
                } elseif (!empty($shop)) {
                    $id_shop_list[] = $shop;
                }
            }
        }
        if (isset($info['id_product']) && $info['id_product']) {
            $product = new Product((int) $info['id_product'], false, $default_language);
        } elseif (Tools::getValue('match_ref') && isset($info['product_reference']) && $info['product_reference']) {
            $datas = Db::getInstance()->getRow('
				SELECT p.`id_product`
				FROM `' . _DB_PREFIX_ . 'product` p
				' . Shop::addSqlAssociation('product', 'p') . '
				WHERE p.`reference` = "' . pSQL($info['product_reference']) . '"
			', false);
            if (isset($datas['id_product']) && $datas['id_product']) {
                $product = new Product((int) $datas['id_product'], false, $default_language);
            }
        } else {
            return;
        }
        $id_image = array();
        if (isset($info['image_url']) && $info['image_url']) {
            $info['image_url'] = explode($this->multiple_value_separator, $info['image_url']);
            if (is_array($info['image_url']) && count($info['image_url'])) {
                foreach ($info['image_url'] as $key => $url) {
                    $url = trim($url);
                    $product_has_images = (bool) Image::getImages($this->context->language->id, $product->id);
                    $image = new Image();
                    $image->id_product = (int) $product->id;
                    $image->position = Image::getHighestPosition($product->id) + 1;
                    $image->cover = !$product_has_images ? true : false;
                    if (isset($info['image_alt'])) {
                        $alt = self::split($info['image_alt']);
                        if (isset($alt[$key]) && strlen($alt[$key]) > 0) {
                            $alt = self::createMultiLangField($alt[$key]);
                            $image->legend = $alt;
                        }
                    }
                    $field_error = $image->validateFields(UNFRIENDLY_ERROR, true);
                    $lang_field_error = $image->validateFieldsLang(UNFRIENDLY_ERROR, true);
                    if ($field_error === true && $lang_field_error === true && !$validateOnly && $image->add()) {
                        $image->associateTo($id_shop_list);
                        // FIXME: 2s/image !
                        if (!AdminImportController::copyImg($product->id, $image->id, $url, 'products', !$regenerate)) {
                            $this->warnings[] = sprintf($this->trans('Error copying image: %s', array(), 'Admin.Parameters.Notification'), $url);
                            $image->delete();
                        } else {
                            $id_image[] = (int) $image->id;
                        }
                        // until here
                    } else {
                        if (!$validateOnly) {
                            $this->warnings[] = sprintf($this->trans('%s cannot be saved', array(), 'Admin.Parameters.Notification'), isset($image->id_product) ? ' (' . $image->id_product . ')' : '');
                        }
                        if ($field_error !== true || $lang_field_error !== true) {
                            $this->errors[] = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '') . mysql_error();
                        }
                    }
                }
            }
        } elseif (isset($info['image_position']) && $info['image_position']) {
            $info['image_position'] = explode($this->multiple_value_separator, $info['image_position']);
            if (is_array($info['image_position']) && count($info['image_position'])) {
                foreach ($info['image_position'] as $position) {
                    // choose images from product by position
                    $images = $product->getImages($default_language);
                    if ($images) {
                        foreach ($images as $row) {
                            if ($row['position'] == (int) $position) {
                                $id_image[] = (int) $row['id_image'];
                                break;
                            }
                        }
                    }
                    if (empty($id_image)) {
                        $this->warnings[] = sprintf($this->trans('No image was found for combination with id_product = %s and image position = %s.', array(), 'Admin.Parameters.Notification'), $product->id, (int) $position);
                    }
                }
            }
        }
        $id_attribute_group = 0;
        // groups
        $groups_attributes = array();
        if (isset($info['group'])) {
            foreach (explode($this->multiple_value_separator, $info['group']) as $key => $group) {
                if (empty($group)) {
                    continue;
                }
                $tab_group = explode(':', $group);
                $group = trim($tab_group[0]);
                if (!isset($tab_group[1])) {
                    $type = 'select';
                } else {
                    $type = trim($tab_group[1]);
                }
                // sets group
                $groups_attributes[$key]['group'] = $group;
                // if position is filled
                if (isset($tab_group[2])) {
                    $position = trim($tab_group[2]);
                } else {
                    $position = false;
                }
                if (!isset($groups[$group])) {
                    $obj = new AttributeGroup();
                    $obj->is_color_group = false;
                    $obj->group_type = pSQL($type);
                    $obj->name[$default_language] = $group;
                    $obj->public_name[$default_language] = $group;
                    $obj->position = !$position ? AttributeGroup::getHigherPosition() + 1 : $position;
                    if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) {
                        // here, cannot avoid attributeGroup insertion to avoid an error during validation step.
                        //if (!$validateOnly) {
                        $obj->add();
                        $obj->associateTo($id_shop_list);
                        $groups[$group] = $obj->id;
                        //}
                    } else {
                        $this->errors[] = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '');
                    }
                    // fills groups attributes
                    $id_attribute_group = $obj->id;
                    $groups_attributes[$key]['id'] = $id_attribute_group;
                } else {
                    // already exists
                    $id_attribute_group = $groups[$group];
                    $groups_attributes[$key]['id'] = $id_attribute_group;
                }
            }
        }
        // inits attribute
        $id_product_attribute = 0;
        $id_product_attribute_update = false;
        $attributes_to_add = array();
        // for each attribute
        if (isset($info['attribute'])) {
            foreach (explode($this->multiple_value_separator, $info['attribute']) as $key => $attribute) {
                if (empty($attribute)) {
                    continue;
                }
                $tab_attribute = explode(':', $attribute);
                $attribute = trim($tab_attribute[0]);
                // if position is filled
                if (isset($tab_attribute[1])) {
                    $position = trim($tab_attribute[1]);
                } else {
                    $position = false;
                }
                if (isset($groups_attributes[$key])) {
                    $group = $groups_attributes[$key]['group'];
                    if (!isset($attributes[$group . '_' . $attribute]) && count($groups_attributes[$key]) == 2) {
                        $id_attribute_group = $groups_attributes[$key]['id'];
                        $obj = new Attribute();
                        // sets the proper id (corresponding to the right key)
                        $obj->id_attribute_group = $groups_attributes[$key]['id'];
                        $obj->name[$default_language] = str_replace('\\n', '', str_replace('\\r', '', $attribute));
                        $obj->position = !$position && isset($groups[$group]) ? Attribute::getHigherPosition($groups[$group]) + 1 : $position;
                        if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) {
                            if (!$validateOnly) {
                                $obj->add();
                                $obj->associateTo($id_shop_list);
                                $attributes[$group . '_' . $attribute] = $obj->id;
                            }
                        } else {
                            $this->errors[] = ($field_error !== true ? $field_error : '') . (isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '');
                        }
                    }
                    $info['minimal_quantity'] = isset($info['minimal_quantity']) && $info['minimal_quantity'] ? (int) $info['minimal_quantity'] : 1;
                    $info['wholesale_price'] = str_replace(',', '.', $info['wholesale_price']);
                    $info['price'] = str_replace(',', '.', $info['price']);
                    $info['ecotax'] = str_replace(',', '.', $info['ecotax']);
                    $info['weight'] = str_replace(',', '.', $info['weight']);
                    $info['available_date'] = Validate::isDate($info['available_date']) ? $info['available_date'] : null;
                    if (!Validate::isEan13($info['ean13'])) {
                        $this->warnings[] = sprintf($this->trans('EAN13 "%1s" has incorrect value for product with id %2d.', array(), 'Admin.Parameters.Notification'), $info['ean13'], $product->id);
                        $info['ean13'] = '';
                    }
                    if ($info['default_on'] && !$validateOnly) {
                        $product->deleteDefaultAttributes();
                    }
                    // if a reference is specified for this product, get the associate id_product_attribute to UPDATE
                    if (isset($info['reference']) && !empty($info['reference'])) {
                        $id_product_attribute = Combination::getIdByReference($product->id, strval($info['reference']));
                        // updates the attribute
                        if ($id_product_attribute && !$validateOnly) {
                            // gets all the combinations of this product
                            $attribute_combinations = $product->getAttributeCombinations($default_language);
                            foreach ($attribute_combinations as $attribute_combination) {
                                if ($id_product_attribute && in_array($id_product_attribute, $attribute_combination)) {
                                    // FIXME: ~3s/declinaison
                                    $product->updateAttribute($id_product_attribute, (double) $info['wholesale_price'], (double) $info['price'], (double) $info['weight'], 0, Configuration::get('PS_USE_ECOTAX') ? (double) $info['ecotax'] : 0, $id_image, strval($info['reference']), strval($info['ean13']), (int) $info['default_on'], 0, strval($info['upc']), (int) $info['minimal_quantity'], $info['available_date'], null, $id_shop_list);
                                    $id_product_attribute_update = true;
                                    if (isset($info['supplier_reference']) && !empty($info['supplier_reference'])) {
                                        $product->addSupplierReference($product->id_supplier, $id_product_attribute, $info['supplier_reference']);
                                    }
                                    // until here
                                }
                            }
                        }
                    }
                    // if no attribute reference is specified, creates a new one
                    if (!$id_product_attribute && !$validateOnly) {
                        $id_product_attribute = $product->addCombinationEntity((double) $info['wholesale_price'], (double) $info['price'], (double) $info['weight'], 0, Configuration::get('PS_USE_ECOTAX') ? (double) $info['ecotax'] : 0, (int) $info['quantity'], $id_image, strval($info['reference']), 0, strval($info['ean13']), (int) $info['default_on'], 0, strval($info['upc']), (int) $info['minimal_quantity'], $id_shop_list, $info['available_date']);
                        if (isset($info['supplier_reference']) && !empty($info['supplier_reference'])) {
                            $product->addSupplierReference($product->id_supplier, $id_product_attribute, $info['supplier_reference']);
                        }
                    }
                    // fills our attributes array, in order to add the attributes to the product_attribute afterwards
                    if (isset($attributes[$group . '_' . $attribute])) {
                        $attributes_to_add[] = (int) $attributes[$group . '_' . $attribute];
                    }
                    // after insertion, we clean attribute position and group attribute position
                    if (!$validateOnly) {
                        $obj = new Attribute();
                        $obj->cleanPositions((int) $id_attribute_group, false);
                        AttributeGroup::cleanPositions();
                    }
                }
            }
        }
        $product->checkDefaultAttributes();
        if (!$product->cache_default_attribute && !$validateOnly) {
            Product::updateDefaultAttribute($product->id);
        }
        if ($id_product_attribute) {
            if (!$validateOnly) {
                // now adds the attributes in the attribute_combination table
                if ($id_product_attribute_update) {
                    Db::getInstance()->execute('
						DELETE FROM ' . _DB_PREFIX_ . 'product_attribute_combination
						WHERE id_product_attribute = ' . (int) $id_product_attribute);
                }
                foreach ($attributes_to_add as $attribute_to_add) {
                    Db::getInstance()->execute('
						INSERT IGNORE INTO ' . _DB_PREFIX_ . 'product_attribute_combination (id_attribute, id_product_attribute)
						VALUES (' . (int) $attribute_to_add . ',' . (int) $id_product_attribute . ')', false);
                }
            }
            // set advanced stock managment
            if (isset($info['advanced_stock_management'])) {
                if ($info['advanced_stock_management'] != 1 && $info['advanced_stock_management'] != 0) {
                    $this->warnings[] = sprintf($this->trans('Advanced stock management has incorrect value. Not set for product with id %d.', array(), 'Admin.Parameters.Notification'), $product->id);
                } elseif (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $info['advanced_stock_management'] == 1) {
                    $this->warnings[] = sprintf($this->trans('Advanced stock management is not enabled, cannot enable on product with id %d.', array(), 'Admin.Parameters.Notification'), $product->id);
                } elseif (!$validateOnly) {
                    $product->setAdvancedStockManagement($info['advanced_stock_management']);
                }
                // automaticly disable depends on stock, if a_s_m set to disabled
                if (!$validateOnly && StockAvailable::dependsOnStock($product->id) == 1 && $info['advanced_stock_management'] == 0) {
                    StockAvailable::setProductDependsOnStock($product->id, 0, null, $id_product_attribute);
                }
            }
            // Check if warehouse exists
            if (isset($info['warehouse']) && $info['warehouse']) {
                if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                    $this->warnings[] = sprintf($this->trans('Advanced stock management is not enabled, warehouse is not set on product with id %d.', array(), 'Admin.Parameters.Notification'), $product->id);
                } else {
                    if (Warehouse::exists($info['warehouse'])) {
                        $warehouse_location_entity = new WarehouseProductLocation();
                        $warehouse_location_entity->id_product = $product->id;
                        $warehouse_location_entity->id_product_attribute = $id_product_attribute;
                        $warehouse_location_entity->id_warehouse = $info['warehouse'];
                        if (!$validateOnly) {
                            if (WarehouseProductLocation::getProductLocation($product->id, $id_product_attribute, $info['warehouse']) !== false) {
                                $warehouse_location_entity->update();
                            } else {
                                $warehouse_location_entity->save();
                            }
                            StockAvailable::synchronize($product->id);
                        }
                    } else {
                        $this->warnings[] = sprintf($this->trans('Warehouse did not exist, cannot set on product %1$s.', array(), 'Admin.Parameters.Notification'), $product->name[$default_language]);
                    }
                }
            }
            // stock available
            if (isset($info['depends_on_stock'])) {
                if ($info['depends_on_stock'] != 0 && $info['depends_on_stock'] != 1) {
                    $this->warnings[] = sprintf($this->trans('Incorrect value for "Depends on stock" for product %1$s ', array(), 'Admin.Notifications.Error'), $product->name[$default_language]);
                } elseif ((!$info['advanced_stock_management'] || $info['advanced_stock_management'] == 0) && $info['depends_on_stock'] == 1) {
                    $this->warnings[] = sprintf($this->trans('Advanced stock management is not enabled, cannot set "Depends on stock" for product %1$s ', array(), 'Admin.Parameters.Notification'), $product->name[$default_language]);
                } elseif (!$validateOnly) {
                    StockAvailable::setProductDependsOnStock($product->id, $info['depends_on_stock'], null, $id_product_attribute);
                }
                // This code allows us to set qty and disable depends on stock
                if (isset($info['quantity']) && (int) $info['quantity']) {
                    // if depends on stock and quantity, add quantity to stock
                    if ($info['depends_on_stock'] == 1) {
                        $stock_manager = StockManagerFactory::getManager();
                        $price = str_replace(',', '.', $info['wholesale_price']);
                        if ($price == 0) {
                            $price = 1.0E-6;
                        }
                        $price = round(floatval($price), 6);
                        $warehouse = new Warehouse($info['warehouse']);
                        if (!$validateOnly && $stock_manager->addProduct((int) $product->id, $id_product_attribute, $warehouse, (int) $info['quantity'], 1, $price, true)) {
                            StockAvailable::synchronize((int) $product->id);
                        }
                    } elseif (!$validateOnly) {
                        if ($shop_is_feature_active) {
                            foreach ($id_shop_list as $shop) {
                                StockAvailable::setQuantity((int) $product->id, $id_product_attribute, (int) $info['quantity'], (int) $shop);
                            }
                        } else {
                            StockAvailable::setQuantity((int) $product->id, $id_product_attribute, (int) $info['quantity'], $this->context->shop->id);
                        }
                    }
                }
            } elseif (!$validateOnly) {
                // if not depends_on_stock set, use normal qty
                if ($shop_is_feature_active) {
                    foreach ($id_shop_list as $shop) {
                        StockAvailable::setQuantity((int) $product->id, $id_product_attribute, (int) $info['quantity'], (int) $shop);
                    }
                } else {
                    StockAvailable::setQuantity((int) $product->id, $id_product_attribute, (int) $info['quantity'], $this->context->shop->id);
                }
            }
        }
    }
Example #16
0
 /**
  * Get quantity for a given attribute combination
  * Check if quantity is enough to serve the customer
  *
  * @param int  $idProductAttribute Product attribute combination id
  * @param int  $qty                Quantity needed
  * @param Shop $shop               Shop
  *
  * @return bool Quantity is available or not
  */
 public static function checkAttributeQty($idProductAttribute, $qty, Shop $shop = null)
 {
     if (!$shop) {
         $shop = Context::getContext()->shop;
     }
     $result = StockAvailable::getQuantityAvailableByProduct(null, (int) $idProductAttribute, $shop->id);
     return $result && $qty <= $result;
 }
Example #17
0
 public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null)
 {
     if (self::DEBUG_MODE) {
         PrestaShopLogger::addLog('PaymentModule::validateOrder - Function called', 1, null, 'Cart', (int) $id_cart, true);
     }
     if (!isset($this->context)) {
         $this->context = Context::getContext();
     }
     $this->context->cart = new Cart($id_cart);
     $this->context->customer = new Customer($this->context->cart->id_customer);
     // The tax cart is loaded before the customer so re-cache the tax calculation method
     $this->context->cart->setTaxCalculationMethod();
     $this->context->language = new Language($this->context->cart->id_lang);
     $this->context->shop = $shop ? $shop : new Shop($this->context->cart->id_shop);
     ShopUrl::resetMainDomainCache();
     $id_currency = $currency_special ? (int) $currency_special : (int) $this->context->cart->id_currency;
     $this->context->currency = new Currency($id_currency, null, $this->context->shop->id);
     if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
         $context_country = $this->context->country;
     }
     $order_status = new OrderState((int) $id_order_state, (int) $this->context->language->id);
     if (!Validate::isLoadedObject($order_status)) {
         PrestaShopLogger::addLog('PaymentModule::validateOrder - Order Status cannot be loaded', 3, null, 'Cart', (int) $id_cart, true);
         throw new PrestaShopException('Can\'t load Order status');
     }
     if (!$this->active) {
         PrestaShopLogger::addLog('PaymentModule::validateOrder - Module is not active', 3, null, 'Cart', (int) $id_cart, true);
         die(Tools::displayError());
     }
     // Does order already exists ?
     if (Validate::isLoadedObject($this->context->cart) && $this->context->cart->OrderExists() == false) {
         if ($secure_key !== false && $secure_key != $this->context->cart->secure_key) {
             PrestaShopLogger::addLog('PaymentModule::validateOrder - Secure key does not match', 3, null, 'Cart', (int) $id_cart, true);
             die(Tools::displayError());
         }
         // For each package, generate an order
         $delivery_option_list = $this->context->cart->getDeliveryOptionList();
         $package_list = $this->context->cart->getPackageList();
         $cart_delivery_option = $this->context->cart->getDeliveryOption();
         // If some delivery options are not defined, or not valid, use the first valid option
         foreach ($delivery_option_list as $id_address => $package) {
             if (!isset($cart_delivery_option[$id_address]) || !array_key_exists($cart_delivery_option[$id_address], $package)) {
                 foreach ($package as $key => $val) {
                     $cart_delivery_option[$id_address] = $key;
                     break;
                 }
             }
         }
         $order_list = array();
         $order_detail_list = array();
         do {
             $reference = Order::generateReference();
         } while (Order::getByReference($reference)->count());
         $this->currentOrderReference = $reference;
         $order_creation_failed = false;
         $cart_total_paid = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(true, Cart::BOTH), 2);
         foreach ($cart_delivery_option as $id_address => $key_carriers) {
             foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data) {
                 foreach ($data['package_list'] as $id_package) {
                     // Rewrite the id_warehouse
                     $package_list[$id_address][$id_package]['id_warehouse'] = (int) $this->context->cart->getPackageIdWarehouse($package_list[$id_address][$id_package], (int) $id_carrier);
                     $package_list[$id_address][$id_package]['id_carrier'] = $id_carrier;
                 }
             }
         }
         // Make sure CartRule caches are empty
         CartRule::cleanCache();
         $cart_rules = $this->context->cart->getCartRules();
         foreach ($cart_rules as $cart_rule) {
             if (($rule = new CartRule((int) $cart_rule['obj']->id)) && Validate::isLoadedObject($rule)) {
                 if ($error = $rule->checkValidity($this->context, true, true)) {
                     $this->context->cart->removeCartRule((int) $rule->id);
                     if (isset($this->context->cookie) && isset($this->context->cookie->id_customer) && $this->context->cookie->id_customer && !empty($rule->code)) {
                         if (Configuration::get('PS_ORDER_PROCESS_TYPE') == 1) {
                             Tools::redirect('index.php?controller=order-opc&submitAddDiscount=1&discount_name=' . urlencode($rule->code));
                         }
                         Tools::redirect('index.php?controller=order&submitAddDiscount=1&discount_name=' . urlencode($rule->code));
                     } else {
                         $rule_name = isset($rule->name[(int) $this->context->cart->id_lang]) ? $rule->name[(int) $this->context->cart->id_lang] : $rule->code;
                         $error = Tools::displayError(sprintf('CartRule ID %1s (%2s) used in this cart is not valid and has been withdrawn from cart', (int) $rule->id, $rule_name));
                         PrestaShopLogger::addLog($error, 3, '0000002', 'Cart', (int) $this->context->cart->id);
                     }
                 }
             }
         }
         foreach ($package_list as $id_address => $packageByAddress) {
             foreach ($packageByAddress as $id_package => $package) {
                 $order = new Order();
                 $order->product_list = $package['product_list'];
                 if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
                     $address = new Address($id_address);
                     $this->context->country = new Country($address->id_country, $this->context->cart->id_lang);
                     if (!$this->context->country->active) {
                         throw new PrestaShopException('The delivery address country is not active.');
                     }
                 }
                 $carrier = null;
                 if (!$this->context->cart->isVirtualCart() && isset($package['id_carrier'])) {
                     $carrier = new Carrier($package['id_carrier'], $this->context->cart->id_lang);
                     $order->id_carrier = (int) $carrier->id;
                     $id_carrier = (int) $carrier->id;
                 } else {
                     $order->id_carrier = 0;
                     $id_carrier = 0;
                 }
                 $order->id_customer = (int) $this->context->cart->id_customer;
                 $order->id_address_invoice = (int) $this->context->cart->id_address_invoice;
                 $order->id_address_delivery = (int) $id_address;
                 $order->id_currency = $this->context->currency->id;
                 $order->id_lang = (int) $this->context->cart->id_lang;
                 $order->id_cart = (int) $this->context->cart->id;
                 $order->reference = $reference;
                 $order->id_shop = (int) $this->context->shop->id;
                 $order->id_shop_group = (int) $this->context->shop->id_shop_group;
                 $order->secure_key = $secure_key ? pSQL($secure_key) : pSQL($this->context->customer->secure_key);
                 $order->payment = $payment_method;
                 if (isset($this->name)) {
                     $order->module = $this->name;
                 }
                 $order->recyclable = $this->context->cart->recyclable;
                 $order->gift = (int) $this->context->cart->gift;
                 $order->gift_message = $this->context->cart->gift_message;
                 $order->mobile_theme = $this->context->cart->mobile_theme;
                 $order->conversion_rate = $this->context->currency->conversion_rate;
                 $amount_paid = !$dont_touch_amount ? Tools::ps_round((double) $amount_paid, 2) : $amount_paid;
                 $order->total_paid_real = 0;
                 $order->total_products = (double) $this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
                 $order->total_products_wt = (double) $this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
                 $order->total_discounts_tax_excl = (double) abs($this->context->cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
                 $order->total_discounts_tax_incl = (double) abs($this->context->cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
                 $order->total_discounts = $order->total_discounts_tax_incl;
                 $order->total_shipping_tax_excl = (double) $this->context->cart->getPackageShippingCost((int) $id_carrier, false, null, $order->product_list);
                 $order->total_shipping_tax_incl = (double) $this->context->cart->getPackageShippingCost((int) $id_carrier, true, null, $order->product_list);
                 $order->total_shipping = $order->total_shipping_tax_incl;
                 if (!is_null($carrier) && Validate::isLoadedObject($carrier)) {
                     $order->carrier_tax_rate = $carrier->getTaxesRate(new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
                 }
                 $order->total_wrapping_tax_excl = (double) abs($this->context->cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
                 $order->total_wrapping_tax_incl = (double) abs($this->context->cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
                 $order->total_wrapping = $order->total_wrapping_tax_incl;
                 $order->total_paid_tax_excl = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
                 $order->total_paid_tax_incl = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $id_carrier), _PS_PRICE_COMPUTE_PRECISION_);
                 $order->total_paid = $order->total_paid_tax_incl;
                 $order->round_mode = Configuration::get('PS_PRICE_ROUND_MODE');
                 $order->invoice_date = '0000-00-00 00:00:00';
                 $order->delivery_date = '0000-00-00 00:00:00';
                 if (self::DEBUG_MODE) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - Order is about to be added', 1, null, 'Cart', (int) $id_cart, true);
                 }
                 // Creating order
                 $result = $order->add();
                 if (!$result) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - Order cannot be created', 3, null, 'Cart', (int) $id_cart, true);
                     throw new PrestaShopException('Can\'t save Order');
                 }
                 // Amount paid by customer is not the right one -> Status = payment error
                 // We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
                 // if ($order->total_paid != $order->total_paid_real)
                 // We use number_format in order to compare two string
                 if ($order_status->logable && number_format($cart_total_paid, _PS_PRICE_COMPUTE_PRECISION_) != number_format($amount_paid, _PS_PRICE_COMPUTE_PRECISION_)) {
                     $id_order_state = Configuration::get('PS_OS_ERROR');
                 }
                 $order_list[] = $order;
                 if (self::DEBUG_MODE) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderDetail is about to be added', 1, null, 'Cart', (int) $id_cart, true);
                 }
                 // Insert new Order detail list using cart for the current order
                 $order_detail = new OrderDetail(null, null, $this->context);
                 $order_detail->createList($order, $this->context->cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
                 $order_detail_list[] = $order_detail;
                 if (self::DEBUG_MODE) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - OrderCarrier is about to be added', 1, null, 'Cart', (int) $id_cart, true);
                 }
                 // Adding an entry in order_carrier table
                 if (!is_null($carrier)) {
                     $order_carrier = new OrderCarrier();
                     $order_carrier->id_order = (int) $order->id;
                     $order_carrier->id_carrier = (int) $id_carrier;
                     $order_carrier->weight = (double) $order->getTotalWeight();
                     $order_carrier->shipping_cost_tax_excl = (double) $order->total_shipping_tax_excl;
                     $order_carrier->shipping_cost_tax_incl = (double) $order->total_shipping_tax_incl;
                     $order_carrier->add();
                 }
             }
         }
         // The country can only change if the address used for the calculation is the delivery address, and if multi-shipping is activated
         if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
             $this->context->country = $context_country;
         }
         if (!$this->context->country->active) {
             PrestaShopLogger::addLog('PaymentModule::validateOrder - Country is not active', 3, null, 'Cart', (int) $id_cart, true);
             throw new PrestaShopException('The order address country is not active.');
         }
         if (self::DEBUG_MODE) {
             PrestaShopLogger::addLog('PaymentModule::validateOrder - Payment is about to be added', 1, null, 'Cart', (int) $id_cart, true);
         }
         // Register Payment only if the order status validate the order
         if ($order_status->logable) {
             // $order is the last order loop in the foreach
             // The method addOrderPayment of the class Order make a create a paymentOrder
             //     linked to the order reference and not to the order id
             if (isset($extra_vars['transaction_id'])) {
                 $transaction_id = $extra_vars['transaction_id'];
             } else {
                 $transaction_id = null;
             }
             if (!$order->addOrderPayment($amount_paid, null, $transaction_id)) {
                 PrestaShopLogger::addLog('PaymentModule::validateOrder - Cannot save Order Payment', 3, null, 'Cart', (int) $id_cart, true);
                 throw new PrestaShopException('Can\'t save Order Payment');
             }
         }
         // Next !
         $only_one_gift = false;
         $cart_rule_used = array();
         $products = $this->context->cart->getProducts();
         // Make sure CarRule caches are empty
         CartRule::cleanCache();
         foreach ($order_detail_list as $key => $order_detail) {
             $order = $order_list[$key];
             if (!$order_creation_failed && isset($order->id)) {
                 if (!$secure_key) {
                     $message .= '<br />' . Tools::displayError('Warning: the secure key is empty, check your payment account before validation');
                 }
                 // Optional message to attach to this order
                 if (isset($message) & !empty($message)) {
                     $msg = new Message();
                     $message = strip_tags($message, '<br>');
                     if (Validate::isCleanHtml($message)) {
                         if (self::DEBUG_MODE) {
                             PrestaShopLogger::addLog('PaymentModule::validateOrder - Message is about to be added', 1, null, 'Cart', (int) $id_cart, true);
                         }
                         $msg->message = $message;
                         $msg->id_order = (int) $order->id;
                         $msg->private = 1;
                         $msg->add();
                     }
                 }
                 // Insert new Order detail list using cart for the current order
                 //$orderDetail = new OrderDetail(null, null, $this->context);
                 //$orderDetail->createList($order, $this->context->cart, $id_order_state);
                 // Construct order detail table for the email
                 $products_list = '';
                 $virtual_product = true;
                 $ppropertiessmartprice_hook1 = null;
                 $product_var_tpl_list = array();
                 foreach ($order->product_list as $product) {
                     PP::smartyPPAssign(array('cart' => $product, 'currency' => $this->context->currency));
                     $price = Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null, 6, null, false, true, array($product['cart_quantity'], $product['cart_quantity_fractional']), false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                     $price_wt = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null, 2, null, false, true, array($product['cart_quantity'], $product['cart_quantity_fractional']), false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                     $ppropertiessmartprice_hook2 = '';
                     $product_var_tpl = array('reference' => $product['reference'], 'name' => $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . PP::smartyDisplayProductName(array('name' => '')) . $ppropertiessmartprice_hook2, 'unit_price' => PP::smartyDisplayPrice(array('price' => Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt)), 'price' => PP::smartyDisplayPrice(array('price' => Product::getTaxCalculationMethod() == PS_TAX_EXC ? $product['total'] : $product['total_wt'], 'quantity' => (int) $product['cart_quantity'], 'm' => 'total')), 'quantity' => PP::smartyDisplayQty(array('quantity' => (int) $product['cart_quantity'])), 'customization' => array());
                     $customized_datas = Product::getAllCustomizedDatas((int) $order->id_cart);
                     $productHasCustomizedDatas = Product::hasCustomizedDatas($product, $customized_datas);
                     if ($productHasCustomizedDatas && isset($customized_datas[$product['id_product']][$product['id_product_attribute']])) {
                         $product_var_tpl['customization'] = array();
                         foreach ($customized_datas[$product['id_product']][$product['id_product_attribute']][$order->id_address_delivery] as $customization) {
                             if ($product['id_cart_product'] == $customization['id_cart_product']) {
                                 $customization_text = '';
                                 if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) {
                                     foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) {
                                         $customization_text .= $text['name'] . ': ' . $text['value'] . '<br />';
                                     }
                                 }
                                 if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) {
                                     $customization_text .= sprintf(Tools::displayError('%d image(s)'), count($customization['datas'][Product::CUSTOMIZE_FILE])) . '<br />';
                                 }
                                 $customization_quantity = (int) $product['customization_quantity'];
                                 $product_var_tpl['customization'][] = array('customization_text' => $customization_text, 'customization_quantity' => PP::smartyDisplayQty(array('quantity' => $customization_quantity)), 'quantity' => PP::smartyDisplayPrice(array('price' => Product::getTaxCalculationMethod() == PS_TAX_EXC ? $product['total_customization'] : $product['total_customization_wt'], 'm' => 'total')));
                             }
                         }
                     }
                     $product_var_tpl_list[] = $product_var_tpl;
                     // Check if is not a virutal product for the displaying of shipping
                     if (!$product['is_virtual']) {
                         $virtual_product &= false;
                     }
                 }
                 // end foreach ($products)
                 PP::smartyPPAssign();
                 $product_list_txt = '';
                 $product_list_html = '';
                 if (count($product_var_tpl_list) > 0) {
                     $product_list_txt = $this->getEmailTemplateContent('order_conf_product_list.txt', Mail::TYPE_TEXT, $product_var_tpl_list);
                     $product_list_html = $this->getEmailTemplateContent('order_conf_product_list.tpl', Mail::TYPE_HTML, $product_var_tpl_list);
                 }
                 $cart_rules_list = array();
                 $total_reduction_value_ti = 0;
                 $total_reduction_value_tex = 0;
                 foreach ($cart_rules as $cart_rule) {
                     $package = array('id_carrier' => $order->id_carrier, 'id_address' => $order->id_address_delivery, 'products' => $order->product_list);
                     $values = array('tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package), 'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package));
                     // If the reduction is not applicable to this order, then continue with the next one
                     if (!$values['tax_excl']) {
                         continue;
                     }
                     // IF
                     //     This is not multi-shipping
                     //     The value of the voucher is greater than the total of the order
                     //     Partial use is allowed
                     //     This is an "amount" reduction, not a reduction in % or a gift
                     // THEN
                     //     The voucher is cloned with a new value corresponding to the remainder
                     if (count($order_list) == 1 && $values['tax_incl'] > $order->total_products_wt - $total_reduction_value_ti && $cart_rule['obj']->partial_use == 1 && $cart_rule['obj']->reduction_amount > 0) {
                         // Create a new voucher from the original
                         $voucher = new CartRule($cart_rule['obj']->id);
                         // We need to instantiate the CartRule without lang parameter to allow saving it
                         unset($voucher->id);
                         // Set a new voucher code
                         $voucher->code = empty($voucher->code) ? Tools::substr(md5($order->id . '-' . $order->id_customer . '-' . $cart_rule['obj']->id), 0, 16) : $voucher->code . '-2';
                         if (preg_match('/\\-([0-9]{1,2})\\-([0-9]{1,2})$/', $voucher->code, $matches) && $matches[1] == $matches[2]) {
                             $voucher->code = preg_replace('/' . $matches[0] . '$/', '-' . (int) ($matches[1] + 1), $voucher->code);
                         }
                         // Set the new voucher value
                         if ($voucher->reduction_tax) {
                             $voucher->reduction_amount = $total_reduction_value_ti + $values['tax_incl'] - $order->total_products_wt;
                             // Add total shipping amout only if reduction amount > total shipping
                             if ($voucher->free_shipping == 1 && $voucher->reduction_amount >= $order->total_shipping_tax_incl) {
                                 $voucher->reduction_amount -= $order->total_shipping_tax_incl;
                             }
                         } else {
                             $voucher->reduction_amount = $total_reduction_value_tex + $values['tax_excl'] - $order->total_products;
                             // Add total shipping amout only if reduction amount > total shipping
                             if ($voucher->free_shipping == 1 && $voucher->reduction_amount >= $order->total_shipping_tax_excl) {
                                 $voucher->reduction_amount -= $order->total_shipping_tax_excl;
                             }
                         }
                         if ($voucher->reduction_amount <= 0) {
                             continue;
                         }
                         $voucher->id_customer = $order->id_customer;
                         $voucher->quantity = 1;
                         $voucher->quantity_per_user = 1;
                         $voucher->free_shipping = 0;
                         if ($voucher->add()) {
                             // If the voucher has conditions, they are now copied to the new voucher
                             CartRule::copyConditions($cart_rule['obj']->id, $voucher->id);
                             $params = array('{voucher_amount}' => Tools::displayPrice($voucher->reduction_amount, $this->context->currency, false), '{voucher_num}' => $voucher->code, '{firstname}' => $this->context->customer->firstname, '{lastname}' => $this->context->customer->lastname, '{id_order}' => $order->reference, '{order_name}' => $order->getUniqReference());
                             Mail::Send((int) $order->id_lang, 'voucher', sprintf(Mail::l('New voucher for your order %s', (int) $order->id_lang), $order->reference), $params, $this->context->customer->email, $this->context->customer->firstname . ' ' . $this->context->customer->lastname, null, null, null, null, _PS_MAIL_DIR_, false, (int) $order->id_shop);
                         }
                         $values['tax_incl'] = $order->total_products_wt - $total_reduction_value_ti;
                         $values['tax_excl'] = $order->total_products - $total_reduction_value_tex;
                     }
                     $total_reduction_value_ti += $values['tax_incl'];
                     $total_reduction_value_tex += $values['tax_excl'];
                     $order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values, 0, $cart_rule['obj']->free_shipping);
                     if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && !in_array($cart_rule['obj']->id, $cart_rule_used)) {
                         $cart_rule_used[] = $cart_rule['obj']->id;
                         // Create a new instance of Cart Rule without id_lang, in order to update its quantity
                         $cart_rule_to_update = new CartRule($cart_rule['obj']->id);
                         $cart_rule_to_update->quantity = max(0, $cart_rule_to_update->quantity - 1);
                         $cart_rule_to_update->update();
                     }
                     $cart_rules_list[] = array('voucher_name' => $cart_rule['obj']->name, 'voucher_reduction' => ($values['tax_incl'] != 0.0 ? '-' : '') . Tools::displayPrice($values['tax_incl'], $this->context->currency, false));
                 }
                 $cart_rules_list_txt = '';
                 $cart_rules_list_html = '';
                 if (count($cart_rules_list) > 0) {
                     $cart_rules_list_txt = $this->getEmailTemplateContent('order_conf_cart_rules.txt', Mail::TYPE_TEXT, $cart_rules_list);
                     $cart_rules_list_html = $this->getEmailTemplateContent('order_conf_cart_rules.tpl', Mail::TYPE_HTML, $cart_rules_list);
                 }
                 // Specify order id for message
                 $old_message = Message::getMessageByCartId((int) $this->context->cart->id);
                 if ($old_message) {
                     $update_message = new Message((int) $old_message['id_message']);
                     $update_message->id_order = (int) $order->id;
                     $update_message->update();
                     // Add this message in the customer thread
                     $customer_thread = new CustomerThread();
                     $customer_thread->id_contact = 0;
                     $customer_thread->id_customer = (int) $order->id_customer;
                     $customer_thread->id_shop = (int) $this->context->shop->id;
                     $customer_thread->id_order = (int) $order->id;
                     $customer_thread->id_lang = (int) $this->context->language->id;
                     $customer_thread->email = $this->context->customer->email;
                     $customer_thread->status = 'open';
                     $customer_thread->token = Tools::passwdGen(12);
                     $customer_thread->add();
                     $customer_message = new CustomerMessage();
                     $customer_message->id_customer_thread = $customer_thread->id;
                     $customer_message->id_employee = 0;
                     $customer_message->message = $update_message->message;
                     $customer_message->private = 0;
                     if (!$customer_message->add()) {
                         $this->errors[] = Tools::displayError('An error occurred while saving message');
                     }
                 }
                 if (self::DEBUG_MODE) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - Hook validateOrder is about to be called', 1, null, 'Cart', (int) $id_cart, true);
                 }
                 // Hook validate order
                 Hook::exec('actionValidateOrder', array('cart' => $this->context->cart, 'order' => $order, 'customer' => $this->context->customer, 'currency' => $this->context->currency, 'orderStatus' => $order_status));
                 foreach ($this->context->cart->getProducts() as $product) {
                     if ($order_status->logable) {
                         ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']);
                     }
                 }
                 if (self::DEBUG_MODE) {
                     PrestaShopLogger::addLog('PaymentModule::validateOrder - Order Status is about to be added', 1, null, 'Cart', (int) $id_cart, true);
                 }
                 // Set the order status
                 $new_history = new OrderHistory();
                 $new_history->id_order = (int) $order->id;
                 $new_history->changeIdOrderState((int) $id_order_state, $order, true);
                 $new_history->addWithemail(true, $extra_vars);
                 // Switch to back order if needed
                 if (Configuration::get('PS_STOCK_MANAGEMENT') && $order_detail->getStockState()) {
                     $history = new OrderHistory();
                     $history->id_order = (int) $order->id;
                     $history->changeIdOrderState(Configuration::get($order->valid ? 'PS_OS_OUTOFSTOCK_PAID' : 'PS_OS_OUTOFSTOCK_UNPAID'), $order, true);
                     $history->addWithemail();
                 }
                 unset($order_detail);
                 // Order is reloaded because the status just changed
                 $order = new Order($order->id);
                 // Send an e-mail to customer (one order = one email)
                 if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && $this->context->customer->id) {
                     $invoice = new Address($order->id_address_invoice);
                     $delivery = new Address($order->id_address_delivery);
                     $delivery_state = $delivery->id_state ? new State($delivery->id_state) : false;
                     $invoice_state = $invoice->id_state ? new State($invoice->id_state) : false;
                     $data = array('{firstname}' => $this->context->customer->firstname, '{lastname}' => $this->context->customer->lastname, '{email}' => $this->context->customer->email, '{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"), '{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"), '{delivery_block_html}' => $this->_getFormatedAddress($delivery, '<br />', array('firstname' => '<span style="font-weight:bold;">%s</span>', 'lastname' => '<span style="font-weight:bold;">%s</span>')), '{invoice_block_html}' => $this->_getFormatedAddress($invoice, '<br />', array('firstname' => '<span style="font-weight:bold;">%s</span>', 'lastname' => '<span style="font-weight:bold;">%s</span>')), '{delivery_company}' => $delivery->company, '{delivery_firstname}' => $delivery->firstname, '{delivery_lastname}' => $delivery->lastname, '{delivery_address1}' => $delivery->address1, '{delivery_address2}' => $delivery->address2, '{delivery_city}' => $delivery->city, '{delivery_postal_code}' => $delivery->postcode, '{delivery_country}' => $delivery->country, '{delivery_state}' => $delivery->id_state ? $delivery_state->name : '', '{delivery_phone}' => $delivery->phone ? $delivery->phone : $delivery->phone_mobile, '{delivery_other}' => $delivery->other, '{invoice_company}' => $invoice->company, '{invoice_vat_number}' => $invoice->vat_number, '{invoice_firstname}' => $invoice->firstname, '{invoice_lastname}' => $invoice->lastname, '{invoice_address2}' => $invoice->address2, '{invoice_address1}' => $invoice->address1, '{invoice_city}' => $invoice->city, '{invoice_postal_code}' => $invoice->postcode, '{invoice_country}' => $invoice->country, '{invoice_state}' => $invoice->id_state ? $invoice_state->name : '', '{invoice_phone}' => $invoice->phone ? $invoice->phone : $invoice->phone_mobile, '{invoice_other}' => $invoice->other, '{order_name}' => $order->getUniqReference(), '{date}' => Tools::displayDate(date('Y-m-d H:i:s'), null, 1), '{carrier}' => $virtual_product || !isset($carrier->name) ? Tools::displayError('No carrier') : $carrier->name, '{payment}' => Tools::substr($order->payment, 0, 32), '{products}' => $product_list_html, '{products_txt}' => $product_list_txt, '{discounts}' => $cart_rules_list_html, '{discounts_txt}' => $cart_rules_list_txt, '{total_paid}' => Tools::displayPrice($order->total_paid, $this->context->currency, false), '{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_wrapping + $order->total_discounts, $this->context->currency, false), '{total_discounts}' => Tools::displayPrice($order->total_discounts, $this->context->currency, false), '{total_shipping}' => Tools::displayPrice($order->total_shipping, $this->context->currency, false), '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $this->context->currency, false), '{total_tax_paid}' => Tools::displayPrice($order->total_products_wt - $order->total_products + ($order->total_shipping_tax_incl - $order->total_shipping_tax_excl), $this->context->currency, false));
                     if (is_array($extra_vars)) {
                         $data = array_merge($data, $extra_vars);
                     }
                     // Join PDF invoice
                     if ((int) Configuration::get('PS_INVOICE') && $order_status->invoice && $order->invoice_number) {
                         $pdf = new PDF($order->getInvoicesCollection(), PDF::TEMPLATE_INVOICE, $this->context->smarty);
                         $file_attachement = array();
                         $file_attachement['content'] = $pdf->render(false);
                         $file_attachement['name'] = Configuration::get('PS_INVOICE_PREFIX', (int) $order->id_lang, null, $order->id_shop) . sprintf('%06d', $order->invoice_number) . '.pdf';
                         $file_attachement['mime'] = 'application/pdf';
                     } else {
                         $file_attachement = null;
                     }
                     if (self::DEBUG_MODE) {
                         PrestaShopLogger::addLog('PaymentModule::validateOrder - Mail is about to be sent', 1, null, 'Cart', (int) $id_cart, true);
                     }
                     if (Validate::isEmail($this->context->customer->email)) {
                         Mail::Send((int) $order->id_lang, 'order_conf', Mail::l('Order confirmation', (int) $order->id_lang), $data, $this->context->customer->email, $this->context->customer->firstname . ' ' . $this->context->customer->lastname, null, null, $file_attachement, null, _PS_MAIL_DIR_, false, (int) $order->id_shop);
                     }
                 }
                 // updates stock in shops
                 if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                     $product_list = $order->getProducts();
                     foreach ($product_list as $product) {
                         // if the available quantities depends on the physical stock
                         if (StockAvailable::dependsOnStock($product['product_id'])) {
                             // synchronizes
                             StockAvailable::synchronize($product['product_id'], $order->id_shop);
                         }
                     }
                 }
             } else {
                 $error = Tools::displayError('Order creation failed');
                 PrestaShopLogger::addLog($error, 4, '0000002', 'Cart', (int) $order->id_cart);
                 die($error);
             }
         }
         // End foreach $order_detail_list
         // Update Order Details Tax in case cart rules have free shipping
         foreach ($order->getOrderDetailList() as $detail) {
             $order_detail = new OrderDetail($detail['id_order_detail']);
             $order_detail->updateTaxAmount($order);
         }
         // Use the last order as currentOrder
         if (isset($order) && $order->id) {
             $this->currentOrder = (int) $order->id;
         }
         if (self::DEBUG_MODE) {
             PrestaShopLogger::addLog('PaymentModule::validateOrder - End of validateOrder', 1, null, 'Cart', (int) $id_cart, true);
         }
         return true;
     } else {
         $error = Tools::displayError('Cart cannot be loaded or an order has already been placed using this cart');
         PrestaShopLogger::addLog($error, 4, '0000001', 'Cart', (int) $this->context->cart->id);
         die($error);
     }
 }
Example #18
0
 public function hookBeforeCarrier($params)
 {
     if (!isset($params['delivery_option_list']) || !count($params['delivery_option_list'])) {
         return false;
     }
     $package_list = $params['cart']->getPackageList();
     $datesDelivery = array();
     foreach ($params['delivery_option_list'] as $id_address => $by_address) {
         $datesDelivery[$id_address] = array();
         foreach ($by_address as $key => $delivery_option) {
             $date_from = null;
             $date_to = null;
             $datesDelivery[$id_address][$key] = array();
             foreach ($delivery_option['carrier_list'] as $id_carrier => $carrier) {
                 foreach ($carrier['package_list'] as $id_package) {
                     $package = $package_list[$id_address][$id_package];
                     $oos = false;
                     // For out of stock management
                     foreach ($package['product_list'] as $product) {
                         if (StockAvailable::getQuantityAvailableByProduct($product['id_product'], $product['id_product_attribute']) <= 0) {
                             $oos = true;
                             break;
                         }
                     }
                     $date_range = $this->_getDatesOfDelivery($id_carrier, $oos);
                     if (is_null($date_from) || $date_from < $date_range[0]) {
                         $date_from = $date_range[0][1];
                         $datesDelivery[$id_address][$key][0] = $date_range[0];
                     }
                     if (is_null($date_to) || $date_to < $date_range[1]) {
                         $date_to = $date_range[1][1];
                         $datesDelivery[$id_address][$key][1] = $date_range[1];
                     }
                 }
             }
         }
     }
     $this->smarty->assign(array('nbPackages' => $params['cart']->getNbOfPackages(), 'datesDelivery' => $datesDelivery, 'delivery_option' => $params['delivery_option']));
     return $this->display(__FILE__, 'beforeCarrier.tpl');
 }
 protected function afterUpdate($new_shop_group)
 {
     //Reset available quantitites
     StockAvailable::resetProductFromStockAvailableByShopGroup($new_shop_group);
 }
Example #20
0
 public function ajaxProcessProductQuantity()
 {
     if (!Tools::getValue('actionQty')) {
         return Tools::jsonEncode(array('error' => $this->l('Undefined action')));
     }
     $product = new Product((int) Tools::getValue('id_product'), true);
     switch (Tools::getValue('actionQty')) {
         case 'depends_on_stock':
             if (Tools::getValue('value') === false) {
                 die(Tools::jsonEncode(array('error' => $this->l('Undefined value'))));
             }
             if ((int) Tools::getValue('value') != 0 && (int) Tools::getValue('value') != 1) {
                 die(Tools::jsonEncode(array('error' => $this->l('Incorrect value'))));
             }
             if (!$product->advanced_stock_management && (int) Tools::getValue('value') == 1) {
                 die(Tools::jsonEncode(array('error' => $this->l('Not possible if advanced stock management is disabled. '))));
             }
             if ($product->advanced_stock_management && Pack::isPack($product->id)) {
                 die(Tools::jsonEncode(array('error' => $this->l('Not possible if the product is a pack.'))));
             }
             StockAvailable::setProductDependsOnStock($product->id, (int) Tools::getValue('value'));
             break;
         case 'out_of_stock':
             if (Tools::getValue('value') === false) {
                 die(Tools::jsonEncode(array('error' => $this->l('Undefined value'))));
             }
             if (!in_array((int) Tools::getValue('value'), array(0, 1, 2))) {
                 die(Tools::jsonEncode(array('error' => $this->l('Incorrect value'))));
             }
             StockAvailable::setProductOutOfStock($product->id, (int) Tools::getValue('value'));
             break;
         case 'set_qty':
             if (Tools::getValue('value') === false || !is_numeric(trim(Tools::getValue('value')))) {
                 die(Tools::jsonEncode(array('error' => $this->l('Undefined value'))));
             }
             if (Tools::getValue('id_product_attribute') === false) {
                 die(Tools::jsonEncode(array('error' => $this->l('Undefined id product attribute'))));
             }
             StockAvailable::setQuantity($product->id, (int) Tools::getValue('id_product_attribute'), (int) Tools::getValue('value'));
             Hook::exec('actionProductUpdate', array('product' => $this->object));
             // Catch potential echo from modules
             $error = ob_get_contents();
             if (!empty($error)) {
                 ob_end_clean();
                 die(Tools::jsonEncode(array('error' => $error)));
             }
             break;
         case 'advanced_stock_management':
             if (Tools::getValue('value') === false) {
                 die(Tools::jsonEncode(array('error' => $this->l('Undefined value'))));
             }
             if ((int) Tools::getValue('value') != 1 && (int) Tools::getValue('value') != 0) {
                 die(Tools::jsonEncode(array('error' => $this->l('Incorrect value'))));
             }
             if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int) Tools::getValue('value') == 1) {
                 die(Tools::jsonEncode(array('error' => $this->l('Not possible if advanced stock management is disabled. '))));
             }
             if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && Pack::isPack($product->id)) {
                 die(Tools::jsonEncode(array('error' => $this->l('Not possible if the product is a pack.'))));
             }
             $product->setAdvancedStockManagement((int) Tools::getValue('value'));
             if (StockAvailable::dependsOnStock($product->id) == 1 && (int) Tools::getValue('value') == 0) {
                 StockAvailable::setProductDependsOnStock($product->id, 0);
             }
             break;
     }
     die(Tools::jsonEncode(array('error' => false)));
 }
 protected function reinjectQuantity($order_detail, $qty_cancel_product, $delete = false)
 {
     // Reinject product
     $reinjectable_quantity = (int) $order_detail->product_quantity - (int) $order_detail->product_quantity_reinjected;
     $quantity_to_reinject = $qty_cancel_product > $reinjectable_quantity ? $reinjectable_quantity : $qty_cancel_product;
     // @since 1.5.0 : Advanced Stock Management
     $product_to_inject = new Product($order_detail->product_id, false, (int) $this->context->language->id, (int) $order_detail->id_shop);
     $product = new Product($order_detail->product_id, false, (int) $this->context->language->id, (int) $order_detail->id_shop);
     if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $product->advanced_stock_management && $order_detail->id_warehouse != 0) {
         $manager = StockManagerFactory::getManager();
         $movements = StockMvt::getNegativeStockMvts($order_detail->id_order, $order_detail->product_id, $order_detail->product_attribute_id, $quantity_to_reinject);
         $left_to_reinject = $quantity_to_reinject;
         foreach ($movements as $movement) {
             if ($left_to_reinject > $movement['physical_quantity']) {
                 $quantity_to_reinject = $movement['physical_quantity'];
             }
             $left_to_reinject -= $quantity_to_reinject;
             if (Pack::isPack((int) $product->id)) {
                 // Gets items
                 if ($product->pack_stock_type == 1 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && Configuration::get('PS_PACK_STOCK_TYPE') > 0) {
                     $products_pack = Pack::getItems((int) $product->id, (int) Configuration::get('PS_LANG_DEFAULT'));
                     // Foreach item
                     foreach ($products_pack as $product_pack) {
                         if ($product_pack->advanced_stock_management == 1) {
                             $manager->addProduct($product_pack->id, $product_pack->id_pack_product_attribute, new Warehouse($movement['id_warehouse']), $product_pack->pack_quantity * $quantity_to_reinject, null, $movement['price_te'], true);
                         }
                     }
                 }
                 if ($product->pack_stock_type == 0 || $product->pack_stock_type == 2 || $product->pack_stock_type == 3 && (Configuration::get('PS_PACK_STOCK_TYPE') == 0 || Configuration::get('PS_PACK_STOCK_TYPE') == 2)) {
                     $manager->addProduct($order_detail->product_id, $order_detail->product_attribute_id, new Warehouse($movement['id_warehouse']), $quantity_to_reinject, null, $movement['price_te'], true);
                 }
             } else {
                 $manager->addProduct($order_detail->product_id, $order_detail->product_attribute_id, new Warehouse($movement['id_warehouse']), $quantity_to_reinject, null, $movement['price_te'], true);
             }
         }
         $id_product = $order_detail->product_id;
         if ($delete) {
             $order_detail->delete();
         }
         StockAvailable::synchronize($id_product);
     } elseif ($order_detail->id_warehouse == 0) {
         StockAvailable::updateQuantity($order_detail->product_id, $order_detail->product_attribute_id, $quantity_to_reinject, $order_detail->id_shop);
         if ($delete) {
             $order_detail->delete();
         }
     } else {
         $this->errors[] = Tools::displayError('This product cannot be re-stocked.');
     }
 }
Example #22
0
 public function checkQuantities($return_product = false)
 {
     if (Configuration::get('PS_CATALOG_MODE') && !defined('_PS_ADMIN_DIR_')) {
         return false;
     }
     foreach ($this->getProducts() as $product) {
         if (!$this->allow_seperated_package && !$product['allow_oosp'] && StockAvailable::dependsOnStock($product['id_product']) && $product['advanced_stock_management'] && (bool) Context::getContext()->customer->isLogged() && ($delivery = $this->getDeliveryOption()) && !empty($delivery)) {
             $product['stock_quantity'] = StockManager::getStockByCarrier((int) $product['id_product'], (int) $product['id_product_attribute'], $delivery);
         }
         if (!$product['active'] || !$product['available_for_order'] || !$product['allow_oosp'] && $product['stock_quantity'] < $product['cart_quantity']) {
             return $return_product ? $product : false;
         }
     }
     return true;
 }
Example #23
0
 /**
  * Get products grouped by package and by addresses to be sent individualy (one package = one shipping cost).
  *
  * @return array array(
  *                   0 => array( // First address
  *                       0 => array(  // First package
  *                           'product_list' => array(...),
  *                           'carrier_list' => array(...),
  *                           'id_warehouse' => array(...),
  *                       ),
  *                   ),
  *               );
  * @todo Add avaibility check
  */
 public function getPackageList($flush = false)
 {
     static $cache = array();
     if (isset($cache[(int) $this->id . '_' . (int) $this->id_address_delivery]) && $cache[(int) $this->id . '_' . (int) $this->id_address_delivery] !== false && !$flush) {
         return $cache[(int) $this->id . '_' . (int) $this->id_address_delivery];
     }
     $product_list = $this->getProducts();
     // Step 1 : Get product informations (warehouse_list and carrier_list), count warehouse
     // Determine the best warehouse to determine the packages
     // For that we count the number of time we can use a warehouse for a specific delivery address
     $warehouse_count_by_address = array();
     $warehouse_carrier_list = array();
     $stock_management_active = Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT');
     foreach ($product_list as &$product) {
         if ((int) $product['id_address_delivery'] == 0) {
             $product['id_address_delivery'] = (int) $this->id_address_delivery;
         }
         if (!isset($warehouse_count_by_address[$product['id_address_delivery']])) {
             $warehouse_count_by_address[$product['id_address_delivery']] = array();
         }
         $product['warehouse_list'] = array();
         if ($stock_management_active && ((int) $product['advanced_stock_management'] == 1 || Pack::usesAdvancedStockManagement((int) $product['id_product']))) {
             $warehouse_list = Warehouse::getProductWarehouseList($product['id_product'], $product['id_product_attribute'], $this->id_shop);
             if (count($warehouse_list) == 0) {
                 $warehouse_list = Warehouse::getProductWarehouseList($product['id_product'], $product['id_product_attribute']);
             }
             // Does the product is in stock ?
             // If yes, get only warehouse where the product is in stock
             $warehouse_in_stock = array();
             $manager = StockManagerFactory::getManager();
             foreach ($warehouse_list as $key => $warehouse) {
                 $product_real_quantities = $manager->getProductRealQuantities($product['id_product'], $product['id_product_attribute'], array($warehouse['id_warehouse']), true);
                 if ($product_real_quantities > 0 || Pack::isPack((int) $product['id_product'])) {
                     $warehouse_in_stock[] = $warehouse;
                 }
             }
             if (!empty($warehouse_in_stock)) {
                 $warehouse_list = $warehouse_in_stock;
                 $product['in_stock'] = true;
             } else {
                 $product['in_stock'] = false;
             }
         } else {
             //simulate default warehouse
             $warehouse_list = array(0);
             $product['in_stock'] = StockAvailable::getQuantityAvailableByProduct($product['id_product'], $product['id_product_attribute']) > 0;
         }
         foreach ($warehouse_list as $warehouse) {
             if (!isset($warehouse_carrier_list[$warehouse['id_warehouse']])) {
                 $warehouse_object = new Warehouse($warehouse['id_warehouse']);
                 $warehouse_carrier_list[$warehouse['id_warehouse']] = $warehouse_object->getCarriers();
             }
             $product['warehouse_list'][] = $warehouse['id_warehouse'];
             if (!isset($warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']])) {
                 $warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']] = 0;
             }
             $warehouse_count_by_address[$product['id_address_delivery']][$warehouse['id_warehouse']]++;
         }
     }
     unset($product);
     arsort($warehouse_count_by_address);
     // Step 2 : Group product by warehouse
     $grouped_by_warehouse = array();
     foreach ($product_list as &$product) {
         if (!isset($grouped_by_warehouse[$product['id_address_delivery']])) {
             $grouped_by_warehouse[$product['id_address_delivery']] = array('in_stock' => array(), 'out_of_stock' => array());
         }
         $product['carrier_list'] = array();
         $id_warehouse = 0;
         foreach ($warehouse_count_by_address[$product['id_address_delivery']] as $id_war => $val) {
             if (in_array((int) $id_war, $product['warehouse_list'])) {
                 $product['carrier_list'] = array_merge($product['carrier_list'], Carrier::getAvailableCarrierList(new Product($product['id_product']), $id_war, $product['id_address_delivery'], null, $this));
                 if (!$id_warehouse) {
                     $id_warehouse = (int) $id_war;
                 }
             }
         }
         if (!isset($grouped_by_warehouse[$product['id_address_delivery']]['in_stock'][$id_warehouse])) {
             $grouped_by_warehouse[$product['id_address_delivery']]['in_stock'][$id_warehouse] = array();
             $grouped_by_warehouse[$product['id_address_delivery']]['out_of_stock'][$id_warehouse] = array();
         }
         if (!$this->allow_seperated_package) {
             $key = 'in_stock';
         } else {
             $key = $product['in_stock'] ? 'in_stock' : 'out_of_stock';
         }
         if (empty($product['carrier_list'])) {
             $product['carrier_list'] = array(0);
         }
         $grouped_by_warehouse[$product['id_address_delivery']][$key][$id_warehouse][] = $product;
     }
     unset($product);
     // Step 3 : grouped product from grouped_by_warehouse by available carriers
     $grouped_by_carriers = array();
     foreach ($grouped_by_warehouse as $id_address_delivery => $products_in_stock_list) {
         if (!isset($grouped_by_carriers[$id_address_delivery])) {
             $grouped_by_carriers[$id_address_delivery] = array('in_stock' => array(), 'out_of_stock' => array());
         }
         foreach ($products_in_stock_list as $key => $warehouse_list) {
             if (!isset($grouped_by_carriers[$id_address_delivery][$key])) {
                 $grouped_by_carriers[$id_address_delivery][$key] = array();
             }
             foreach ($warehouse_list as $id_warehouse => $product_list) {
                 if (!isset($grouped_by_carriers[$id_address_delivery][$key][$id_warehouse])) {
                     $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse] = array();
                 }
                 foreach ($product_list as $product) {
                     $package_carriers_key = implode(',', $product['carrier_list']);
                     if (!isset($grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key])) {
                         $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key] = array('product_list' => array(), 'carrier_list' => $product['carrier_list'], 'warehouse_list' => $product['warehouse_list']);
                     }
                     $grouped_by_carriers[$id_address_delivery][$key][$id_warehouse][$package_carriers_key]['product_list'][] = $product;
                 }
             }
         }
     }
     $package_list = array();
     // Step 4 : merge product from grouped_by_carriers into $package to minimize the number of package
     foreach ($grouped_by_carriers as $id_address_delivery => $products_in_stock_list) {
         if (!isset($package_list[$id_address_delivery])) {
             $package_list[$id_address_delivery] = array('in_stock' => array(), 'out_of_stock' => array());
         }
         foreach ($products_in_stock_list as $key => $warehouse_list) {
             if (!isset($package_list[$id_address_delivery][$key])) {
                 $package_list[$id_address_delivery][$key] = array();
             }
             // Count occurance of each carriers to minimize the number of packages
             $carrier_count = array();
             foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) {
                 foreach ($products_grouped_by_carriers as $data) {
                     foreach ($data['carrier_list'] as $id_carrier) {
                         if (!isset($carrier_count[$id_carrier])) {
                             $carrier_count[$id_carrier] = 0;
                         }
                         $carrier_count[$id_carrier]++;
                     }
                 }
             }
             arsort($carrier_count);
             foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) {
                 if (!isset($package_list[$id_address_delivery][$key][$id_warehouse])) {
                     $package_list[$id_address_delivery][$key][$id_warehouse] = array();
                 }
                 foreach ($products_grouped_by_carriers as $data) {
                     foreach ($carrier_count as $id_carrier => $rate) {
                         if (in_array($id_carrier, $data['carrier_list'])) {
                             if (!isset($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier])) {
                                 $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier] = array('carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'product_list' => array());
                             }
                             $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['carrier_list'] = array_intersect($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['carrier_list'], $data['carrier_list']);
                             $package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['product_list'] = array_merge($package_list[$id_address_delivery][$key][$id_warehouse][$id_carrier]['product_list'], $data['product_list']);
                             break;
                         }
                     }
                 }
             }
         }
     }
     // Step 5 : Reduce depth of $package_list
     $final_package_list = array();
     foreach ($package_list as $id_address_delivery => $products_in_stock_list) {
         if (!isset($final_package_list[$id_address_delivery])) {
             $final_package_list[$id_address_delivery] = array();
         }
         foreach ($products_in_stock_list as $key => $warehouse_list) {
             foreach ($warehouse_list as $id_warehouse => $products_grouped_by_carriers) {
                 foreach ($products_grouped_by_carriers as $data) {
                     $final_package_list[$id_address_delivery][] = array('product_list' => $data['product_list'], 'carrier_list' => $data['carrier_list'], 'warehouse_list' => $data['warehouse_list'], 'id_warehouse' => $id_warehouse);
                 }
             }
         }
     }
     $cache[(int) $this->id] = $final_package_list;
     return $final_package_list;
 }
    /**
     * Creating order details of order
     * @param $neteven_order
     * @param $id_order
     * @return mixed
     */
    private function createOrderDetails($neteven_order, $id_order)
    {
        global $cookie;
        $date_now = date('Y-m-d H:i:s');
        if (in_array($neteven_order->Status, $this->getValue('t_list_order_status'))) {
            return;
        }
        // If order detail doesn't exist
        if (!($res = Db::getInstance()->getRow('SELECT * FROM `' . _DB_PREFIX_ . 'orders_gateway` WHERE `id_order_neteven` = ' . (int) $neteven_order->OrderID . ' AND `id_order_detail_neteven` = ' . (int) $neteven_order->OrderLineID))) {
            // If product exist
            $ref_temp = $neteven_order->SKU;
            $type_temp = substr($ref_temp, 0, 1);
            $id_p_temp = str_replace($type_temp, '', $ref_temp);
            $where_req = '';
            if ($type_temp == 'D') {
                $where_req = 'pa.`id_product_attribute` = ' . (int) $id_p_temp;
            }
            if ($type_temp == 'P') {
                $where_req = 'p.`id_product` = ' . (int) $id_p_temp;
            }
            if (self::$type_sku == 'reference') {
                $where_req = ' (p.`reference` = "' . pSQL($ref_temp) . '" OR pa.`reference` = "' . pSQL($ref_temp) . '") ';
            }
            if (empty($where_req)) {
                return;
            }
            $res_product = Db::getInstance()->getRow('
					SELECT pl.`name` as name_product, p.`id_product`, pa.`id_product_attribute`, p.`reference` as product_reference, pa.`reference` as product_attribute_reference, p.`weight` as weight, GROUP_CONCAT(CONCAT(agl.`name`," : ",al.`name`) SEPARATOR ", ") as attribute_name
					FROM `' . _DB_PREFIX_ . 'product` p
					INNER JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON(p.`id_product` = pl.`id_product` AND pl.`id_lang` = ' . (int) $this->getValue('id_lang') . ')
					LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON (pa.`id_product` = p.`id_product`)
					LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute_combination` pac ON (pac.`id_product_attribute`=pa.`id_product_attribute`)
					LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a ON (a.`id_attribute`=pac.`id_attribute`)
					LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al ON (al.`id_attribute`=a.`id_attribute` AND al.`id_lang`=' . (int) $this->getValue('id_lang') . ')
					LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl ON (agl.`id_attribute_group`=a.`id_attribute_group` AND agl.`id_lang`=' . (int) $this->getValue('id_lang') . ')
					WHERE p.`active` = 1 AND ' . $where_req . '
					GROUP BY pa.`id_product_attribute`, p.`id_product`
				');
            if ($res_product) {
                // Get order detail informations
                $product_reference = $res_product['product_reference'];
                $id_product_attribute = 0;
                $name = $res_product['name_product'];
                $control_attribute_product = false;
                if (!empty($res_product['id_product_attribute'])) {
                    $product_reference = $res_product['product_attribute_reference'];
                    $id_product_attribute = $res_product['id_product_attribute'];
                    if (!empty($res_product['attribute_name'])) {
                        $name .= ' - ' . $res_product['attribute_name'];
                    }
                    $control_attribute_product = true;
                }
                // Add product in cart
                $order = new Order($id_order);
                if (!Db::getInstance()->getRow('SELECT `id_cart` FROM `' . _DB_PREFIX_ . 'cart_product` WHERE `id_cart` = ' . (int) $order->id_cart . ' AND `id_product` = ' . (int) $res_product['id_product'] . ' AND `id_product_attribute` = ' . (int) $id_product_attribute)) {
                    Db::getInstance()->Execute('INSERT INTO `' . _DB_PREFIX_ . 'cart_product` (`id_cart`, `id_product`, `id_product_attribute`, `quantity`, `date_add`) VALUES (' . (int) $order->id_cart . ', ' . (int) $res_product['id_product'] . ', ' . (int) $id_product_attribute . ', ' . (int) $neteven_order->Quantity . ', "' . pSQL($date_now) . '")');
                }
                if ($this->time_analyse) {
                    $this->current_time_0 = time();
                    Toolbox::displayDebugMessage(self::getL('Order information') . ' : ' . ((int) $this->current_time_0 - (int) $this->current_time_2) . 's');
                }
                // Add order detail
                $tax = new Tax(Configuration::get('PS_TAX'), $cookie->id_lang);
                $price_product = ($neteven_order->Price->_ - floatval($neteven_order->VAT->_)) / $neteven_order->Quantity;
                $order_detail = new OrderDetail();
                $order_detail->id_order = $id_order;
                $order_detail->product_id = $res_product['id_product'];
                $order_detail->product_attribute_id = $id_product_attribute;
                $order_detail->product_name = $name;
                $order_detail->product_quantity = $neteven_order->Quantity;
                $order_detail->product_quantity_in_stock = $neteven_order->Quantity;
                $order_detail->product_quantity_refunded = 0;
                $order_detail->product_quantity_return = 0;
                $order_detail->product_quantity_reinjected = 0;
                $order_detail->product_price = number_format((double) $price_product, 4, '.', '');
                $order_detail->total_price_tax_excl = number_format((double) $price_product, 4, '.', '');
                $order_detail->unit_price_tax_incl = number_format((double) $price_product, 4, '.', '');
                $order_detail->unit_price_tax_excl = $tax->rate ? number_format((double) $price_product / ((double) $tax->rate / 100), 4, '.', '') : $price_product;
                $order_detail->reduction_percent = 0;
                $order_detail->reduction_amount = 0;
                $order_detail->group_reduction = 0;
                $order_detail->product_quantity_discount = 0;
                $order_detail->product_ean13 = NULL;
                $order_detail->product_upc = NULL;
                $order_detail->product_reference = $product_reference;
                $order_detail->product_supplier_reference = NULL;
                $order_detail->product_weight = !empty($res_product['weight']) ? (double) $res_product['weight'] : 0;
                $order_detail->tax_name = $tax->name;
                $order_detail->tax_rate = (double) $tax->rate;
                $order_detail->ecotax = 0;
                $order_detail->ecotax_tax_rate = 0;
                $order_detail->discount_quantity_applied = 0;
                $order_detail->download_hash = '';
                $order_detail->download_nb = 0;
                $order_detail->download_deadline = '0000-00-00 00:00:00';
                $order_detail->id_warehouse = 0;
                if (Configuration::get('PS_SHOP_ENABLE')) {
                    $order_detail->id_shop = (int) Configuration::get('PS_SHOP_DEFAULT');
                }
                if (!$order_detail->add()) {
                    Toolbox::addLogLine(self::getL('Failed for creation of order detail / NetEven Order Id') . ' ' . (int) $neteven_order->OrderID . ' ' . self::getL('NetEven order detail id') . ' ' . $neteven_order->OrderLineID);
                } else {
                    if ($this->time_analyse) {
                        $this->current_time_2 = time();
                        Toolbox::displayDebugMessage(self::getL('Order detail') . ' : ' . ((int) $this->current_time_2 - (int) $this->current_time_0) . 's');
                    }
                    $id_order_detail_temp = $order_detail->id;
                    Toolbox::addLogLine(self::getL('Creation of order detail for NetEven order Id') . ' ' . (int) $neteven_order->OrderID . ' ' . self::getL('NetEven order detail id') . ' ' . (int) $neteven_order->OrderLineID);
                    // Update quantity of product
                    if (class_exists('StockAvailable')) {
                        // Update quantity of product
                        if ($control_attribute_product) {
                            StockAvailable::setQuantity($res_product['id_product'], $id_product_attribute, StockAvailable::getQuantityAvailableByProduct($res_product['id_product'], $id_product_attribute) - $neteven_order->Quantity);
                        } else {
                            StockAvailable::setQuantity($res_product['id_product'], 0, StockAvailable::getQuantityAvailableByProduct($res_product['id_product']) - $neteven_order->Quantity);
                        }
                    } else {
                        $t_info_product = array();
                        $t_info_product['id_product'] = $res_product["id_product"];
                        $t_info_product['cart_quantity'] = $neteven_order->Quantity;
                        $t_info_product['id_product_attribute'] = NULL;
                        if ($control_attribute_product) {
                            $t_info_product['id_product_attribute'] = $id_product_attribute;
                        }
                        Product::updateQuantity($t_info_product);
                    }
                    if ($this->time_analyse) {
                        $this->current_time_0 = time();
                        Toolbox::displayDebugMessage(self::getL('Cart product') . ' : ' . ((int) $this->current_time_0 - (int) $this->current_time_2) . 's');
                    }
                    // Insert order in orders_gateway table
                    if (!Db::getInstance()->Execute('INSERT INTO `' . _DB_PREFIX_ . 'orders_gateway` (`id_order_neteven`, `id_order`, `id_order_detail_neteven`, `date_add`, `date_upd`) VALUES (' . (int) $neteven_order->OrderID . ', ' . (int) $id_order . ', ' . (int) $neteven_order->OrderLineID . ', "' . pSQL($date_now) . '", "' . pSQL($date_now) . '")')) {
                        Toolbox::addLogLine(self::getL('Failed for save export NetEven order Id') . ' ' . (int) $neteven_order->OrderID . ' ' . self::getL('NetEven order detail id') . ' ' . (int) $neteven_order->OrderLineID);
                    } else {
                        Toolbox::addLogLine(self::getL('Save export NetEven order Id') . ' ' . (int) $neteven_order->OrderID . ' ' . self::getL('NetEven order detail id') . ' ' . (int) $neteven_order->OrderLineID);
                    }
                }
            }
        } else {
            Toolbox::addLogLine(self::getL('Failed for creation of order detail of NetEven order Id') . $neteven_order->OrderID . ' ' . self::getL('NetEven order detail id') . ' ' . $neteven_order->OrderLineID . ' ' . self::getL('Product not found SKU') . ' ' . $neteven_order->SKU);
        }
        $order = new Order($id_order);
        $products = $order->getProductsDetail();
        if (count($products) == 0 && $this->getValue('mail_active')) {
            $this->sendDebugMail($this->getValue('mail_list_alert'), self::getL('Order imported is empty'), self::getL('Order Id') . ' ' . (int) $order->id);
        }
    }
Example #25
0
 protected function reinjectQuantity($order_detail, $qty_cancel_product)
 {
     // Reinject product
     $reinjectable_quantity = (int) $order_detail->product_quantity - (int) $order_detail->product_quantity_reinjected;
     $quantity_to_reinject = $qty_cancel_product > $reinjectable_quantity ? $reinjectable_quantity : $qty_cancel_product;
     // @since 1.5.0 : Advanced Stock Management
     $product_to_inject = new Product($order_detail->product_id, false, (int) $this->context->language->id, (int) $order_detail->id_shop);
     $product = new Product($order_detail->product_id, false, (int) $this->context->language->id, (int) $order_detail->id_shop);
     if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $product->advanced_stock_management && $order_detail->id_warehouse != 0) {
         $manager = StockManagerFactory::getManager();
         $movements = StockMvt::getNegativeStockMvts($order_detail->id_order, $order_detail->product_id, $order_detail->product_attribute_id, $quantity_to_reinject);
         $left_to_reinject = $quantity_to_reinject;
         foreach ($movements as $movement) {
             if ($left_to_reinject > $movement['physical_quantity']) {
                 $quantity_to_reinject = $movement['physical_quantity'];
             }
             $left_to_reinject -= $quantity_to_reinject;
             $manager->addProduct($order_detail->product_id, $order_detail->product_attribute_id, new Warehouse($movement['id_warehouse']), $quantity_to_reinject, null, $movement['price_te'], true);
         }
         StockAvailable::synchronize($order_detail->product_id);
     } elseif ($order_detail->id_warehouse == 0) {
         StockAvailable::updateQuantity($order_detail->product_id, $order_detail->product_attribute_id, $quantity_to_reinject, $order_detail->id_shop);
     } else {
         $this->errors[] = Tools::displayError('This product cannot be re-stocked.');
     }
 }
 /**
  * Convert the entities data into an xml object and return the xml object as a string
  *
  * @param array $aEntity Entity data
  */
 public function formatEntityToXML($aEntity)
 {
     $sReturn = '';
     $dom = new DOMDocument('1.0', 'utf-8');
     $bUseRoutes = (bool) Configuration::get('PS_REWRITING_SETTINGS');
     $oDispatcher = Dispatcher::getInstance();
     // Force the dispatcher to use custom routes because the use of custom routes is disabled in the BO Context
     foreach ($oDispatcher->default_routes as $route_id => $route_data) {
         if ($custom_route = Configuration::get('PS_ROUTE_' . $route_id)) {
             foreach (Language::getLanguages() as $lang) {
                 $oDispatcher->addRoute($route_id, $custom_route, $route_data['controller'], $lang['id_lang'], $route_data['keywords'], isset($route_data['params']) ? $route_data['params'] : array());
             }
         }
     }
     $oPrediggoConfig = $this->aPrediggoConfigs[(int) $aEntity['id_shop']];
     $link = $oPrediggoConfig->getContext()->link;
     $oProduct = new Product((int) $aEntity['id_product'], true, null, (int) $aEntity['id_shop'], $oPrediggoConfig->getContext());
     if ((int) StockAvailable::getQuantityAvailableByProduct((int) $aEntity['id_product'], 0, (int) $aEntity['id_shop']) < (int) $oPrediggoConfig->export_product_min_quantity) {
         $this->nbEntitiesTreated--;
         $this->nbEntities--;
         return ' ';
     }
     $ps_tax = (int) Configuration::get('PS_TAX');
     foreach ($this->aLanguages as $aLanguage) {
         $id_lang = (int) $aLanguage['id_lang'];
         // Set the root of the XML
         $root = $dom->createElement($this->sEntity);
         $dom->appendChild($root);
         $root->setAttribute('timestamp', (int) strtotime($oProduct->date_add));
         $id = $dom->createElement('id', (int) $oProduct->id);
         $root->appendChild($id);
         $profile = $dom->createElement('profile', (int) $aEntity['id_shop']);
         $root->appendChild($profile);
         $name = $dom->createElement('name');
         $name->appendChild($dom->createCDATASection($oProduct->name[$id_lang]));
         $root->appendChild($name);
         $oCategory = new Category((int) $oProduct->id_category_default);
         $aCategories = $oCategory->getParentsCategories($id_lang);
         if (is_array($aCategories) && count($aCategories) > 0) {
             foreach ($aCategories as $aCategory) {
                 $oCategoryTmp = new Category((int) $aCategory['id_category'], $id_lang);
                 if (!empty($oCategoryTmp->name)) {
                     $genre = $dom->createElement('genre');
                     $genre->appendChild($dom->createCDATASection($oCategoryTmp->name));
                     $root->appendChild($genre);
                 }
                 unset($oCategoryTmp);
             }
         }
         unset($aCategories);
         unset($oCategory);
         if (!empty($oProduct->ean13)) {
             $ean = $dom->createElement('ean');
             $ean->appendChild($dom->createCDATASection($oProduct->ean13));
             $root->appendChild($ean);
         }
         $price = $dom->createElement('price', number_format($oProduct->getPrice($ps_tax), 2, '.', ''));
         $root->appendChild($price);
         if (isset($oProduct->tags[$id_lang]) && ($aTags = $oProduct->tags[$id_lang])) {
             $tag = $dom->createElement('tag');
             $tag->appendChild($dom->createCDATASection(join(',', $aTags)));
             $root->appendChild($tag);
         }
         $sDesc = trim(strip_tags($oProduct->description[$id_lang]));
         if ($oPrediggoConfig->export_product_description && !empty($sDesc)) {
             $description = $dom->createElement('description');
             $description->appendChild($dom->createCDATASection($sDesc));
             $root->appendChild($description);
         }
         if (!empty($oProduct->id_manufacturer)) {
             $supplierid = $dom->createElement('supplierid', (int) $oProduct->id_manufacturer);
             $root->appendChild($supplierid);
         }
         $recommendable = $dom->createElement('recommendable', in_array((int) $oProduct->id, explode(',', $oPrediggoConfig->products_ids_not_recommendable)) ? 'false' : 'true');
         $root->appendChild($recommendable);
         $searchable = $dom->createElement('searchable', in_array((int) $oProduct->id, explode(',', $oPrediggoConfig->products_ids_not_searchable)) ? 'false' : 'true');
         $root->appendChild($searchable);
         // Set product URL
         $attribute = $dom->createElement('attribute');
         $root->appendChild($attribute);
         $attName = $dom->createElement('attName', 'producturl');
         $attribute->appendChild($attName);
         $attValue = $dom->createElement('attValue');
         $attValue->appendChild($dom->createCDATASection($link->getProductLink((int) $oProduct->id, $oProduct->link_rewrite[$id_lang], Category::getLinkRewrite((int) $oProduct->id_category_default, $id_lang), NULL, $id_lang, (int) $aEntity['id_shop'], 0, $bUseRoutes)));
         $attribute->appendChild($attValue);
         // Set product picture
         if ($oPrediggoConfig->export_product_image) {
             $attribute = $dom->createElement('attribute');
             $root->appendChild($attribute);
             $attName = $dom->createElement('attName', 'imageurl');
             $attribute->appendChild($attName);
             $aCover = $oProduct->getCover((int) $oProduct->id);
             $attValue = $dom->createElement('attValue');
             $attValue->appendChild($dom->createCDATASection($link->getImageLink($oProduct->link_rewrite[$id_lang], (int) $aCover['id_image'], 'large')));
             $attribute->appendChild($attValue);
         }
         // Set combinations
         $aProductCombinations = Product::getAttributesInformationsByProduct((int) $oProduct->id);
         if (sizeof($aProductCombinations)) {
             foreach ($aProductCombinations as $aProductCombination) {
                 if (!empty($oPrediggoConfig->attributes_groups_ids) && in_array((int) $aProductCombination['id_attribute_group'], explode(',', $oPrediggoConfig->attributes_groups_ids))) {
                     $attribute = $dom->createElement('attribute');
                     $root->appendChild($attribute);
                     $attName = $dom->createElement('attName');
                     $attName->appendChild($dom->createCDATASection($aProductCombination['group']));
                     $attribute->appendChild($attName);
                     $attValue = $dom->createElement('attValue');
                     $attValue->appendChild($dom->createCDATASection($aProductCombination['attribute']));
                     $attribute->appendChild($attValue);
                 }
             }
         }
         unset($aProductCombinations);
         // Set features
         $aProductFeatures = $oProduct->getFrontFeatures($id_lang);
         if (sizeof($aProductFeatures)) {
             foreach ($aProductFeatures as $aProductFeature) {
                 if (!empty($oPrediggoConfig->features_ids) && in_array((int) $aProductFeature['id_feature'], explode(',', $oPrediggoConfig->features_ids))) {
                     $attribute = $dom->createElement('attribute');
                     $root->appendChild($attribute);
                     $attName = $dom->createElement('attName');
                     $attName->appendChild($dom->createCDATASection($aProductFeature['name']));
                     $attribute->appendChild($attName);
                     $attValue = $dom->createElement('attValue');
                     $attValue->appendChild($dom->createCDATASection($aProductFeature['value']));
                     $attribute->appendChild($attValue);
                 }
             }
         }
         unset($aProductFeatures);
         $aAccessories = Product::getAccessoriesLight($id_lang, (int) $oProduct->id);
         if (sizeof($aAccessories)) {
             foreach ($aAccessories as $aAccessory) {
                 $attribute = $dom->createElement('attribute');
                 $root->appendChild($attribute);
                 $attName = $dom->createElement('attName');
                 $attName->appendChild($dom->createCDATASection('accessory'));
                 $attribute->appendChild($attName);
                 $attValue = $dom->createElement('attValue');
                 $attValue->appendChild($dom->createCDATASection((int) $aAccessory['id_product']));
                 $attribute->appendChild($attValue);
             }
         }
         unset($aAccessories);
         $sReturn .= $dom->saveXML($root);
     }
     unset($dom);
     unset($oProduct);
     return $sReturn;
 }
Example #27
0
 function getPriceList()
 {
     $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
     if ($currency->iso_code == 'RUB') {
         $currency->iso_code = 'RUR';
     }
     $desc_type = Configuration::get('YAMARKET_DESC_TYPE');
     $link = $this->context->link;
     $this->ensureHttpPrefix($link);
     // Get products
     $products = Product::getProducts($this->id_lang, 0, 0, 'name', 'asc');
     $xml = $this->getDocBody();
     // Offers
     $offers = $xml->createElement("offers");
     foreach ($products as $product) {
         // Get home category
         $category = $product['id_category_default'];
         if ($category == 1) {
             $temp_categories = Product::getProductCategories($product['id_product']);
             foreach ($temp_categories as $category) {
                 if ($category != 1) {
                     break;
                 }
             }
             if ($category == 1) {
                 continue;
             }
         }
         if (in_array($category, $this->excluded_cats)) {
             continue;
         }
         $prod_obj = new Product($product['id_product']);
         $crewrite = Category::getLinkRewrite($product['id_category_default'], $this->id_lang);
         $accessories = $this->getAccessories($product);
         $features = $this->getFeatures($product['id_product']);
         $combinations = $this->getCombinations($prod_obj, $currency);
         // template array
         $product_item = array('name' => html_entity_decode($product['name']), 'description' => html_entity_decode($product['description']), 'id_category_default' => $category, 'ean13' => $product['ean13'], 'accessories' => implode(',', $accessories), 'vendor' => $product['manufacturer_name']);
         if ($desc_type == 1) {
             $product_item['description'] = html_entity_decode($product['description_short']);
         }
         if ($this->country_of_origin_attr != '' && array_key_exists($this->country_of_origin_attr, $features)) {
             $product_item['country_of_origin'] = $features[$this->country_of_origin_attr];
             unset($features[$this->country_of_origin_attr]);
         }
         if ($this->model_name_attr != '' && array_key_exists($this->model_name_attr, $features)) {
             $product_item['name'] = $features[$this->model_name_attr];
             unset($features[$this->model_name_attr]);
         }
         if (!$product['available_for_order'] or !$product['active']) {
             continue;
         }
         if (!empty($combinations)) {
             foreach ($combinations as $combination) {
                 $prod_obj->id_product_attribute = $combination['id_product_attribute'];
                 $available_for_order = 1 <= StockAvailable::getQuantityAvailableByProduct($product['id_product'], $combination['id_product_attribute']);
                 if (!$available_for_order && !$prod_obj->checkQty(1)) {
                     continue;
                 }
                 $params = $this->getParams($combination);
                 $pictures = array();
                 foreach ($combination['id_images'] as $id_image) {
                     $pictures[] = $link->getImageLink($product['link_rewrite'], $product['id_product'] . '-' . $id_image, $this->image_type);
                 }
                 $mainPicture = array_shift($pictures);
                 $url = $link->getProductLink($prod_obj, $product['link_rewrite'], $crewrite, null, null, null, $combination['id_product_attribute']);
                 $extra_product_item = array('id_product' => $product['id_product'] . 'c' . $combination['id_product_attribute'], 'available_for_order' => $available_for_order, 'price' => $prod_obj->getPrice(true, $combination['id_product_attribute']), 'pictures' => $pictures, 'main_picture' => $mainPicture, 'params' => array_merge($params, $features), 'url' => $url);
                 $offer = array_merge($product_item, $extra_product_item);
                 $offers->appendChild($this->getOfferElem($offer, $xml, $currency));
             }
         } else {
             $pictures = $this->getPictures($product['id_product'], $product['link_rewrite']);
             $mainPicture = array_shift($pictures);
             $available_for_order = 1 <= StockAvailable::getQuantityAvailableByProduct($product['id_product'], 0);
             if (!$available_for_order && !$prod_obj->checkQty(1)) {
                 continue;
             }
             $url = $link->getProductLink($prod_obj, $product['link_rewrite'], $crewrite);
             $extra_product_item = array('id_product' => $product['id_product'], 'available_for_order' => $available_for_order, 'price' => $prod_obj->getPrice(), 'pictures' => $pictures, 'main_picture' => $mainPicture, 'params' => $features, 'url' => $url);
             $offer = array_merge($product_item, $extra_product_item);
             $offers->appendChild($this->getOfferElem($offer, $xml, $currency));
         }
         $prod_obj->clearCache(true);
     }
     $shop = $xml->getElementsByTagName("shop")->item(0);
     $shop->appendChild($offers);
     return $xml->saveXML();
 }
 public function processGenerate()
 {
     if (!is_array(Tools::getValue('options'))) {
         $this->errors[] = $this->trans('Please select at least one attribute.', array(), 'Admin.Catalog.Notification');
     } else {
         $tab = array_values(Tools::getValue('options'));
         if (count($tab) && Validate::isLoadedObject($this->product)) {
             AdminAttributeGeneratorController::setAttributesImpacts($this->product->id, $tab);
             $this->combinations = array_values(AdminAttributeGeneratorController::createCombinations($tab));
             $values = array_values(array_map(array($this, 'addAttribute'), $this->combinations));
             // @since 1.5.0
             if ($this->product->depends_on_stock == 0) {
                 $attributes = Product::getProductAttributesIds($this->product->id, true);
                 foreach ($attributes as $attribute) {
                     StockAvailable::removeProductFromStockAvailable($this->product->id, $attribute['id_product_attribute'], Context::getContext()->shop);
                 }
             }
             SpecificPriceRule::disableAnyApplication();
             $this->product->deleteProductAttributes();
             $this->product->generateMultipleCombinations($values, $this->combinations);
             // Reset cached default attribute for the product and get a new one
             Product::getDefaultAttribute($this->product->id, 0, true);
             Product::updateDefaultAttribute($this->product->id);
             // @since 1.5.0
             if ($this->product->depends_on_stock == 0) {
                 $attributes = Product::getProductAttributesIds($this->product->id, true);
                 $quantity = (int) Tools::getValue('quantity');
                 foreach ($attributes as $attribute) {
                     if (Shop::getContext() == Shop::CONTEXT_ALL) {
                         $shops_list = Shop::getShops();
                         if (is_array($shops_list)) {
                             foreach ($shops_list as $current_shop) {
                                 if (isset($current_shop['id_shop']) && (int) $current_shop['id_shop'] > 0) {
                                     StockAvailable::setQuantity($this->product->id, (int) $attribute['id_product_attribute'], $quantity, (int) $current_shop['id_shop']);
                                 }
                             }
                         }
                     } else {
                         StockAvailable::setQuantity($this->product->id, (int) $attribute['id_product_attribute'], $quantity);
                     }
                 }
             } else {
                 StockAvailable::synchronize($this->product->id);
             }
             SpecificPriceRule::enableAnyApplication();
             SpecificPriceRule::applyAllRules(array((int) $this->product->id));
             Tools::redirectAdmin($this->context->link->getAdminLink('AdminProducts') . '&id_product=' . (int) Tools::getValue('id_product') . '&updateproduct&key_tab=Combinations&conf=4');
         } else {
             $this->errors[] = $this->trans('Unable to initialize these parameters. A combination is missing or an object cannot be loaded.');
         }
     }
 }
Example #29
0
 /**
  * For a given product, get its "out of stock" flag
  *
  * @param int $id_product
  * @param int $id_shop Optional : gets context if null @see Context::getContext()
  * @return bool : depends on stock @see $depends_on_stock
  */
 public static function outOfStock($id_product, $id_shop = null)
 {
     if (!Validate::isUnsignedId($id_product)) {
         return false;
     }
     $query = new DbQuery();
     $query->select('out_of_stock');
     $query->from('stock_available');
     $query->where('id_product = ' . (int) $id_product);
     $query->where('id_product_attribute = 0');
     $query = StockAvailable::addSqlShopRestriction($query, $id_shop);
     return (int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($query);
 }
 /**
  * Object creation
  */
 public function processAdd()
 {
     if (!Tools::getValue('categoryBox') || !in_array(Tools::getValue('id_category'), Tools::getValue('categoryBox'))) {
         $this->errors[] = $this->l('You need to select at least the root category.');
     }
     if (Tools::isSubmit('id_category_default')) {
         $_POST['id_category'] = (int) Tools::getValue('id_category_default');
     }
     /* Checking fields validity */
     $this->validateRules();
     if (!count($this->errors)) {
         $object = new $this->className();
         $this->copyFromPost($object, $this->table);
         $this->beforeAdd($object);
         if (!$object->add()) {
             $this->errors[] = Tools::displayError('An error occurred while creating an object.') . ' <b>' . $this->table . ' (' . Db::getInstance()->getMsgError() . ')</b>';
         } else {
             if (($_POST[$this->identifier] = $object->id) && $this->postImage($object->id) && !count($this->errors) && $this->_redirect) {
                 $parent_id = (int) Tools::getValue('id_parent', 1);
                 $this->afterAdd($object);
                 $this->updateAssoShop($object->id);
                 // Save and stay on same form
                 if (Tools::isSubmit('submitAdd' . $this->table . 'AndStay')) {
                     $this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=' . $object->id . '&conf=3&update' . $this->table . '&token=' . $this->token;
                 }
                 // Save and back to parent
                 if (Tools::isSubmit('submitAdd' . $this->table . 'AndBackToParent')) {
                     $this->redirect_after = self::$currentIndex . '&' . $this->identifier . '=' . $parent_id . '&conf=3&token=' . $this->token;
                 }
                 // Default behavior (save and back)
                 if (empty($this->redirect_after)) {
                     $this->redirect_after = self::$currentIndex . ($parent_id ? '&' . $this->identifier . '=' . $object->id : '') . '&conf=3&token=' . $this->token;
                 }
             }
         }
     }
     $this->errors = array_unique($this->errors);
     if (count($this->errors) > 0) {
         $this->display = 'add';
         return;
     }
     // specific import for stock
     if (isset($import_data['stock_available']) && isset($import_data['product']) && Tools::isSubmit('useImportData')) {
         $id_src_shop = (int) Tools::getValue('importFromShop');
         if ($object->getGroup()->share_stock == false) {
             StockAvailable::copyStockAvailableFromShopToShop($id_src_shop, $object->id);
         }
     }
     $categories = Tools::getValue('categoryBox');
     array_unshift($categories, Configuration::get('PS_ROOT_CATEGORY'));
     Category::updateFromShop($categories, $object->id);
     Search::indexation(true);
     return $object;
 }