/**
  * Get all Packs that contains the given item in the corresponding declination.
  *
  * @param Product $item
  * @param integer $item_attribute_id
  * @param integer $id_lang Optional
  * @return Array[Pack] The packs that contains the given item, with special dynamic attribute [pack_item_quantity]
  */
 public function getPacksContainingItem($item, $item_attribute_id, $id_lang = false)
 {
     if ($id_lang === false) {
         $configuration = Adapter_ServiceLocator::get('Core_Business_ConfigurationInterface');
         $id_lang = (int) $configuration->get('PS_LANG_DEFAULT');
     }
     return Pack::getPacksContainingItem($item->id, $item_attribute_id, $id_lang);
 }
예제 #2
0
 /**
  *
  * @param Address $address
  * @param mixed $type An additional parameter for the tax manager (ex: tax rules id for TaxRuleTaxManager)
  */
 public function __construct(Address $address, $type, Core_Business_ConfigurationInterface $configurationManager = null)
 {
     if ($configurationManager === null) {
         $this->configurationManager = Adapter_ServiceLocator::get('Core_Business_ConfigurationInterface');
     } else {
         $this->configurationManager = $configurationManager;
     }
     $this->address = $address;
     $this->type = $type;
 }
예제 #3
0
 /**
  * This function returns the total cart amount
  *
  * Possible values for $type:
  * Cart::ONLY_PRODUCTS
  * Cart::ONLY_DISCOUNTS
  * Cart::BOTH
  * Cart::BOTH_WITHOUT_SHIPPING
  * Cart::ONLY_SHIPPING
  * Cart::ONLY_WRAPPING
  * Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING
  * Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING
  *
  * @param bool $withTaxes With or without taxes
  * @param int $type Total type
  * @param bool $use_cache Allow using cache of the method CartRule::getContextualValue
  * @return float Order total
  */
 public function getOrderTotal($with_taxes = true, $type = Cart::BOTH, $products = null, $id_carrier = null, $use_cache = true)
 {
     // Dependencies
     $address_factory = Adapter_ServiceLocator::get('Adapter_AddressFactory');
     $price_calculator = Adapter_ServiceLocator::get('Adapter_ProductPriceCalculator');
     $configuration = Adapter_ServiceLocator::get('Core_Business_ConfigurationInterface');
     $ps_tax_address_type = $configuration->get('PS_TAX_ADDRESS_TYPE');
     $ps_use_ecotax = $configuration->get('PS_USE_ECOTAX');
     $ps_round_type = $configuration->get('PS_ROUND_TYPE');
     $ps_ecotax_tax_rules_group_id = $configuration->get('PS_ECOTAX_TAX_RULES_GROUP_ID');
     $compute_precision = $configuration->get('_PS_PRICE_COMPUTE_PRECISION_');
     if (!$this->id) {
         return 0;
     }
     $type = (int) $type;
     $array_type = array(Cart::ONLY_PRODUCTS, Cart::ONLY_DISCOUNTS, Cart::BOTH, Cart::BOTH_WITHOUT_SHIPPING, Cart::ONLY_SHIPPING, Cart::ONLY_WRAPPING, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING);
     // Define virtual context to prevent case where the cart is not the in the global context
     $virtual_context = Context::getContext()->cloneContext();
     $virtual_context->cart = $this;
     if (!in_array($type, $array_type)) {
         die(Tools::displayError());
     }
     $with_shipping = in_array($type, array(Cart::BOTH, Cart::ONLY_SHIPPING));
     // if cart rules are not used
     if ($type == Cart::ONLY_DISCOUNTS && !CartRule::isFeatureActive()) {
         return 0;
     }
     // no shipping cost if is a cart with only virtuals products
     $virtual = $this->isVirtualCart();
     if ($virtual && $type == Cart::ONLY_SHIPPING) {
         return 0;
     }
     if ($virtual && $type == Cart::BOTH) {
         $type = Cart::BOTH_WITHOUT_SHIPPING;
     }
     if ($with_shipping || $type == Cart::ONLY_DISCOUNTS) {
         if (is_null($products) && is_null($id_carrier)) {
             $shipping_fees = $this->getTotalShippingCost(null, (bool) $with_taxes);
         } else {
             $shipping_fees = $this->getPackageShippingCost($id_carrier, (bool) $with_taxes, null, $products);
         }
     } else {
         $shipping_fees = 0;
     }
     if ($type == Cart::ONLY_SHIPPING) {
         return $shipping_fees;
     }
     if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING) {
         $type = Cart::ONLY_PRODUCTS;
     }
     $param_product = true;
     if (is_null($products)) {
         $param_product = false;
         $products = $this->getProducts();
     }
     if ($type == Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING) {
         foreach ($products as $key => $product) {
             if ($product['is_virtual']) {
                 unset($products[$key]);
             }
         }
         $type = Cart::ONLY_PRODUCTS;
     }
     $order_total = 0;
     if (Tax::excludeTaxeOption()) {
         $with_taxes = false;
     }
     $products_total = array();
     $ecotax_total = 0;
     foreach ($products as $product) {
         // products refer to the cart details
         if ($virtual_context->shop->id != $product['id_shop']) {
             $virtual_context->shop = new Shop((int) $product['id_shop']);
         }
         if ($ps_tax_address_type == 'id_address_invoice') {
             $id_address = (int) $this->id_address_invoice;
         } else {
             $id_address = (int) $product['id_address_delivery'];
         }
         // Get delivery address of the product from the cart
         if (!$address_factory->addressExists($id_address)) {
             $id_address = null;
         }
         // The $null variable below is not used,
         // but it is necessary to pass it to getProductPrice because
         // it expects a reference.
         $null = null;
         $price = $price_calculator->getProductPrice((int) $product['id_product'], $with_taxes, (int) $product['id_product_attribute'], 6, null, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $id_address, $null, $ps_use_ecotax, true, $virtual_context);
         if ($product['price_more']) {
             $price += $product['price_more'];
         }
         $address = $address_factory->findOrCreate($id_address, true);
         if ($with_taxes) {
             $id_tax_rules_group = Product::getIdTaxRulesGroupByIdProduct((int) $product['id_product'], $virtual_context);
             $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator();
         } else {
             $id_tax_rules_group = 0;
         }
         if (in_array($ps_round_type, array(Order::ROUND_ITEM, Order::ROUND_LINE))) {
             if (!isset($products_total[$id_tax_rules_group])) {
                 $products_total[$id_tax_rules_group] = 0;
             }
         } elseif (!isset($products_total[$id_tax_rules_group . '_' . $id_address])) {
             $products_total[$id_tax_rules_group . '_' . $id_address] = 0;
         }
         switch ($ps_round_type) {
             case Order::ROUND_TOTAL:
                 $products_total[$id_tax_rules_group . '_' . $id_address] += $price * (int) $product['cart_quantity'];
                 break;
             case Order::ROUND_LINE:
                 $product_price = $price * $product['cart_quantity'];
                 $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision);
                 break;
             case Order::ROUND_ITEM:
             default:
                 $product_price = $price;
                 $products_total[$id_tax_rules_group] += Tools::ps_round($product_price, $compute_precision) * (int) $product['cart_quantity'];
                 break;
         }
     }
     foreach ($products_total as $key => $price) {
         $order_total += $price;
     }
     $order_total_products = $order_total;
     if ($type == Cart::ONLY_DISCOUNTS) {
         $order_total = 0;
     }
     // Wrapping Fees
     $wrapping_fees = 0;
     // With PS_ATCP_SHIPWRAP on the gift wrapping cost computation calls getOrderTotal with $type === Cart::ONLY_PRODUCTS, so the flag below prevents an infinite recursion.
     $include_gift_wrapping = !$configuration->get('PS_ATCP_SHIPWRAP') || $type !== Cart::ONLY_PRODUCTS;
     if ($this->gift && $include_gift_wrapping) {
         $wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), $compute_precision), Currency::getCurrencyInstance((int) $this->id_currency));
     }
     if ($type == Cart::ONLY_WRAPPING) {
         return $wrapping_fees;
     }
     $order_total_discount = 0;
     $order_shipping_discount = 0;
     if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive()) {
         // First, retrieve the cart rules associated to this "getOrderTotal"
         if ($with_shipping || $type == Cart::ONLY_DISCOUNTS) {
             $cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL);
         } else {
             $cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_REDUCTION);
             // Cart Rules array are merged manually in order to avoid doubles
             foreach ($this->getCartRules(CartRule::FILTER_ACTION_GIFT) as $tmp_cart_rule) {
                 $flag = false;
                 foreach ($cart_rules as $cart_rule) {
                     if ($tmp_cart_rule['id_cart_rule'] == $cart_rule['id_cart_rule']) {
                         $flag = true;
                     }
                 }
                 if (!$flag) {
                     $cart_rules[] = $tmp_cart_rule;
                 }
             }
         }
         $id_address_delivery = 0;
         if (isset($products[0])) {
             $id_address_delivery = is_null($products) ? $this->id_address_delivery : $products[0]['id_address_delivery'];
         }
         $package = array('id_carrier' => $id_carrier, 'id_address' => $id_address_delivery, 'products' => $products);
         // Then, calculate the contextual value for each one
         $flag = false;
         foreach ($cart_rules as $cart_rule) {
             // If the cart rule offers free shipping, add the shipping cost
             if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping && !$flag) {
                 $order_shipping_discount = (double) Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, $param_product ? $package : null, $use_cache), $compute_precision);
                 $flag = true;
             }
             // If the cart rule is a free gift, then add the free gift value only if the gift is in this package
             if ((int) $cart_rule['obj']->gift_product) {
                 $in_order = false;
                 if (is_null($products)) {
                     $in_order = true;
                 } else {
                     foreach ($products as $product) {
                         if ($cart_rule['obj']->gift_product == $product['id_product'] && $cart_rule['obj']->gift_product_attribute == $product['id_product_attribute']) {
                             $in_order = true;
                         }
                     }
                 }
                 if ($in_order) {
                     $order_total_discount += $cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_GIFT, $package, $use_cache);
                 }
             }
             // If the cart rule offers a reduction, the amount is prorated (with the products in the package)
             if ($cart_rule['obj']->reduction_percent > 0 || $cart_rule['obj']->reduction_amount > 0) {
                 $order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_REDUCTION, $package, $use_cache), $compute_precision);
             }
         }
         $order_total_discount = min(Tools::ps_round($order_total_discount, 2), (double) $order_total_products) + (double) $order_shipping_discount;
         $order_total -= $order_total_discount;
     }
     if ($type == Cart::BOTH) {
         $order_total += $shipping_fees + $wrapping_fees;
     }
     if ($order_total < 0 && $type != Cart::ONLY_DISCOUNTS) {
         return 0;
     }
     if ($type == Cart::ONLY_DISCOUNTS) {
         return $order_total_discount;
     }
     return Tools::ps_round((double) $order_total, $compute_precision);
 }
예제 #4
0
 /**
  * Builds the object
  *
  * @param int|null $id      If specified, loads and existing object from DB (optional).
  * @param int|null $id_lang Required if object is multilingual (optional).
  * @param int|null $id_shop ID shop for objects with multishop tables.
  *
  * @throws PrestaShopDatabaseException
  * @throws PrestaShopException
  */
 public function __construct($id = null, $id_lang = null, $id_shop = null)
 {
     $class_name = get_class($this);
     if (!isset(ObjectModel::$loaded_classes[$class_name])) {
         $this->def = ObjectModel::getDefinition($class_name);
         $this->setDefinitionRetrocompatibility();
         if (!Validate::isTableOrIdentifier($this->def['primary']) || !Validate::isTableOrIdentifier($this->def['table'])) {
             throw new PrestaShopException('Identifier or table format not valid for class ' . $class_name);
         }
         ObjectModel::$loaded_classes[$class_name] = get_object_vars($this);
     } else {
         foreach (ObjectModel::$loaded_classes[$class_name] as $key => $value) {
             $this->{$key} = $value;
         }
     }
     if ($id_lang !== null) {
         $this->id_lang = Language::getLanguage($id_lang) !== false ? $id_lang : Configuration::get('PS_LANG_DEFAULT');
     }
     if ($id_shop && $this->isMultishop()) {
         $this->id_shop = (int) $id_shop;
         $this->get_shop_from_context = false;
     }
     if ($this->isMultishop() && !$this->id_shop) {
         $this->id_shop = Context::getContext()->shop->id;
     }
     if ($id) {
         $entity_mapper = Adapter_ServiceLocator::get("Adapter_EntityMapper");
         $entity_mapper->load($id, $id_lang, $this, $this->def, $this->id_shop, self::$cache_objects);
     }
 }
예제 #5
0
 public function initContent()
 {
     if (Tools::isSubmit('addnewmodule') && $this->context->mode == Context::MODE_HOST) {
         $this->display = 'add';
         $this->context->smarty->assign(array('iso_code' => $this->context->language->iso_code));
         return parent::initContent();
     }
     $this->meta_title = 'Modules';
     // If we are on a module configuration, no need to load all modules
     if (Tools::getValue('configure') != '') {
         $this->context->smarty->assign(array('maintenance_mode' => !(bool) Configuration::Get('PS_SHOP_ENABLE')));
         return true;
     }
     $this->initToolbar();
     $this->initPageHeaderToolbar();
     // Init
     $smarty = $this->context->smarty;
     $autocomplete_list = 'var moduleList = [';
     $category_filtered = array();
     $filter_categories = explode('|', Configuration::get('PS_SHOW_CAT_MODULES_' . (int) $this->id_employee));
     if (count($filter_categories) > 0) {
         foreach ($filter_categories as $fc) {
             if (!empty($fc)) {
                 $category_filtered[$fc] = 1;
             }
         }
     }
     if (empty($category_filtered) && Tools::getValue('tab_module')) {
         $category_filtered[Tools::getValue('tab_module')] = 1;
     }
     foreach ($this->list_modules_categories as $k => $v) {
         $this->list_modules_categories[$k]['nb'] = 0;
     }
     // Retrieve Modules Preferences
     $modules_preferences = '';
     $tab_modules_preferences = array();
     $modules_preferences_tmp = Db::getInstance()->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'module_preference` WHERE `id_employee` = ' . (int) $this->id_employee);
     $tab_modules_preferences_tmp = Db::getInstance()->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'tab_module_preference` WHERE `id_employee` = ' . (int) $this->id_employee);
     foreach ($tab_modules_preferences_tmp as $i => $j) {
         $tab_modules_preferences[$j['module']][] = $j['id_tab'];
     }
     foreach ($modules_preferences_tmp as $k => $v) {
         if ($v['interest'] == null) {
             unset($v['interest']);
         }
         if ($v['favorite'] == null) {
             unset($v['favorite']);
         }
         $modules_preferences[$v['module']] = $v;
     }
     // Retrieve Modules List
     $modules = Module::getModulesOnDisk(true, $this->logged_on_addons, $this->id_employee);
     $this->initModulesList($modules);
     $this->nb_modules_total = count($modules);
     $module_errors = array();
     $module_success = array();
     $upgrade_available = array();
     $dont_filter = false;
     //Add succes message for one module update
     if (Tools::getValue('updated') && Tools::getValue('module_name')) {
         $module_names = (string) Tools::getValue('module_name');
         if (strpos($module_names, '|')) {
             $module_names = explode('|', $module_names);
             $dont_filter = true;
         }
         if (!is_array($module_names)) {
             $module_names = (array) $module_names;
         }
         foreach ($modules as $km => $module) {
             if (in_array($module->name, $module_names)) {
                 $module_success[] = array('name' => $module->displayName, 'message' => array(0 => sprintf($this->l('Current version: %s'), $module->version)));
             }
         }
     }
     if (Tools::getValue('allUpdated')) {
         $this->confirmations[] = $this->l('All modules updated successfully.');
     }
     // Browse modules list
     foreach ($modules as $km => $module) {
         //if we are in favorites view we only display installed modules
         if (Tools::getValue('select') == 'favorites' && !$module->id) {
             unset($modules[$km]);
             continue;
         }
         // Upgrade Module process, init check if a module could be upgraded
         if (Module::initUpgradeModule($module)) {
             // When the XML cache file is up-to-date, the module may not be loaded yet
             if (!class_exists($module->name)) {
                 if (!file_exists(_PS_MODULE_DIR_ . $module->name . '/' . $module->name . '.php')) {
                     continue;
                 }
                 require_once _PS_MODULE_DIR_ . $module->name . '/' . $module->name . '.php';
             }
             if ($object = Adapter_ServiceLocator::get($module->name)) {
                 /** @var Module $object */
                 $object->runUpgradeModule();
                 if (count($errors_module_list = $object->getErrors())) {
                     $module_errors[] = array('name' => $module->displayName, 'message' => $errors_module_list);
                 } elseif (count($conf_module_list = $object->getConfirmations())) {
                     $module_success[] = array('name' => $module->displayName, 'message' => $conf_module_list);
                 }
                 unset($object);
             }
         } elseif (Module::getUpgradeStatus($module->name)) {
             // When the XML cache file is up-to-date, the module may not be loaded yet
             if (!class_exists($module->name)) {
                 if (file_exists(_PS_MODULE_DIR_ . $module->name . '/' . $module->name . '.php')) {
                     require_once _PS_MODULE_DIR_ . $module->name . '/' . $module->name . '.php';
                     $object = Adapter_ServiceLocator::get($module->name);
                     $module_success[] = array('name' => $module->name, 'message' => array(0 => sprintf($this->l('Current version: %s'), $object->version), 1 => $this->l('No file upgrades applied (none exist).')));
                 } else {
                     continue;
                 }
             }
             unset($object);
         }
         // Make modules stats
         $this->makeModulesStats($module);
         // Assign warnings
         if ($module->active && isset($module->warning) && !empty($module->warning) && !$this->ajax) {
             $href = Context::getContext()->link->getAdminLink('AdminModules', true) . '&module_name=' . $module->name . '&tab_module=' . $module->tab . '&configure=' . $module->name;
             $this->context->smarty->assign('text', sprintf($this->l('%1$s: %2$s'), $module->displayName, $module->warning));
             $this->context->smarty->assign('module_link', $href);
             $this->displayWarning($this->context->smarty->fetch('controllers/modules/warning_module.tpl'));
         }
         // AutoComplete array
         $autocomplete_list .= Tools::jsonEncode(array('displayName' => (string) $module->displayName, 'desc' => (string) $module->description, 'name' => (string) $module->name, 'author' => (string) $module->author, 'image' => isset($module->image) ? (string) $module->image : '', 'option' => '')) . ', ';
         // Apply filter
         if ($this->isModuleFiltered($module) && Tools::getValue('select') != 'favorites') {
             unset($modules[$km]);
         } else {
             if (isset($modules_preferences[$modules[$km]->name])) {
                 $modules[$km]->preferences = $modules_preferences[$modules[$km]->name];
             }
             $this->fillModuleData($module, 'array');
             $module->categoryName = isset($this->list_modules_categories[$module->tab]['name']) ? $this->list_modules_categories[$module->tab]['name'] : $this->list_modules_categories['others']['name'];
         }
         unset($object);
         if ($module->installed && isset($module->version_addons) && $module->version_addons) {
             $upgrade_available[] = array('anchor' => ucfirst($module->name), 'name' => $module->name, 'displayName' => $module->displayName);
         }
         if (in_array($module->name, $this->list_partners_modules)) {
             $module->type = 'addonsPartner';
         }
         if (isset($module->description_full) && trim($module->description_full) != '') {
             $module->show_quick_view = true;
         }
     }
     // Don't display categories without modules
     $cleaned_list = array();
     foreach ($this->list_modules_categories as $k => $list) {
         if ($list['nb'] > 0) {
             $cleaned_list[$k] = $list;
         }
     }
     // Actually used for the report of the upgraded errors
     if (count($module_errors)) {
         $html = $this->generateHtmlMessage($module_errors);
         $this->errors[] = sprintf(Tools::displayError('The following module(s) were not upgraded successfully: %s.'), $html);
     }
     if (count($module_success)) {
         $html = $this->generateHtmlMessage($module_success);
         $this->confirmations[] = sprintf($this->l('The following module(s) were upgraded successfully: %s.'), $html);
     }
     ConfigurationKPI::updateValue('UPDATE_MODULES', count($upgrade_available));
     if (count($upgrade_available) == 0 && (int) Tools::getValue('check') == 1) {
         $this->confirmations[] = $this->l('Everything is up-to-date');
     }
     // Init tpl vars for smarty
     $tpl_vars = array('token' => $this->token, 'upgrade_available' => $upgrade_available, 'currentIndex' => self::$currentIndex, 'dirNameCurrentIndex' => dirname(self::$currentIndex), 'ajaxCurrentIndex' => str_replace('index', 'ajax-tab', self::$currentIndex), 'autocompleteList' => rtrim($autocomplete_list, ' ,') . '];', 'showTypeModules' => $this->filter_configuration['PS_SHOW_TYPE_MODULES_' . (int) $this->id_employee], 'showCountryModules' => $this->filter_configuration['PS_SHOW_COUNTRY_MODULES_' . (int) $this->id_employee], 'showInstalledModules' => $this->filter_configuration['PS_SHOW_INSTALLED_MODULES_' . (int) $this->id_employee], 'showEnabledModules' => $this->filter_configuration['PS_SHOW_ENABLED_MODULES_' . (int) $this->id_employee], 'nameCountryDefault' => Country::getNameById($this->context->language->id, Configuration::get('PS_COUNTRY_DEFAULT')), 'isoCountryDefault' => $this->iso_default_country, 'categoryFiltered' => $category_filtered, 'modules' => $modules, 'nb_modules' => $this->nb_modules_total, 'nb_modules_favorites' => count($this->context->employee->favoriteModulesList()), 'nb_modules_installed' => $this->nb_modules_installed, 'nb_modules_uninstalled' => $this->nb_modules_total - $this->nb_modules_installed, 'nb_modules_activated' => $this->nb_modules_activated, 'nb_modules_unactivated' => $this->nb_modules_installed - $this->nb_modules_activated, 'list_modules_categories' => $cleaned_list, 'list_modules_authors' => $this->modules_authors, 'add_permission' => $this->tabAccess['add'], 'tab_modules_preferences' => $tab_modules_preferences, 'kpis' => $this->renderKpis(), 'module_name' => Tools::getValue('module_name'), 'page_header_toolbar_title' => $this->page_header_toolbar_title, 'page_header_toolbar_btn' => $this->page_header_toolbar_btn, 'modules_uri' => __PS_BASE_URI__ . basename(_PS_MODULE_DIR_), 'dont_filter' => $dont_filter, 'is_contributor' => (int) $this->context->cookie->is_contributor, 'maintenance_mode' => !(bool) Configuration::Get('PS_SHOP_ENABLE'));
     if ($this->logged_on_addons) {
         $tpl_vars['logged_on_addons'] = 1;
         $tpl_vars['username_addons'] = $this->context->cookie->username_addons;
     }
     $smarty->assign($tpl_vars);
 }
예제 #6
0
 /**
  * Returns the taxes calculator associated to the carrier
  *
  * @since 1.5
  * @param Address $address
  * @return
  */
 public function getTaxCalculator(Address $address, $id_order = null, $use_average_tax_of_products = false)
 {
     if ($use_average_tax_of_products) {
         return Adapter_ServiceLocator::get('AverageTaxOfProductsTaxCalculator')->setIdOrder($id_order);
     } else {
         $tax_manager = TaxManagerFactory::getManager($address, $this->getIdTaxRulesGroup());
         return $tax_manager->getTaxCalculator();
     }
 }
예제 #7
0
파일: Product.php 프로젝트: yewed/share
 public function delete()
 {
     /*
      * @since 1.5.0
      * It is NOT possible to delete a product if there are currently:
      * - physical stock for this product
      * - supply order(s) for this product
      */
     if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && $this->advanced_stock_management) {
         $stock_manager = StockManagerFactory::getManager();
         $physical_quantity = $stock_manager->getProductPhysicalQuantities($this->id, 0);
         $real_quantity = $stock_manager->getProductRealQuantities($this->id, 0);
         if ($physical_quantity > 0) {
             return false;
         }
         if ($real_quantity > $physical_quantity) {
             return false;
         }
         $warehouse_product_locations = Adapter_ServiceLocator::get('Core_Foundation_Database_EntityManager')->getRepository('WarehouseProductLocation')->findByIdProduct($this->id);
         foreach ($warehouse_product_locations as $warehouse_product_location) {
             $warehouse_product_location->delete();
         }
         $stocks = Adapter_ServiceLocator::get('Core_Foundation_Database_EntityManager')->getRepository('Stock')->findByIdProduct($this->id);
         foreach ($stocks as $stock) {
             $stock->delete();
         }
     }
     $result = parent::delete();
     // Removes the product from StockAvailable, for the current shop
     StockAvailable::removeProductFromStockAvailable($this->id);
     $result &= $this->deleteProductAttributes() && $this->deleteImages() && $this->deleteSceneProducts();
     // If there are still entries in product_shop, don't remove completely the product
     if ($this->hasMultishopEntries()) {
         return true;
     }
     Hook::exec('actionProductDelete', array('id_product' => (int) $this->id, 'product' => $this));
     if (!$result || !GroupReduction::deleteProductReduction($this->id) || !$this->deleteCategories(true) || !$this->deleteProductFeatures() || !$this->deleteTags() || !$this->deleteCartProducts() || !$this->deleteAttributesImpacts() || !$this->deleteAttachments(false) || !$this->deleteCustomization() || !SpecificPrice::deleteByProductId((int) $this->id) || !$this->deletePack() || !$this->deleteProductSale() || !$this->deleteSearchIndexes() || !$this->deleteAccessories() || !$this->deleteFromAccessories() || !$this->deleteFromSupplier() || !$this->deleteDownload() || !$this->deleteFromCartRules()) {
         return false;
     }
     return true;
 }
예제 #8
0
 public static function setServiceContainerInstance(Core_Foundation_IoC_Container $container)
 {
     self::$service_container = $container;
 }
 /**
  * Will update Product available stock int he given declinaison. If product is a Pack, could decrease the sub products.
  * If Product is contained in a Pack, Pack could be decreased or not (only if sub product stocks become not sufficient).
  *
  * @param Product $product The product to update its stockAvailable
  * @param integer $id_product_attribute The declinaison to update (null if not)
  * @param integer $delta_quantity The quantity change (positive or negative)
  * @param integer|null $id_shop Optional
  */
 public function updateQuantity($product, $id_product_attribute, $delta_quantity, $id_shop = null)
 {
     $stockManager = Adapter_ServiceLocator::get('Adapter_StockManager');
     $stockAvailable = $stockManager->getStockAvailableByProduct($product, $id_product_attribute, $id_shop);
     $packItemsManager = Adapter_ServiceLocator::get('Adapter_PackItemsManager');
     $cacheManager = Adapter_ServiceLocator::get('Adapter_CacheManager');
     $hookManager = Adapter_ServiceLocator::get('Adapter_HookManager');
     // Update quantity of the pack products
     if ($packItemsManager->isPack($product)) {
         // The product is a pack
         $this->updatePackQuantity($product, $stockAvailable, $delta_quantity, $id_shop);
     } else {
         // The product is not a pack
         $stockAvailable->quantity = $stockAvailable->quantity + $delta_quantity;
         $stockAvailable->id_product = (int) $product->id;
         $stockAvailable->id_product_attribute = (int) $id_product_attribute;
         $stockAvailable->update();
         // Decrease case only: the stock of linked packs should be decreased too.
         if ($delta_quantity < 0) {
             // The product is not a pack, but the product combination is part of a pack (use of isPacked, not isPack)
             if ($packItemsManager->isPacked($product, $id_product_attribute)) {
                 $this->updatePacksQuantityContainingProduct($product, $id_product_attribute, $stockAvailable, $id_shop);
             }
         }
     }
     $cacheManager->clean('StockAvailable::getQuantityAvailableByProduct_' . (int) $product->id . '*');
     $hookManager->exec('actionUpdateQuantity', array('id_product' => $product->id, 'id_product_attribute' => $id_product_attribute, 'quantity' => $stockAvailable->quantity));
 }
예제 #10
0
<?php

/*
 *  2015-2016 DOGS
 *  @author J.Podracky, L.Fisher
 *  @copyright  2015-2016 F2FCREATIVE
 */
$container_builder = new Core_Business_ContainerBuilder();
$container = $container_builder->build();
Adapter_ServiceLocator::setServiceContainerInstance($container);
예제 #11
0
    /**
     * Return available modules
     *
     * @param bool $use_config in order to use config.xml file in module dir
     * @return array Modules
     */
    public static function getModulesOnDisk($use_config = false, $logged_on_addons = false, $id_employee = false)
    {
        global $_MODULES;
        // Init var
        $module_list = array();
        $module_name_list = array();
        $modules_name_to_cursor = array();
        $errors = array();
        // Get modules directory list and memory limit
        $modules_dir = Module::getModulesDirOnDisk();
        $modules_installed = array();
        $result = Db::getInstance()->executeS('
		SELECT m.name, m.version, mp.interest, module_shop.enable_device
		FROM `' . _DB_PREFIX_ . 'module` m
		' . Shop::addSqlAssociation('module', 'm') . '
		LEFT JOIN `' . _DB_PREFIX_ . 'module_preference` mp ON (mp.`module` = m.`name` AND mp.`id_employee` = ' . (int) $id_employee . ')');
        foreach ($result as $row) {
            $modules_installed[$row['name']] = $row;
        }
        foreach ($modules_dir as $module) {
            if (Module::useTooMuchMemory()) {
                $errors[] = Tools::displayError('All modules cannot be loaded due to memory limit restrictions, please increase your memory_limit value on your server configuration');
                break;
            }
            $iso = substr(Context::getContext()->language->iso_code, 0, 2);
            // Check if config.xml module file exists and if it's not outdated
            if ($iso == 'en') {
                $config_file = _PS_MODULE_DIR_ . $module . '/config.xml';
            } else {
                $config_file = _PS_MODULE_DIR_ . $module . '/config_' . $iso . '.xml';
            }
            $xml_exist = file_exists($config_file);
            $need_new_config_file = $xml_exist ? @filemtime($config_file) < @filemtime(_PS_MODULE_DIR_ . $module . '/' . $module . '.php') : true;
            // If config.xml exists and that the use config flag is at true
            if ($use_config && $xml_exist && !$need_new_config_file) {
                // Load config.xml
                libxml_use_internal_errors(true);
                $xml_module = simplexml_load_file($config_file);
                foreach (libxml_get_errors() as $error) {
                    $errors[] = '[' . $module . '] ' . Tools::displayError('Error found in config file:') . ' ' . htmlentities($error->message);
                }
                libxml_clear_errors();
                // If no errors in Xml, no need instand and no need new config.xml file, we load only translations
                if (!count($errors) && (int) $xml_module->need_instance == 0) {
                    $file = _PS_MODULE_DIR_ . $module . '/' . Context::getContext()->language->iso_code . '.php';
                    if (Tools::file_exists_cache($file) && (include_once $file)) {
                        if (isset($_MODULE) && is_array($_MODULE)) {
                            $_MODULES = !empty($_MODULES) ? array_merge($_MODULES, $_MODULE) : $_MODULE;
                        }
                    }
                    $item = new stdClass();
                    $item->id = 0;
                    $item->warning = '';
                    foreach ($xml_module as $k => $v) {
                        $item->{$k} = (string) $v;
                    }
                    $item->displayName = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->displayName), (string) $xml_module->name));
                    $item->description = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->description), (string) $xml_module->name));
                    $item->author = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->author), (string) $xml_module->name));
                    $item->author_uri = isset($xml_module->author_uri) && $xml_module->author_uri ? stripslashes($xml_module->author_uri) : false;
                    if (isset($xml_module->confirmUninstall)) {
                        $item->confirmUninstall = Translate::getModuleTranslation((string) $xml_module->name, html_entity_decode(Module::configXmlStringFormat($xml_module->confirmUninstall)), (string) $xml_module->name);
                    }
                    $item->active = 0;
                    $item->onclick_option = false;
                    $item->trusted = Module::isModuleTrusted($item->name);
                    $module_list[] = $item;
                    $module_name_list[] = '\'' . pSQL($item->name) . '\'';
                    $modules_name_to_cursor[Tools::strtolower(strval($item->name))] = $item;
                }
            }
            // If use config flag is at false or config.xml does not exist OR need instance OR need a new config.xml file
            if (!$use_config || !$xml_exist || isset($xml_module->need_instance) && (int) $xml_module->need_instance == 1 || $need_new_config_file) {
                // If class does not exists, we include the file
                if (!class_exists($module, false)) {
                    // Get content from php file
                    $file_path = _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                    $file = trim(file_get_contents(_PS_MODULE_DIR_ . $module . '/' . $module . '.php'));
                    if (substr($file, 0, 5) == '<?php') {
                        $file = substr($file, 5);
                    }
                    if (substr($file, -2) == '?>') {
                        $file = substr($file, 0, -2);
                    }
                    // If (false) is a trick to not load the class with "eval".
                    // This way require_once will works correctly
                    if (eval('if (false){	' . $file . ' }') !== false) {
                        require_once _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                    } else {
                        $errors[] = sprintf(Tools::displayError('%1$s (parse error in %2$s)'), $module, substr($file_path, strlen(_PS_ROOT_DIR_)));
                    }
                }
                // If class exists, we just instanciate it
                if (class_exists($module, false)) {
                    $tmp_module = Adapter_ServiceLocator::get($module);
                    $item = new stdClass();
                    $item->id = $tmp_module->id;
                    $item->warning = $tmp_module->warning;
                    $item->name = $tmp_module->name;
                    $item->version = $tmp_module->version;
                    $item->tab = $tmp_module->tab;
                    $item->displayName = $tmp_module->displayName;
                    $item->description = stripslashes($tmp_module->description);
                    $item->author = $tmp_module->author;
                    $item->author_uri = isset($tmp_module->author_uri) && $tmp_module->author_uri ? $tmp_module->author_uri : false;
                    $item->limited_countries = $tmp_module->limited_countries;
                    $item->parent_class = get_parent_class($module);
                    $item->is_configurable = $tmp_module->is_configurable = method_exists($tmp_module, 'getContent') ? 1 : 0;
                    $item->need_instance = isset($tmp_module->need_instance) ? $tmp_module->need_instance : 0;
                    $item->active = $tmp_module->active;
                    $item->trusted = Module::isModuleTrusted($tmp_module->name);
                    $item->currencies = isset($tmp_module->currencies) ? $tmp_module->currencies : null;
                    $item->currencies_mode = isset($tmp_module->currencies_mode) ? $tmp_module->currencies_mode : null;
                    $item->confirmUninstall = isset($tmp_module->confirmUninstall) ? html_entity_decode($tmp_module->confirmUninstall) : null;
                    $item->description_full = stripslashes($tmp_module->description_full);
                    $item->additional_description = isset($tmp_module->additional_description) ? stripslashes($tmp_module->additional_description) : null;
                    $item->compatibility = isset($tmp_module->compatibility) ? (array) $tmp_module->compatibility : null;
                    $item->nb_rates = isset($tmp_module->nb_rates) ? (array) $tmp_module->nb_rates : null;
                    $item->avg_rate = isset($tmp_module->avg_rate) ? (array) $tmp_module->avg_rate : null;
                    $item->badges = isset($tmp_module->badges) ? (array) $tmp_module->badges : null;
                    $item->url = isset($tmp_module->url) ? $tmp_module->url : null;
                    $item->onclick_option = method_exists($module, 'onclickOption') ? true : false;
                    if ($item->onclick_option) {
                        $href = Context::getContext()->link->getAdminLink('Module', true) . '&module_name=' . $tmp_module->name . '&tab_module=' . $tmp_module->tab;
                        $item->onclick_option_content = array();
                        $option_tab = array('desactive', 'reset', 'configure', 'delete');
                        foreach ($option_tab as $opt) {
                            $item->onclick_option_content[$opt] = $tmp_module->onclickOption($opt, $href);
                        }
                    }
                    $module_list[] = $item;
                    if (!$xml_exist || $need_new_config_file) {
                        self::$_generate_config_xml_mode = true;
                        $tmp_module->_generateConfigXml();
                        self::$_generate_config_xml_mode = false;
                    }
                    unset($tmp_module);
                } else {
                    $errors[] = sprintf(Tools::displayError('%1$s (class missing in %2$s)'), $module, substr($file_path, strlen(_PS_ROOT_DIR_)));
                }
            }
        }
        // Get modules information from database
        if (!empty($module_name_list)) {
            $list = Shop::getContextListShopID();
            $sql = 'SELECT m.id_module, m.name, (
						SELECT COUNT(*) FROM ' . _DB_PREFIX_ . 'module_shop ms WHERE m.id_module = ms.id_module AND ms.id_shop IN (' . implode(',', $list) . ')
					) as total
					FROM ' . _DB_PREFIX_ . 'module m
					WHERE LOWER(m.name) IN (' . Tools::strtolower(implode(',', $module_name_list)) . ')';
            $results = Db::getInstance()->executeS($sql);
            foreach ($results as $result) {
                if (isset($modules_name_to_cursor[Tools::strtolower($result['name'])])) {
                    $module_cursor = $modules_name_to_cursor[Tools::strtolower($result['name'])];
                    $module_cursor->id = (int) $result['id_module'];
                    $module_cursor->active = $result['total'] == count($list) ? 1 : 0;
                }
            }
        }
        // Get Default Country Modules and customer module
        $files_list = array(array('type' => 'addonsNative', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST, 'loggedOnAddons' => 0), array('type' => 'addonsBought', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_CUSTOMER_MODULES_LIST, 'loggedOnAddons' => 1), array('type' => 'addonsMustHave', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_MUST_HAVE_MODULES_LIST, 'loggedOnAddons' => 0));
        foreach ($files_list as $f) {
            if (file_exists($f['file']) && ($f['loggedOnAddons'] == 0 || $logged_on_addons)) {
                if (Module::useTooMuchMemory()) {
                    $errors[] = Tools::displayError('All modules cannot be loaded due to memory limit restrictions, please increase your memory_limit value on your server configuration');
                    break;
                }
                $file = $f['file'];
                $content = Tools::file_get_contents($file);
                $xml = @simplexml_load_string($content, null, LIBXML_NOCDATA);
                if ($xml && isset($xml->module)) {
                    foreach ($xml->module as $modaddons) {
                        $flag_found = 0;
                        foreach ($module_list as $k => &$m) {
                            if (Tools::strtolower($m->name) == Tools::strtolower($modaddons->name) && !isset($m->available_on_addons)) {
                                $flag_found = 1;
                                if ($m->version != $modaddons->version && version_compare($m->version, $modaddons->version) === -1) {
                                    $module_list[$k]->version_addons = $modaddons->version;
                                }
                            }
                        }
                        if ($flag_found == 0) {
                            $item = new stdClass();
                            $item->id = 0;
                            $item->warning = '';
                            $item->type = strip_tags((string) $f['type']);
                            $item->name = strip_tags((string) $modaddons->name);
                            $item->version = strip_tags((string) $modaddons->version);
                            $item->tab = strip_tags((string) $modaddons->tab);
                            $item->displayName = strip_tags((string) $modaddons->displayName);
                            $item->description = stripslashes(strip_tags((string) $modaddons->description));
                            $item->description_full = stripslashes(strip_tags((string) $modaddons->description_full));
                            $item->author = strip_tags((string) $modaddons->author);
                            $item->limited_countries = array();
                            $item->parent_class = '';
                            $item->onclick_option = false;
                            $item->is_configurable = 0;
                            $item->need_instance = 0;
                            $item->not_on_disk = 1;
                            $item->available_on_addons = 1;
                            $item->trusted = Module::isModuleTrusted($item->name);
                            $item->active = 0;
                            $item->description_full = stripslashes($modaddons->description_full);
                            $item->additional_description = isset($modaddons->additional_description) ? stripslashes($modaddons->additional_description) : null;
                            $item->compatibility = isset($modaddons->compatibility) ? (array) $modaddons->compatibility : null;
                            $item->nb_rates = isset($modaddons->nb_rates) ? (array) $modaddons->nb_rates : null;
                            $item->avg_rate = isset($modaddons->avg_rate) ? (array) $modaddons->avg_rate : null;
                            $item->badges = isset($modaddons->badges) ? (array) $modaddons->badges : null;
                            $item->url = isset($modaddons->url) ? $modaddons->url : null;
                            if (isset($modaddons->img)) {
                                if (!file_exists(_PS_TMP_IMG_DIR_ . md5((int) $modaddons->id . '-' . $modaddons->name) . '.jpg')) {
                                    if (!file_put_contents(_PS_TMP_IMG_DIR_ . md5((int) $modaddons->id . '-' . $modaddons->name) . '.jpg', Tools::file_get_contents($modaddons->img))) {
                                        copy(_PS_IMG_DIR_ . '404.gif', _PS_TMP_IMG_DIR_ . md5((int) $modaddons->id . '-' . $modaddons->name) . '.jpg');
                                    }
                                }
                                if (file_exists(_PS_TMP_IMG_DIR_ . md5((int) $modaddons->id . '-' . $modaddons->name) . '.jpg')) {
                                    $item->image = '../img/tmp/' . md5((int) $modaddons->id . '-' . $modaddons->name) . '.jpg';
                                }
                            }
                            if ($item->type == 'addonsMustHave') {
                                $item->addons_buy_url = strip_tags((string) $modaddons->url);
                                $prices = (array) $modaddons->price;
                                $id_default_currency = Configuration::get('PS_CURRENCY_DEFAULT');
                                foreach ($prices as $currency => $price) {
                                    if ($id_currency = Currency::getIdByIsoCode($currency)) {
                                        $item->price = (double) $price;
                                        $item->id_currency = (int) $id_currency;
                                        if ($id_default_currency == $id_currency) {
                                            break;
                                        }
                                    }
                                }
                            }
                            $module_list[] = $item;
                        }
                    }
                }
            }
        }
        foreach ($module_list as $key => &$module) {
            if (defined('_PS_HOST_MODE_') && in_array($module->name, self::$hosted_modules_blacklist)) {
                unset($module_list[$key]);
            } elseif (isset($modules_installed[$module->name])) {
                $module->installed = true;
                $module->database_version = $modules_installed[$module->name]['version'];
                $module->interest = $modules_installed[$module->name]['interest'];
                $module->enable_device = $modules_installed[$module->name]['enable_device'];
            } else {
                $module->installed = false;
                $module->database_version = 0;
                $module->interest = 0;
            }
        }
        usort($module_list, create_function('$a,$b', 'return strnatcasecmp($a->displayName, $b->displayName);'));
        if ($errors) {
            if (!isset(Context::getContext()->controller) && !Context::getContext()->controller->controller_name) {
                echo '<div class="alert error"><h3>' . Tools::displayError('The following module(s) could not be loaded') . ':</h3><ol>';
                foreach ($errors as $error) {
                    echo '<li>' . $error . '</li>';
                }
                echo '</ol></div>';
            } else {
                foreach ($errors as $error) {
                    Context::getContext()->controller->errors[] = $error;
                }
            }
        }
        return $module_list;
    }
예제 #12
0
 /**
  * This method allows to fulfill the object order_invoice with sales figures
  */
 protected function setInvoiceDetails($order_invoice)
 {
     if (!$order_invoice || !is_object($order_invoice)) {
         return;
     }
     $address = new Address((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
     $carrier = new Carrier((int) $this->id_carrier);
     $tax_calculator = $carrier->getTaxCalculator($address);
     $order_invoice->total_discount_tax_excl = $this->total_discounts_tax_excl;
     $order_invoice->total_discount_tax_incl = $this->total_discounts_tax_incl;
     $order_invoice->total_paid_tax_excl = $this->total_paid_tax_excl;
     $order_invoice->total_paid_tax_incl = $this->total_paid_tax_incl;
     $order_invoice->total_products = $this->total_products;
     $order_invoice->total_products_wt = $this->total_products_wt;
     $order_invoice->total_shipping_tax_excl = $this->total_shipping_tax_excl;
     $order_invoice->total_shipping_tax_incl = $this->total_shipping_tax_incl;
     $order_invoice->shipping_tax_computation_method = $tax_calculator->computation_method;
     $order_invoice->total_wrapping_tax_excl = $this->total_wrapping_tax_excl;
     $order_invoice->total_wrapping_tax_incl = $this->total_wrapping_tax_incl;
     $order_invoice->save();
     if (Configuration::get('PS_ATCP_SHIPWRAP')) {
         $wrapping_tax_calculator = Adapter_ServiceLocator::get('AverageTaxOfProductsTaxCalculator')->setIdOrder($this->id);
     } else {
         $wrapping_tax_manager = TaxManagerFactory::getManager($address, (int) Configuration::get('PS_GIFT_WRAPPING_TAX_RULES_GROUP'));
         $wrapping_tax_calculator = $wrapping_tax_manager->getTaxCalculator();
     }
     $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl, $order_invoice->total_shipping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
     $order_invoice->saveWrappingTaxCalculator($wrapping_tax_calculator->getTaxesAmount($order_invoice->total_wrapping_tax_excl, $order_invoice->total_wrapping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
 }
예제 #13
0
 /**
  * For a given id_product and id_product_attribute updates the quantity available
  * If $avoid_parent_pack_update is true, then packs containing the given product won't be updated
  *
  * @param int $id_product
  * @param int $id_product_attribute Optional
  * @param int $delta_quantity The delta quantity to update
  * @param int $id_shop Optional
  */
 public static function updateQuantity($id_product, $id_product_attribute, $delta_quantity, $id_shop = null)
 {
     if (!Validate::isUnsignedId($id_product)) {
         return false;
     }
     $product = new Product((int) $id_product);
     if (!Validate::isLoadedObject($product)) {
         return false;
     }
     $stockManager = Adapter_ServiceLocator::get('Core_Business_Stock_StockManager');
     $stockManager->updateQuantity($product, $id_product_attribute, $delta_quantity, $id_shop = null);
     return true;
 }
예제 #14
0
    /**
     * This method allows to generate first invoice of the current order
     */
    public function setInvoice($use_existing_payment = false)
    {
        if (!$this->hasInvoice()) {
            if ($id = (int) $this->hasDelivery()) {
                $order_invoice = new OrderInvoice($id);
            } else {
                $order_invoice = new OrderInvoice();
            }
            $order_invoice->id_order = $this->id;
            if (!$id) {
                $order_invoice->number = 0;
            }
            $address = new Address((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $carrier = new Carrier((int) $this->id_carrier);
            $tax_calculator = $carrier->getTaxCalculator($address, $this->id, Configuration::get('PS_ATCP_SHIPWRAP'));
            $order_invoice->total_discount_tax_excl = $this->total_discounts_tax_excl;
            $order_invoice->total_discount_tax_incl = $this->total_discounts_tax_incl;
            $order_invoice->total_paid_tax_excl = $this->total_paid_tax_excl;
            $order_invoice->total_paid_tax_incl = $this->total_paid_tax_incl;
            $order_invoice->total_products = $this->total_products;
            $order_invoice->total_products_wt = $this->total_products_wt;
            $order_invoice->total_shipping_tax_excl = $this->total_shipping_tax_excl;
            $order_invoice->total_shipping_tax_incl = $this->total_shipping_tax_incl;
            $order_invoice->shipping_tax_computation_method = $tax_calculator->computation_method;
            $order_invoice->total_wrapping_tax_excl = $this->total_wrapping_tax_excl;
            $order_invoice->total_wrapping_tax_incl = $this->total_wrapping_tax_incl;
            // Save Order invoice
            $order_invoice->save();
            if (Configuration::get('PS_INVOICE')) {
                $this->setLastInvoiceNumber($order_invoice->id, $this->id_shop);
            }
            if (Configuration::get('PS_ATCP_SHIPWRAP')) {
                $wrapping_tax_calculator = Adapter_ServiceLocator::get('AverageTaxOfProductsTaxCalculator')->setIdOrder($this->id);
            } else {
                $wrapping_tax_manager = TaxManagerFactory::getManager($address, (int) Configuration::get('PS_GIFT_WRAPPING_TAX_RULES_GROUP'));
                $wrapping_tax_calculator = $wrapping_tax_manager->getTaxCalculator();
            }
            $order_invoice->saveCarrierTaxCalculator($tax_calculator->getTaxesAmount($order_invoice->total_shipping_tax_excl, $order_invoice->total_shipping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
            $order_invoice->saveWrappingTaxCalculator($wrapping_tax_calculator->getTaxesAmount($order_invoice->total_wrapping_tax_excl, $order_invoice->total_wrapping_tax_incl, _PS_PRICE_COMPUTE_PRECISION_, $this->round_mode));
            // Update order_carrier
            $id_order_carrier = Db::getInstance()->getValue('
				SELECT `id_order_carrier`
				FROM `' . _DB_PREFIX_ . 'order_carrier`
				WHERE `id_order` = ' . (int) $order_invoice->id_order . '
				AND (`id_order_invoice` IS NULL OR `id_order_invoice` = 0)');
            if ($id_order_carrier) {
                $order_carrier = new OrderCarrier($id_order_carrier);
                $order_carrier->id_order_invoice = (int) $order_invoice->id;
                $order_carrier->update();
            }
            // Update order detail
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_detail`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Update order payment
            if ($use_existing_payment) {
                $id_order_payments = Db::getInstance()->executeS('
					SELECT DISTINCT op.id_order_payment
					FROM `' . _DB_PREFIX_ . 'order_payment` op
					INNER JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.reference = op.order_reference)
					LEFT JOIN `' . _DB_PREFIX_ . 'order_invoice_payment` oip ON (oip.id_order_payment = op.id_order_payment)
					WHERE (oip.id_order != ' . (int) $order_invoice->id_order . ' OR oip.id_order IS NULL) AND o.id_order = ' . (int) $order_invoice->id_order);
                if (count($id_order_payments)) {
                    foreach ($id_order_payments as $order_payment) {
                        Db::getInstance()->execute('
							INSERT INTO `' . _DB_PREFIX_ . 'order_invoice_payment`
							SET
								`id_order_invoice` = ' . (int) $order_invoice->id . ',
								`id_order_payment` = ' . (int) $order_payment['id_order_payment'] . ',
								`id_order` = ' . (int) $order_invoice->id_order);
                    }
                    // Clear cache
                    Cache::clean('order_invoice_paid_*');
                }
            }
            // Update order cart rule
            Db::getInstance()->execute('
				UPDATE `' . _DB_PREFIX_ . 'order_cart_rule`
				SET `id_order_invoice` = ' . (int) $order_invoice->id . '
				WHERE `id_order` = ' . (int) $order_invoice->id_order);
            // Keep it for backward compatibility, to remove on 1.6 version
            $this->invoice_date = $order_invoice->date_add;
            if (Configuration::get('PS_INVOICE')) {
                $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                $invoice_number = Hook::exec('actionSetInvoice', array(get_class($this) => $this, get_class($order_invoice) => $order_invoice, 'use_existing_payment' => (bool) $use_existing_payment));
                if (is_numeric($invoice_number)) {
                    $this->invoice_number = (int) $invoice_number;
                } else {
                    $this->invoice_number = $this->getInvoiceNumber($order_invoice->id);
                }
            }
            $this->update();
        }
    }