/**
  * Assign price and tax to the template
  */
 protected function assignPriceAndTax()
 {
     die('coucou');
     $id_customer = isset($this->context->customer) ? (int) $this->context->customer->id : 0;
     $id_group = (int) Group::getCurrent()->id;
     $id_country = $id_customer ? (int) Customer::getCurrentCountry($id_customer) : (int) Tools::getCountry();
     $group_reduction = GroupReduction::getValueForProduct($this->product->id, $id_group);
     if ($group_reduction === false) {
         $group_reduction = Group::getReduction((int) $this->context->cookie->id_customer) / 100;
     }
     // Tax
     $tax = (double) $this->product->getTaxesRate(new Address((int) $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
     $this->context->smarty->assign('tax_rate', $tax);
     $product_price_with_tax = Product::getPriceStatic($this->product->id, true, null, 6) * 10;
     if (Product::$_taxCalculationMethod == PS_TAX_INC) {
         $product_price_with_tax = Tools::ps_round($product_price_with_tax, 2);
     }
     $product_price_without_eco_tax = (double) $product_price_with_tax - $this->product->ecotax;
     $ecotax_rate = (double) Tax::getProductEcotaxRate($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
     $ecotax_tax_amount = Tools::ps_round($this->product->ecotax, 2);
     if (Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX')) {
         $ecotax_tax_amount = Tools::ps_round($ecotax_tax_amount * (1 + $ecotax_rate / 100), 2);
     }
     $id_currency = (int) $this->context->cookie->id_currency;
     $id_product = (int) $this->product->id;
     $id_shop = $this->context->shop->id;
     $quantity_discounts = SpecificPrice::getQuantityDiscounts($id_product, $id_shop, $id_currency, $id_country, $id_group, null, true, (int) $this->context->customer->id);
     foreach ($quantity_discounts as &$quantity_discount) {
         if ($quantity_discount['id_product_attribute']) {
             $combination = new Combination((int) $quantity_discount['id_product_attribute']);
             $attributes = $combination->getAttributesName((int) $this->context->language->id);
             foreach ($attributes as $attribute) {
                 $quantity_discount['attributes'] = $attribute['name'] . ' - ';
             }
             $quantity_discount['attributes'] = rtrim($quantity_discount['attributes'], ' - ');
         }
         if ((int) $quantity_discount['id_currency'] == 0 && $quantity_discount['reduction_type'] == 'amount') {
             $quantity_discount['reduction'] = Tools::convertPriceFull($quantity_discount['reduction'], null, Context::getContext()->currency);
         }
     }
     $product_price = $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false) * 10;
     $address = new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
     $this->context->smarty->assign(array('quantity_discounts' => $this->formatQuantityDiscounts($quantity_discounts, $product_price, (double) $tax, $ecotax_tax_amount), 'ecotax_tax_inc' => $ecotax_tax_amount, 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2), 'ecotaxTax_rate' => $ecotax_rate, 'productPriceWithoutEcoTax' => (double) $product_price_without_eco_tax, 'group_reduction' => $group_reduction, 'no_tax' => Tax::excludeTaxeOption() || !$this->product->getTaxesRate($address), 'ecotax' => !count($this->errors) && $this->product->ecotax > 0 ? Tools::convertPrice((double) $this->product->ecotax) : 0, 'tax_enabled' => Configuration::get('PS_TAX') && !Configuration::get('AEUC_LABEL_TAX_INC_EXC'), 'customer_group_without_tax' => Group::getPriceDisplayMethod($this->context->customer->id_default_group)));
 }
Esempio n. 2
0
 /**
  * Apply tax to the product
  * @param object $order
  * @param array $product
  */
 protected function setProductTax(Order $order, $product)
 {
     $this->ecotax = Tools::convertPrice(floatval($product['ecotax']), intval($order->id_currency));
     // Exclude VAT
     if (!Tax::excludeTaxeOption()) {
         $this->setContext((int) $product['id_shop']);
         $this->id_tax_rules_group = (int) Product::getIdTaxRulesGroupByIdProduct((int) $product['id_product'], $this->context);
         $tax_manager = TaxManagerFactory::getManager($this->vat_address, $this->id_tax_rules_group);
         $this->tax_calculator = $tax_manager->getTaxCalculator();
         $this->tax_computation_method = (int) $this->tax_calculator->computation_method;
     }
     $this->ecotax_tax_rate = 0;
     if (!empty($product['ecotax'])) {
         $this->ecotax_tax_rate = Tax::getProductEcotaxRate($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
     }
 }
Esempio n. 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 boolean $withTaxes With or without taxes
  * @param integer $type Total type
  * @param boolean $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)
 {
     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) {
         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;
     }
     foreach ($products as $product) {
         if ($virtual_context->shop->id != $product['id_shop']) {
             $virtual_context->shop = new Shop((int) $product['id_shop']);
         }
         if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') {
             $address_id = (int) $this->id_address_invoice;
         } else {
             $address_id = (int) $product['id_address_delivery'];
         }
         // Get delivery address of the product from the cart
         if (!Address::addressExists($address_id)) {
             $address_id = null;
         }
         if ($this->_taxCalculationMethod == PS_TAX_EXC) {
             // Here taxes are computed only once the quantity has been applied to the product price
             $price = Product::getPriceStatic((int) $product['id_product'], false, (int) $product['id_product_attribute'], 2, null, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $address_id, $null, true, true, $virtual_context);
             $total_ecotax = $product['ecotax'] * (int) $product['cart_quantity'];
             $total_price = $price * (int) $product['cart_quantity'];
             if ($with_taxes) {
                 $product_tax_rate = (double) Tax::getProductTaxRate((int) $product['id_product'], (int) $address_id, $virtual_context);
                 $product_eco_tax_rate = Tax::getProductEcotaxRate((int) $address_id);
                 $total_price = ($total_price - $total_ecotax) * (1 + $product_tax_rate / 100);
                 $total_ecotax = $total_ecotax * (1 + $product_eco_tax_rate / 100);
                 $total_price = Tools::ps_round($total_price + $total_ecotax, 2);
             }
         } else {
             if ($with_taxes) {
                 $price = Product::getPriceStatic((int) $product['id_product'], true, (int) $product['id_product_attribute'], 2, null, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $null, true, true, $virtual_context);
             } else {
                 $price = Product::getPriceStatic((int) $product['id_product'], false, (int) $product['id_product_attribute'], 2, null, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, (int) $address_id ? (int) $address_id : null, $null, true, true, $virtual_context);
             }
             $total_price = Tools::ps_round($price * (int) $product['cart_quantity'], 2);
         }
         $order_total += $total_price;
     }
     $order_total_products = $order_total;
     if ($type == Cart::ONLY_DISCOUNTS) {
         $order_total = 0;
     }
     // Wrapping Fees
     $wrapping_fees = 0;
     if ($this->gift) {
         $wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int) $this->id_currency));
     }
     if ($type == Cart::ONLY_WRAPPING) {
         return $wrapping_fees;
     }
     $order_total_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
         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) {
                 $order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, $param_product ? $package : null, $use_cache), 2);
             }
             // 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), 2);
             }
         }
         $order_total_discount = min(Tools::ps_round($order_total_discount, 2), $wrapping_fees + $order_total_products + $shipping_fees);
         $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, 2);
 }
 public function process()
 {
     global $cart, $currency;
     parent::process();
     if (!($id_product = (int) Tools::getValue('id_product')) or !Validate::isUnsignedId($id_product)) {
         $this->errors[] = Tools::displayError('Product not found');
     } else {
         if (!Validate::isLoadedObject($this->product) or !$this->product->active and Tools::getValue('adtoken') != Tools::encrypt('PreviewProduct' . $this->product->id) || !file_exists(dirname(__FILE__) . '/../' . Tools::getValue('ad') . '/ajax.php')) {
             header('HTTP/1.1 404 page not found');
             $this->errors[] = Tools::displayError('Product is no longer available.');
         } elseif (!$this->product->checkAccess((int) self::$cookie->id_customer)) {
             $this->errors[] = Tools::displayError('You do not have access to this product.');
         } else {
             self::$smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int) $this->product->id));
             if (!$this->product->active) {
                 self::$smarty->assign('adminActionDisplay', true);
             }
             /* rewrited url set */
             $rewrited_url = self::$link->getProductLink($this->product->id, $this->product->link_rewrite);
             /* Product pictures management */
             require_once 'images.inc.php';
             self::$smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
             if (Tools::isSubmit('submitCustomizedDatas')) {
                 $this->pictureUpload($this->product, $cart);
                 $this->textRecord($this->product, $cart);
                 $this->formTargetFormat();
             } elseif (isset($_GET['deletePicture']) and !$cart->deletePictureToProduct((int) $this->product->id, (int) Tools::getValue('deletePicture'))) {
                 $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture');
             }
             $files = self::$cookie->getFamily('pictures_' . (int) $this->product->id);
             $textFields = self::$cookie->getFamily('textFields_' . (int) $this->product->id);
             foreach ($textFields as $key => $textField) {
                 $textFields[$key] = str_replace('<br />', "\n", $textField);
             }
             self::$smarty->assign(array('pictures' => $files, 'textFields' => $textFields));
             if ((int) Tools::getValue('pp') == 1) {
                 echo 'here1';
             }
             $productPriceWithTax = Product::getPriceStatic($id_product, true, NULL, 6);
             if (Product::$_taxCalculationMethod == PS_TAX_INC) {
                 $productPriceWithTax = Tools::ps_round($productPriceWithTax, 2);
             }
             if ((int) Tools::getValue('pp') == 1) {
                 $time2 = time();
                 echo 'time2: ' . $time2;
             }
             $productPriceWithoutEcoTax = (double) ($productPriceWithTax - $this->product->ecotax);
             $configs = Configuration::getMultiple(array('PS_ORDER_OUT_OF_STOCK', 'PS_LAST_QTIES'));
             /* Features / Values */
             $features = $this->product->getFrontFeatures((int) self::$cookie->id_lang);
             $attachments = $this->product->getAttachments((int) self::$cookie->id_lang);
             /* Category */
             $category = false;
             if (isset($_SERVER['HTTP_REFERER']) and preg_match('!^(.*)\\/([0-9]+)\\-(.*[^\\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs) and !strstr($_SERVER['HTTP_REFERER'], '.html')) {
                 if (isset($regs[2]) and is_numeric($regs[2])) {
                     if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[2])))) {
                         $category = new Category((int) $regs[2], (int) self::$cookie->id_lang);
                     }
                 } elseif (isset($regs[5]) and is_numeric($regs[5])) {
                     if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[5])))) {
                         $category = new Category((int) $regs[5], (int) self::$cookie->id_lang);
                     }
                 }
             }
             if (!$category) {
                 $category = new Category($this->product->id_category_default, (int) self::$cookie->id_lang);
             }
             if (isset($category) and Validate::isLoadedObject($category)) {
                 self::$smarty->assign(array('path' => Tools::getPath((int) $category->id, $this->product->name, true), 'category' => $category, 'subCategories' => $category->getSubCategories((int) self::$cookie->id_lang, true), 'id_category_current' => (int) $category->id, 'id_category_parent' => (int) $category->id_parent, 'return_category_name' => Tools::safeOutput($category->name)));
             } else {
                 self::$smarty->assign('path', Tools::getPath((int) $this->product->id_category_default, $this->product->name));
             }
             self::$smarty->assign('return_link', (isset($category->id) and $category->id) ? Tools::safeOutput(self::$link->getCategoryLink($category)) : 'javascript: history.back();');
             $lang = Configuration::get('PS_LANG_DEFAULT');
             if (Pack::isPack((int) $this->product->id, (int) $lang) and !Pack::isInStock((int) $this->product->id, (int) $lang)) {
                 $this->product->quantity = 0;
             }
             $group_reduction = (100 - Group::getReduction((int) self::$cookie->id_customer)) / 100;
             $id_customer = (isset(self::$cookie->id_customer) and self::$cookie->id_customer) ? (int) self::$cookie->id_customer : 0;
             $id_group = $id_customer ? (int) Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_;
             $id_country = (int) ($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
             if ((int) Tools::getValue('pp') == 1) {
                 $time3 = time();
                 echo 'time3: ' . $time3;
             }
             // Tax
             $tax = (double) Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             self::$smarty->assign('tax_rate', $tax);
             $ecotax_rate = (double) Tax::getProductEcotaxRate($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $ecotaxTaxAmount = Tools::ps_round($this->product->ecotax, 2);
             if (Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX')) {
                 $ecotaxTaxAmount = Tools::ps_round($ecotaxTaxAmount * (1 + $ecotax_rate / 100), 2);
             }
             $manufacturer = new Manufacturer((int) $this->product->id_manufacturer, 1);
             $sizechart = new Sizechart((int) $this->product->id_sizechart, 1);
             //see if the product is already in the wishlist
             if ($id_customer) {
                 $sql = "select id from ps_wishlist where id_customer = " . $id_customer . " and id_product = " . $this->product->id;
                 $res = Db::getInstance()->ExecuteS($sql);
                 if ($res) {
                     self::$smarty->assign("in_wishlist", true);
                 } else {
                     self::$smarty->assign("in_wishlist", false);
                 }
             } else {
                 self::$smarty->assign("in_wishlist", false);
             }
             self::$smarty->assign(array('quantity_discounts' => $this->formatQuantityDiscounts(SpecificPrice::getQuantityDiscounts((int) $this->product->id, (int) Shop::getCurrentShop(), (int) self::$cookie->id_currency, $id_country, $id_group), $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false), (double) $tax), 'product' => $this->product, 'ecotax_tax_inc' => $ecotaxTaxAmount, 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2), 'ecotaxTax_rate' => $ecotax_rate, 'homeSize' => Image::getSize('home'), 'product_manufacturer' => $manufacturer, 'token' => Tools::getToken(false), 'productPriceWithoutEcoTax' => (double) $productPriceWithoutEcoTax, 'features' => $features, 'attachments' => $attachments, 'allow_oosp' => $this->product->isAvailableWhenOutOfStock((int) $this->product->out_of_stock), 'last_qties' => (int) $configs['PS_LAST_QTIES'], 'group_reduction' => $group_reduction, 'col_img_dir' => _PS_COL_IMG_DIR_, 'sizechart' => $sizechart->sizechart, 'sizechart_data' => $sizechart->sizechart_data));
             self::$smarty->assign(array('HOOK_EXTRA_LEFT' => Module::hookExec('extraLeft'), 'HOOK_EXTRA_RIGHT' => Module::hookExec('extraRight'), 'HOOK_PRODUCT_OOS' => Hook::productOutOfStock($this->product), 'HOOK_PRODUCT_FOOTER' => Hook::productFooter($this->product, $category), 'HOOK_PRODUCT_ACTIONS' => Module::hookExec('productActions'), 'HOOK_PRODUCT_TAB' => Module::hookExec('productTab'), 'HOOK_PRODUCT_TAB_CONTENT' => Module::hookExec('productTabContent')));
             if ((int) Tools::getValue('pp') == 1) {
                 $time4 = time();
                 echo 'time4: ' . $time4;
             }
             $images = $this->product->getImages((int) self::$cookie->id_lang);
             $productImages = array();
             foreach ($images as $k => $image) {
                 if ($image['cover']) {
                     self::$smarty->assign('mainImage', $images[0]);
                     $cover = $image;
                     $cover['id_image'] = Configuration::get('PS_LEGACY_IMAGES') ? $this->product->id . '-' . $image['id_image'] : $image['id_image'];
                     $cover['id_image_only'] = (int) $image['id_image'];
                 }
                 $productImages[(int) $image['id_image']] = $image;
             }
             if (!isset($cover)) {
                 $cover = array('id_image' => Language::getIsoById(self::$cookie->id_lang) . '-default', 'legend' => 'No picture', 'title' => 'No picture');
             }
             $size = Image::getSize('large');
             self::$smarty->assign(array('cover' => $cover, 'imgWidth' => (int) $size['width'], 'mediumSize' => Image::getSize('medium'), 'largeSize' => Image::getSize('large'), 'accessories' => $this->product->getAccessories((int) self::$cookie->id_lang)));
             if (sizeof($productImages)) {
                 self::$smarty->assign('images', $productImages);
             }
             if ((int) Tools::getValue('pp') == 1) {
                 $time5 = time();
                 echo 'time5: ' . $time5;
             }
             /* Attributes / Groups & colors */
             $colors = array();
             //see if the product has shades
             if ($this->product->id_group && $this->product->id_group > 0) {
                 global $link;
                 $related_productIds = $this->product->getRelatedProducts();
                 $related_products = array();
                 foreach ($related_productIds as &$productId) {
                     $relProduct = new Product((int) $productId['id_product'], true, self::$cookie->id_lang);
                     $idImage = $relProduct->getCoverWs();
                     if ($idImage) {
                         $idImage = $relProduct->id . '-' . $idImage;
                     } else {
                         $idImage = Language::getIsoById(1) . '-default';
                     }
                     $relProduct->image_link = $link->getImageLink($relProduct->link_rewrite, $idImage, 'small');
                     $relProduct->link = $relProduct->getLink();
                     $related_products[] = $relProduct;
                 }
                 self::$smarty->assign('relatedProducts', $related_products);
             }
             if ((int) Tools::getValue('pp') == 1) {
                 $time6 = time();
                 echo 'time6: ' . $time6;
             }
             $attributesGroups = $this->product->getAttributesGroups((int) self::$cookie->id_lang);
             // @todo (RM) should only get groups and not all declination ?
             if (is_array($attributesGroups) and $attributesGroups) {
                 $groups = array();
                 $combinationImages = $this->product->getCombinationImages((int) self::$cookie->id_lang);
                 foreach ($attributesGroups as $k => $row) {
                     /* Color management */
                     if ((isset($row['attribute_color']) and $row['attribute_color'] or file_exists(_PS_COL_IMG_DIR_ . $row['id_attribute'] . '.jpg')) and $row['id_attribute_group'] == $this->product->id_color_default) {
                         $colors[$row['id_attribute']]['value'] = $row['attribute_color'];
                         $colors[$row['id_attribute']]['name'] = $row['attribute_name'];
                         if (!isset($colors[$row['id_attribute']]['attributes_quantity'])) {
                             $colors[$row['id_attribute']]['attributes_quantity'] = 0;
                         }
                         $colors[$row['id_attribute']]['attributes_quantity'] += (int) $row['quantity'];
                     }
                     if (!isset($groups[$row['id_attribute_group']])) {
                         $groups[$row['id_attribute_group']] = array('name' => $row['public_group_name'], 'is_color_group' => $row['is_color_group'], 'default' => -1);
                     }
                     $groups[$row['id_attribute_group']]['attributes'][$row['id_attribute']] = $row['attribute_name'];
                     if ($row['default_on'] && $groups[$row['id_attribute_group']]['default'] == -1) {
                         $groups[$row['id_attribute_group']]['default'] = (int) $row['id_attribute'];
                     }
                     if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) {
                         $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0;
                     }
                     $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int) $row['quantity'];
                     $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name'];
                     $combinations[$row['id_product_attribute']]['attributes'][] = (int) $row['id_attribute'];
                     $combinations[$row['id_product_attribute']]['price'] = (double) $row['price'];
                     $combinations[$row['id_product_attribute']]['ecotax'] = (double) $row['ecotax'];
                     $combinations[$row['id_product_attribute']]['weight'] = (double) $row['weight'];
                     $combinations[$row['id_product_attribute']]['quantity'] = (int) $row['quantity'];
                     $combinations[$row['id_product_attribute']]['reference'] = $row['reference'];
                     $combinations[$row['id_product_attribute']]['unit_impact'] = $row['unit_price_impact'];
                     $combinations[$row['id_product_attribute']]['minimal_quantity'] = $row['minimal_quantity'];
                     $combinations[$row['id_product_attribute']]['id_image'] = isset($combinationImages[$row['id_product_attribute']][0]['id_image']) ? $combinationImages[$row['id_product_attribute']][0]['id_image'] : -1;
                 }
                 if ((int) Tools::getValue('pp') == 1) {
                     $time7 = time();
                     echo 'time7: ' . $time7;
                 }
                 //wash attributes list (if some attributes are unavailables and if allowed to wash it)
                 if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) {
                     foreach ($groups as &$group) {
                         foreach ($group['attributes_quantity'] as $key => &$quantity) {
                             if (!$quantity) {
                                 unset($group['attributes'][$key]);
                             }
                         }
                     }
                     foreach ($colors as $key => $color) {
                         if (!$color['attributes_quantity']) {
                             unset($colors[$key]);
                         }
                     }
                 }
                 if ((int) Tools::getValue('pp') == 1) {
                     $time71 = time();
                     echo 'time71: ' . $time71;
                 }
                 foreach ($groups as &$group) {
                     natcasesort($group['attributes']);
                 }
                 foreach ($combinations as $id_product_attribute => $comb) {
                     $attributeList = '';
                     foreach ($comb['attributes'] as $id_attribute) {
                         $attributeList .= '\'' . (int) $id_attribute . '\',';
                     }
                     $attributeList = rtrim($attributeList, ',');
                     $combinations[$id_product_attribute]['list'] = $attributeList;
                 }
                 self::$smarty->assign(array('groups' => $groups, 'combinaisons' => $combinations, 'combinations' => $combinations, 'colors' => (sizeof($colors) and $this->product->id_color_default) ? $colors : false, 'combinationImages' => $combinationImages));
             }
             if ((int) Tools::getValue('pp') == 1) {
                 $time72 = time();
                 echo 'time72: ' . $time72;
             }
             //$newProducts = Product::getNewProducts((int)(self::$cookie->id_lang), 0, 10, false, 'date_add', 'desc');
             /*$categoryProducts = $this->getRandomCatProducts();
               self::$smarty->assign('cat_products', $categoryProducts);*/
             //$brandProducts = $this->getRandomBrandProducts();
             //self::$smarty->assign('brand_products', $brandProducts);
             if ((int) Tools::getValue('pp') == 1) {
                 $time73 = time();
                 echo ' time73: ' . $time73;
             }
             self::$smarty->assign(array('no_tax' => Tax::excludeTaxeOption() or !Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}), 'customizationFields' => $this->product->getCustomizationFields((int) self::$cookie->id_lang)));
             if ((int) Tools::getValue('pp') == 1) {
                 $time74 = time();
                 echo 'time74: ' . $time74;
             }
             // Pack management
             self::$smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, (int) self::$cookie->id_lang, true) : array());
             self::$smarty->assign('packs', Pack::getPacksTable($this->product->id, (int) self::$cookie->id_lang, true, 1));
             if ((int) Tools::getValue('pp') == 1) {
                 print_r('pack done');
             }
         }
     }
     if ((int) Tools::getValue('pp') == 1) {
         $time8 = time();
         echo 'time8: ' . $time8;
     }
     if ($this->is_saree || $this->is_lehenga) {
         if ($this->is_lehenga) {
             self::$smarty->assign('is_lehenga', $this->is_lehenga);
         }
         self::$smarty->assign('as_shown', (bool) $this->product->as_shown);
         /*if($blouse_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 1))
               self::$smarty->assign('measurement_info', $blouse_measurements);
           if($skirt_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 2))
               self::$smarty->assign('skirt_measurement_info', $skirt_measurements);*/
         if ((int) Tools::getValue('pp') == 1) {
             $time81 = time();
             echo 'time81: ' . $time81;
         }
         if ($this->is_saree) {
             //count of all styles mapped to this product
             $res = Db::getInstance()->getRow("select count(s.id_style) as style_count from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and s.style_type = 1");
             $style_count = (int) $res['style_count'];
             if ($style_count === 0) {
                 // show the default style for sarees
                 $style = array('id_style' => 1, 'style_image_small' => '1-small.png', 'style_name' => 'Round');
             } else {
                 $res = Db::getInstance()->getRow("select s.id_style, s.style_name, s.style_image_small  from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and s.style_type = 1 and ps.is_default = 1");
                 if (!empty($res)) {
                     //show the default style for this product
                     $style = array('id_style' => $res['id_style'], 'style_image_small' => $res['style_image_small'], 'style_name' => $res['style_name']);
                 }
             }
             if ((int) Tools::getValue('pp') == 1) {
                 $time82 = time();
                 echo 'time82: ' . $time82;
             }
             self::$smarty->assign('blouse_style_count', $style_count);
             self::$smarty->assign('blouse_style', $style);
         }
     } else {
         if ($this->is_skd || $this->is_skd_rts) {
             self::$smarty->assign('is_anarkali', $this->is_anarkali);
             if ($this->is_anarkali) {
                 if ($kurta_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 5)) {
                     self::$smarty->assign('kurta_measurement_info', $kurta_measurements);
                 }
             } else {
                 if ($kurta_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 3)) {
                     self::$smarty->assign('kurta_measurement_info', $kurta_measurements);
                 }
             }
             if ($salwar_measurements = $this->getCustomerMeasurements(self::$cookie->id_customer, 4)) {
                 self::$smarty->assign('salwar_measurement_info', $salwar_measurements);
             }
             //get default styles for this product (RTS)
             if ($this->is_skd_rts) {
                 $res = Db::getInstance()->ExecuteS("select count(s.id_style) as style_count, s.style_type, ps.id_product from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} group by ps.id_product,s.style_type");
                 foreach ($res as $s) {
                     $style_count = (int) $s['style_count'];
                     if ((int) $s['style_type'] === 4) {
                         self::$smarty->assign('kurta_style_count', $style_count);
                     } else {
                         if ((int) $s['style_type'] === 5) {
                             self::$smarty->assign('salwar_style_count', $style_count);
                         }
                     }
                 }
                 $res = Db::getInstance()->ExecuteS("select s.id_style, s.style_type, s.style_image_small, s.style_name from ps_styles s inner join ps_product_style ps on ps.id_style = s.id_style and ps.id_product = {$id_product} and ps.is_default = 1");
                 foreach ($res as $s) {
                     $style = array('id_style' => $s['id_style'], 'style_image_small' => $s['style_image_small'], 'style_name' => $s['style_name']);
                     if ((int) $s['style_type'] === 4) {
                         self::$smarty->assign('kurta_style', $style);
                     } else {
                         if ((int) $s['style_type'] === 5) {
                             self::$smarty->assign('salwar_style', $style);
                         }
                     }
                 }
             }
         }
     }
     self::$smarty->assign('is_bottoms', $this->is_bottoms);
     self::$smarty->assign('is_abaya', $this->is_abaya);
     self::$smarty->assign('is_wristwear', $this->is_wristwear);
     self::$smarty->assign('is_pakistani_rts', $this->is_pakistani_rts);
     if ((int) Tools::getValue('pp') == 1) {
         $time85 = time();
         echo 'time85: ' . $time85;
     }
     self::$smarty->assign(array('ENT_NOQUOTES' => ENT_NOQUOTES, 'outOfStockAllowed' => (int) Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'errors' => $this->errors, 'categories' => Category::getHomeCategories((int) self::$cookie->id_lang), 'have_image' => Product::getCover((int) Tools::getValue('id_product')), 'tax_enabled' => Configuration::get('PS_TAX'), 'display_qties' => (int) Configuration::get('PS_DISPLAY_QTIES'), 'display_ht' => !Tax::excludeTaxeOption(), 'ecotax' => !sizeof($this->errors) and $this->product->ecotax > 0 ? Tools::convertPrice((double) $this->product->ecotax) : 0, 'currencySign' => $currency->sign, 'currencyRate' => $currency->conversion_rate, 'currencyFormat' => $currency->format, 'currencyBlank' => $currency->blank, 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM')));
     if ((int) Tools::getValue('pp') == 1) {
         $time9 = time();
         echo 'time9: ' . $time9;
     }
     //add this to product stats
     //Tools::captureActivity(PSTAT_VIEWS,$id_product);
     if ((int) Tools::getValue('pp') == 1) {
         $time1 = time();
         echo 'process end: ' . $time1;
     }
 }
Esempio n. 5
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
  *
  * @param boolean $withTaxes With or without taxes
  * @param integer $type Total type
  * @return float Order total
  */
 public function getOrderTotal($withTaxes = true, $type = Cart::BOTH)
 {
     if (!$this->id) {
         return 0;
     }
     $type = (int) $type;
     if (!in_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))) {
         die(Tools::displayError());
     }
     // no shipping cost if is a cart with only virtuals products
     $virtual = $this->isVirtualCart();
     if ($virtual and $type == Cart::ONLY_SHIPPING) {
         return 0;
     }
     if ($virtual and $type == Cart::BOTH) {
         $type = Cart::BOTH_WITHOUT_SHIPPING;
     }
     $shipping_fees = ($type != Cart::BOTH_WITHOUT_SHIPPING and $type != Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING) ? $this->getOrderShippingCost(NULL, (int) $withTaxes) : 0;
     if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING) {
         $type = Cart::ONLY_PRODUCTS;
     }
     $products = $this->getProducts();
     $order_total = 0;
     if (Tax::excludeTaxeOption()) {
         $withTaxes = false;
     }
     foreach ($products as $product) {
         if ($this->_taxCalculationMethod == PS_TAX_EXC) {
             // Here taxes are computed only once the quantity has been applied to the product price
             $price = Product::getPriceStatic((int) $product['id_product'], false, (int) $product['id_product_attribute'], 2, NULL, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : NULL, (int) $this->id, $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $total_ecotax = $product['ecotax'] * (int) $product['cart_quantity'];
             $total_price = $price * (int) $product['cart_quantity'];
             if ($withTaxes) {
                 $total_price = ($total_price - $total_ecotax) * (1 + (double) Tax::getProductTaxRate((int) $product['id_product'], (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) / 100);
                 $total_ecotax = $total_ecotax * (1 + Tax::getProductEcotaxRate((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) / 100);
                 $total_price = Tools::ps_round($total_price + $total_ecotax, 2);
             }
         } else {
             $price = Product::getPriceStatic((int) $product['id_product'], true, (int) $product['id_product_attribute'], 2, NULL, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : NULL, (int) $this->id, (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')} ? (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')} : NULL);
             $total_price = Tools::ps_round($price, 2) * (int) $product['cart_quantity'];
             if (!$withTaxes) {
                 $total_price = Tools::ps_round($total_price / (1 + (double) Tax::getProductTaxRate((int) $product['id_product'], (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) / 100), 2);
             }
         }
         $order_total += $total_price;
     }
     $order_total_products = $order_total;
     if ($type == Cart::ONLY_DISCOUNTS) {
         $order_total = 0;
     }
     // Wrapping Fees
     $wrapping_fees = 0;
     if ($this->gift) {
         $wrapping_fees = (double) Configuration::get('PS_GIFT_WRAPPING_PRICE');
         if ($withTaxes) {
             $wrapping_fees_tax = new Tax((int) Configuration::get('PS_GIFT_WRAPPING_TAX'));
             $wrapping_fees *= 1 + (double) $wrapping_fees_tax->rate / 100;
         }
         $wrapping_fees = Tools::convertPrice(Tools::ps_round($wrapping_fees, 2), Currency::getCurrencyInstance((int) $this->id_currency));
     }
     if ($type != Cart::ONLY_PRODUCTS) {
         $discounts = array();
         /* Firstly get all discounts, looking for a free shipping one (in order to substract shipping fees to the total amount) */
         if ($discountIds = $this->getDiscounts(true)) {
             foreach ($discountIds as $id_discount) {
                 $discount = new Discount((int) $id_discount['id_discount']);
                 if (Validate::isLoadedObject($discount)) {
                     $discounts[] = $discount;
                     if ($discount->id_discount_type == 3) {
                         foreach ($products as $product) {
                             $categories = Discount::getCategories($discount->id);
                             if (count($categories) and Product::idIsOnCategoryId($product['id_product'], $categories)) {
                                 if ($type == Cart::ONLY_DISCOUNTS) {
                                     $order_total -= $shipping_fees;
                                 }
                                 $shipping_fees = 0;
                                 break;
                             }
                         }
                     }
                 }
             }
             /* Secondly applying all vouchers to the correct amount */
             $shrunk = false;
             foreach ($discounts as $discount) {
                 if ($discount->id_discount_type != 3) {
                     $order_total -= Tools::ps_round((double) $discount->getValue(sizeof($discounts), $order_total_products, $shipping_fees, $this->id, (int) $withTaxes), 2);
                     if ($discount->id_discount_type == 2) {
                         if (in_array($discount->behavior_not_exhausted, array(1, 2))) {
                             $shrunk = true;
                         }
                     }
                 }
             }
             $order_total_discount = 0;
             if ($shrunk and $order_total < -$wrapping_fees - $order_total_products - $shipping_fees) {
                 $order_total_discount = -$wrapping_fees - $order_total_products - $shipping_fees;
             } else {
                 $order_total_discount = $order_total;
             }
         }
     }
     if ($type == Cart::ONLY_SHIPPING) {
         return $shipping_fees;
     }
     if ($type == Cart::ONLY_WRAPPING) {
         return $wrapping_fees;
     }
     if ($type == Cart::BOTH) {
         $order_total += $shipping_fees + $wrapping_fees;
     }
     if ($order_total < 0 and $type != Cart::ONLY_DISCOUNTS) {
         return 0;
     }
     if ($type == Cart::ONLY_DISCOUNTS and isset($order_total_discount)) {
         return Tools::ps_round((double) $order_total_discount, 2);
     }
     return Tools::ps_round((double) $order_total, 2);
 }
Esempio n. 6
0
    /**
     * Return cart products
     *
     * @result array Products
     */
    public function getProducts($refresh = false, $id_product = false, $id_country = null)
    {
        if (!$this->id) {
            return array();
        }
        // Product cache must be strictly compared to NULL, or else an empty cart will add dozens of queries
        if ($this->_products !== null && !$refresh) {
            // Return product row with specified ID if it exists
            if (is_int($id_product)) {
                foreach ($this->_products as $product) {
                    if ($product['id_product'] == $id_product) {
                        return array($product);
                    }
                }
                return array();
            }
            return $this->_products;
        }
        // Build query
        $sql = new DbQuery();
        // Build SELECT
        $sql->select('cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, cp.id_shop, pl.`name`, p.`is_virtual`,
                        cp.`price_more`,cp.`price_more_text`, cp.price_more_id,
						pl.`description_short`, pl.`available_now`, pl.`available_later`, product_shop.`id_category_default`, p.`id_supplier`,
						p.`id_manufacturer`, product_shop.`on_sale`, product_shop.`ecotax`, product_shop.`additional_shipping_cost`,
						product_shop.`available_for_order`, product_shop.`price`, product_shop.`active`, product_shop.`unity`, product_shop.`unit_price_ratio`,
						stock.`quantity` AS quantity_available, p.`width`, p.`height`, p.`depth`, stock.`out_of_stock`, p.`weight`,
						p.`date_add`, p.`date_upd`, IFNULL(stock.quantity, 0) as quantity, pl.`link_rewrite`, cl.`link_rewrite` AS category,
						CONCAT(LPAD(cp.`id_product`, 10, 0), LPAD(IFNULL(cp.`id_product_attribute`, 0), 10, 0), IFNULL(cp.`id_address_delivery`, 0)) AS unique_id, cp.id_address_delivery,
						product_shop.advanced_stock_management, ps.product_supplier_reference supplier_reference');
        // Build FROM
        $sql->from('cart_product', 'cp');
        // Build JOIN
        $sql->leftJoin('product', 'p', 'p.`id_product` = cp.`id_product`');
        $sql->innerJoin('product_shop', 'product_shop', '(product_shop.`id_shop` = cp.`id_shop` AND product_shop.`id_product` = p.`id_product`)');
        $sql->leftJoin('product_lang', 'pl', '
			p.`id_product` = pl.`id_product`
			AND pl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('pl', 'cp.id_shop'));
        $sql->leftJoin('category_lang', 'cl', '
			product_shop.`id_category_default` = cl.`id_category`
			AND cl.`id_lang` = ' . (int) $this->id_lang . Shop::addSqlRestrictionOnLang('cl', 'cp.id_shop'));
        $sql->leftJoin('product_supplier', 'ps', 'ps.`id_product` = cp.`id_product` AND ps.`id_product_attribute` = cp.`id_product_attribute` AND ps.`id_supplier` = p.`id_supplier`');
        // @todo test if everything is ok, then refactorise call of this method
        $sql->join(Product::sqlStock('cp', 'cp'));
        // Build WHERE clauses
        $sql->where('cp.`id_cart` = ' . (int) $this->id);
        if ($id_product) {
            $sql->where('cp.`id_product` = ' . (int) $id_product);
        }
        $sql->where('p.`id_product` IS NOT NULL');
        // Build ORDER BY
        $sql->orderBy('cp.`date_add`, cp.`id_product`, cp.`id_product_attribute` ASC');
        if (Customization::isFeatureActive()) {
            $sql->select('cu.`id_customization`, cu.`quantity` AS customization_quantity');
            $sql->leftJoin('customization', 'cu', 'p.`id_product` = cu.`id_product` AND cp.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = ' . (int) $this->id);
            $sql->groupBy('cp.`id_product_attribute`, cp.`id_product`, cp.`id_shop`');
        } else {
            $sql->select('NULL AS customization_quantity, NULL AS id_customization');
        }
        if (Combination::isFeatureActive()) {
            $sql->select('
				product_attribute_shop.`price` AS price_attribute, product_attribute_shop.`ecotax` AS ecotax_attr,
				IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference,
				(p.`weight`+ pa.`weight`) weight_attribute,
				IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13,
				IF (IFNULL(pa.`upc`, \'\') = \'\', p.`upc`, pa.`upc`) AS upc,
				IFNULL(product_attribute_shop.`minimal_quantity`, product_shop.`minimal_quantity`) as minimal_quantity,
				IF(product_attribute_shop.wholesale_price > 0,  product_attribute_shop.wholesale_price, product_shop.`wholesale_price`) wholesale_price
			');
            $sql->leftJoin('product_attribute', 'pa', 'pa.`id_product_attribute` = cp.`id_product_attribute`');
            $sql->leftJoin('product_attribute_shop', 'product_attribute_shop', '(product_attribute_shop.`id_shop` = cp.`id_shop` AND product_attribute_shop.`id_product_attribute` = pa.`id_product_attribute`)');
        } else {
            $sql->select('p.`reference` AS reference, p.`ean13`,
				p.`upc` AS upc, product_shop.`minimal_quantity` AS minimal_quantity, product_shop.`wholesale_price` wholesale_price');
        }
        $sql->select('image_shop.`id_image` id_image, il.`legend`');
        $sql->leftJoin('image_shop', 'image_shop', 'image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop=' . (int) $this->id_shop);
        $sql->leftJoin('image_lang', 'il', 'il.`id_image` = image_shop.`id_image` AND il.`id_lang` = ' . (int) $this->id_lang);
        $result = Db::getInstance()->executeS($sql);
        // Reset the cache before the following return, or else an empty cart will add dozens of queries
        $products_ids = array();
        $pa_ids = array();
        if ($result) {
            foreach ($result as $key => $row) {
                $products_ids[] = $row['id_product'];
                $pa_ids[] = $row['id_product_attribute'];
                $specific_price = SpecificPrice::getSpecificPrice($row['id_product'], $this->id_shop, $this->id_currency, $id_country, $this->id_shop_group, $row['cart_quantity'], $row['id_product_attribute'], $this->id_customer, $this->id);
                if ($specific_price) {
                    $reduction_type_row = array('reduction_type' => $specific_price['reduction_type']);
                } else {
                    $reduction_type_row = array('reduction_type' => 0);
                }
                $result[$key] = array_merge($row, $reduction_type_row);
            }
        }
        // Thus you can avoid one query per product, because there will be only one query for all the products of the cart
        Product::cacheProductsFeatures($products_ids);
        Cart::cacheSomeAttributesLists($pa_ids, $this->id_lang);
        $this->_products = array();
        if (empty($result)) {
            return array();
        }
        $ecotax_rate = (double) Tax::getProductEcotaxRate($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
        $apply_eco_tax = Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX');
        $cart_shop_context = Context::getContext()->cloneContext();
        foreach ($result as &$row) {
            if (isset($row['ecotax_attr']) && $row['ecotax_attr'] > 0) {
                $row['ecotax'] = (double) $row['ecotax_attr'];
            }
            $row['stock_quantity'] = (int) $row['quantity'];
            // for compatibility with 1.2 themes
            $row['quantity'] = (int) $row['cart_quantity'];
            if (isset($row['id_product_attribute']) && (int) $row['id_product_attribute'] && isset($row['weight_attribute'])) {
                $row['weight'] = (double) $row['weight_attribute'];
            }
            if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_invoice') {
                $address_id = (int) $this->id_address_invoice;
            } else {
                $address_id = (int) $row['id_address_delivery'];
            }
            if (!Address::addressExists($address_id)) {
                $address_id = null;
            }
            if ($cart_shop_context->shop->id != $row['id_shop']) {
                $cart_shop_context->shop = new Shop((int) $row['id_shop']);
            }
            $address = Address::initialize($address_id, true);
            $id_tax_rules_group = Product::getIdTaxRulesGroupByIdProduct((int) $row['id_product'], $cart_shop_context);
            $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator();
            $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6, null, false, false, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $address_id, $specific_price_output, true, true, $cart_shop_context);
            $row['price_with_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6, null, false, true, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $address_id, $specific_price_output, true, true, $cart_shop_context);
            $row['price'] = $row['price_with_reduction_without_tax'] = Product::getPriceStatic((int) $row['id_product'], false, isset($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null, 6, null, false, true, $row['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : null, (int) $this->id, $address_id, $specific_price_output, true, true, $cart_shop_context);
            if ($row['price_more']) {
                $row['price'] += $row['price_more'];
            }
            switch (Configuration::get('PS_ROUND_TYPE')) {
                case Order::ROUND_TOTAL:
                    $row['total'] = $row['price_with_reduction_without_tax'] * (int) $row['cart_quantity'];
                    $row['total_wt'] = $row['price_with_reduction'] * (int) $row['cart_quantity'];
                    break;
                case Order::ROUND_LINE:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'] * (int) $row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'] * (int) $row['cart_quantity'], _PS_PRICE_COMPUTE_PRECISION_);
                    break;
                case Order::ROUND_ITEM:
                default:
                    $row['total'] = Tools::ps_round($row['price_with_reduction_without_tax'], _PS_PRICE_COMPUTE_PRECISION_) * (int) $row['cart_quantity'];
                    $row['total_wt'] = Tools::ps_round($row['price_with_reduction'], _PS_PRICE_COMPUTE_PRECISION_) * (int) $row['cart_quantity'];
                    break;
            }
            $row['price_wt'] = $row['price_with_reduction'];
            $row['description_short'] = Tools::nl2br($row['description_short']);
            if ($row['price_more']) {
                $row['price_wt'] += $row['price_more'];
            }
            // check if a image associated with the attribute exists
            if ($row['id_product_attribute']) {
                $row2 = Image::getBestImageAttribute($row['id_shop'], $this->id_lang, $row['id_product'], $row['id_product_attribute']);
                if ($row2) {
                    $row = array_merge($row, $row2);
                }
            }
            $row['reduction_applies'] = $specific_price_output && (double) $specific_price_output['reduction'];
            $row['quantity_discount_applies'] = $specific_price_output && $row['cart_quantity'] >= (int) $specific_price_output['from_quantity'];
            $row['id_image'] = Product::defineProductImage($row, $this->id_lang);
            $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']);
            $row['features'] = Product::getFeaturesStatic((int) $row['id_product']);
            if (array_key_exists($row['id_product_attribute'] . '-' . $this->id_lang, self::$_attributesLists)) {
                $row = array_merge($row, self::$_attributesLists[$row['id_product_attribute'] . '-' . $this->id_lang]);
            }
            $row = Product::getTaxesInformations($row, $cart_shop_context);
            $this->_products[] = $row;
        }
        return $this->_products;
    }
Esempio n. 7
0
 public function initFormPrices($obj)
 {
     $data = $this->createTemplate($this->tpl_form);
     $product = $obj;
     if ($obj->id) {
         $shops = Shop::getShops();
         $countries = Country::getCountries($this->context->language->id);
         $groups = Group::getGroups($this->context->language->id);
         $currencies = Currency::getCurrencies();
         $attributes = $obj->getAttributesGroups((int) $this->context->language->id);
         $combinations = array();
         foreach ($attributes as $attribute) {
             $combinations[$attribute['id_product_attribute']]['id_product_attribute'] = $attribute['id_product_attribute'];
             if (!isset($combinations[$attribute['id_product_attribute']]['attributes'])) {
                 $combinations[$attribute['id_product_attribute']]['attributes'] = '';
             }
             $combinations[$attribute['id_product_attribute']]['attributes'] .= $attribute['attribute_name'] . ' - ';
             $combinations[$attribute['id_product_attribute']]['price'] = Tools::displayPrice(Tools::convertPrice(Product::getPriceStatic((int) $obj->id, false, $attribute['id_product_attribute']), $this->context->currency), $this->context->currency);
         }
         foreach ($combinations as &$combination) {
             $combination['attributes'] = rtrim($combination['attributes'], ' - ');
         }
         $data->assign('specificPriceModificationForm', $this->_displaySpecificPriceModificationForm($this->context->currency, $shops, $currencies, $countries, $groups));
         $data->assign('ecotax_tax_excl', $obj->ecotax);
         $this->_applyTaxToEcotax($obj);
         $data->assign(array('shops' => $shops, 'admin_one_shop' => count($this->context->employee->getAssociatedShops()) == 1, 'currencies' => $currencies, 'countries' => $countries, 'groups' => $groups, 'combinations' => $combinations, 'multi_shop' => Shop::isFeatureActive(), 'link' => new Link()));
     } else {
         $this->displayWarning($this->l('You must save this product before adding specific pricing'));
         $product->id_tax_rules_group = (int) Product::getIdTaxRulesGroupMostUsed();
         $data->assign('ecotax_tax_excl', 0);
     }
     // prices part
     $data->assign(array('link' => $this->context->link, 'currency' => $currency = $this->context->currency, 'tax_rules_groups' => TaxRulesGroup::getTaxRulesGroups(true), 'taxesRatesByGroup' => TaxRulesGroup::getAssociatedTaxRatesByIdCountry($this->context->country->id), 'ecotaxTaxRate' => Tax::getProductEcotaxRate(), 'tax_exclude_taxe_option' => Tax::excludeTaxeOption(), 'ps_use_ecotax' => Configuration::get('PS_USE_ECOTAX')));
     $product->price = Tools::convertPrice($product->price, $this->context->currency, true, $this->context);
     if ($product->unit_price_ratio != 0) {
         $data->assign('unit_price', Tools::ps_round($product->price / $product->unit_price_ratio, 2));
     } else {
         $data->assign('unit_price', 0);
     }
     $data->assign('ps_tax', Configuration::get('PS_TAX'));
     $data->assign('country_display_tax_label', $this->context->country->display_tax_label);
     $data->assign(array('currency', $this->context->currency, 'product' => $product, 'token' => $this->token));
     $this->tpl_form_vars['custom_form'] = $data->fetch();
 }
Esempio n. 8
0
 public function getProducts($selected_filters, &$products, &$nb_products, &$p, &$n, &$pages_nb, &$start, &$stop, &$range, &$combinations)
 {
     global $cookie;
     $products = $this->getProductByFilters($selected_filters);
     $products = Product::getProductsProperties((int) $cookie->id_lang, $products);
     $nb_products = $this->nbr_products;
     $range = 2;
     /* how many pages around page selected */
     $n = (int) Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'));
     if ($n <= 0) {
         $n = 1;
     }
     $p = $this->page;
     if ($p < 0) {
         $p = 0;
     }
     if ($p > $nb_products / $n) {
         $p = ceil($nb_products / $n);
     }
     $pages_nb = ceil($nb_products / (int) $n);
     $start = (int) ($p - $range);
     if ($start < 1) {
         $start = 1;
     }
     $stop = (int) ($p + $range);
     if ($stop > $pages_nb) {
         $stop = (int) $pages_nb;
     }
     foreach ($products as &$product) {
         if ($product['id_product_attribute'] && isset($product['product_attribute_minimal_quantity'])) {
             $product['minimal_quantity'] = $product['product_attribute_minimal_quantity'];
         }
         $product_obj = new Product((int) $product['id_product'], $this->context->language->id);
         $product['groups'] = $product_obj->getProductCombinationsGroups((int) $product['id_product']);
         $product['obj'] = $product_obj;
         $combinations[$product['id_product']] = $product_obj->getProductAttributeCombinations($product['id_product']);
         $id_group = (int) Group::getCurrent()->id;
         $group_reduction = GroupReduction::getValueForProduct($product['id_product'], $id_group);
         if ($group_reduction === false) {
             $group_reduction = Group::getReduction((int) $this->context->cookie->id_customer) / 100;
         }
         $product['group_reduction'] = $group_reduction;
         $address = new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
         $product['no_tax'] = Tax::excludeTaxeOption() || !$product_obj->getTaxesRate($address);
         $product['customer_group_without_tax'] = Group::getPriceDisplayMethod($this->context->customer->id_default_group);
         $tax = (double) $product_obj->getTaxesRate(new Address((int) $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
         $product['tax_rate'] = $tax;
         $product['unit_price_ratio'] = $product_obj->unit_price_ratio;
         $ecotax_rate = (double) Tax::getProductEcotaxRate($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
         $product['ecotaxTax_rate'] = $ecotax_rate;
     }
 }
    function displayFormInformations($obj, $currency)
    {
        parent::displayForm(false);
        global $currentIndex, $cookie, $link;
        $default_country = new Country((int) Configuration::get('PS_COUNTRY_DEFAULT'));
        $iso = Language::getIsoById((int) $cookie->id_lang);
        $has_attribute = false;
        $qty_state = 'readonly';
        $qty = Attribute::getAttributeQty($this->getFieldValue($obj, 'id_product'));
        if ($qty === false) {
            if (Validate::isLoadedObject($obj)) {
                $qty = $this->getFieldValue($obj, 'quantity');
            } else {
                $qty = 1;
            }
            $qty_state = '';
        } else {
            $has_attribute = true;
        }
        $cover = Product::getCover($obj->id);
        $this->_applyTaxToEcotax($obj);
        echo '
		<div class="tab-page" id="step1">
			<h4 class="tab">1. ' . $this->l('Info.') . '</h4>
			<script type="text/javascript">
				$(document).ready(function() {
					updateCurrentText();
					updateFriendlyURL();
					$.ajax({
						url: "' . dirname($currentIndex) . '/ajax.php",
						cache: false,
						dataType: "json",
						data: "ajaxProductManufacturers=1",
						success: function(j) {
							var options = $("select#id_manufacturer").html();
							if (j)
							for (var i = 0; i < j.length; i++)
								options += \'<option value="\' + j[i].optionValue + \'">\' + j[i].optionDisplay + \'</option>\';
							$("select#id_manufacturer").html(options);
						},
						error: function(XMLHttpRequest, textStatus, errorThrown)
						{
							alert(\'Manufacturer ajax error: \'+textStatus);
						}

					});
					$.ajax({
						url: "' . dirname($currentIndex) . '/ajax.php",
						cache: false,
						dataType: "json",
						data: "ajaxProductSuppliers=1",
						success: function(j) {
							var options = $("select#id_supplier").html();
							if (j)
							for (var i = 0; i < j.length; i++)
								options += \'<option value="\' + j[i].optionValue + \'">\' + j[i].optionDisplay + \'</option>\';
							$("select#id_supplier").html(options);
						},
						error: function(XMLHttpRequest, textStatus, errorThrown)
						{
							alert(\'Supplier ajax error: \'+textStatus);
						}

					});
					if ($(\'#available_for_order\').is(\':checked\')){
						$(\'#show_price\').attr(\'checked\', \'checked\');
						$(\'#show_price\').attr(\'disabled\', \'disabled\');
					}
					else {
						$(\'#show_price\').attr(\'disabled\', \'\');
					}
				});
			</script>
			<b>' . $this->l('Product global information') . '</b>&nbsp;-&nbsp;';
        $preview_url = '';
        if (isset($obj->id)) {
            $preview_url = $link->getProductLink($this->getFieldValue($obj, 'id'), $this->getFieldValue($obj, 'link_rewrite', $this->_defaultFormLanguage), Category::getLinkRewrite($this->getFieldValue($obj, 'id_category_default'), (int) $cookie->id_lang));
            if (!$obj->active) {
                $admin_dir = dirname($_SERVER['PHP_SELF']);
                $admin_dir = substr($admin_dir, strrpos($admin_dir, '/') + 1);
                $token = Tools::encrypt('PreviewProduct' . $obj->id);
                $preview_url .= $obj->active ? '' : '&adtoken=' . $token . '&ad=' . $admin_dir;
            }
            echo '
			<a href="index.php?tab=AdminCatalog&id_product=' . $obj->id . '&deleteproduct&token=' . $this->token . '" style="float:right;"
			onclick="return confirm(\'' . $this->l('Are you sure?', __CLASS__, true, false) . '\');">
			<img src="../img/admin/delete.gif" alt="' . $this->l('Delete this product') . '" title="' . $this->l('Delete this product') . '" /> ' . $this->l('Delete this product') . '</a>
			<a href="' . $preview_url . '" target="_blank"><img src="../img/admin/details.gif" alt="' . $this->l('View product in shop') . '" title="' . $this->l('View product in shop') . '" /> ' . $this->l('View product in shop') . '</a>';
            if (file_exists(_PS_MODULE_DIR_ . 'statsproduct/statsproduct.php')) {
                echo '&nbsp;-&nbsp;<a href="index.php?tab=AdminStats&module=statsproduct&id_product=' . $obj->id . '&token=' . Tools::getAdminToken('AdminStats' . (int) Tab::getIdFromClassName('AdminStats') . (int) $cookie->id_employee) . '"><img src="../modules/statsproduct/logo.gif" alt="' . $this->l('View product sales') . '" title="' . $this->l('View product sales') . '" /> ' . $this->l('View product sales') . '</a>';
            }
        }
        echo '
			<hr class="clear"/>
			<br />
				<table cellpadding="5" style="width: 50%; float: left; margin-right: 20px; border-right: 1px solid #E0D0B1;">
					<tr>
						<td class="col-left">' . $this->l('Name:') . '</td>
						<td style="padding-bottom:5px;" class="translatable">';
        foreach ($this->_languages as $language) {
            echo '		<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
								<input size="43" type="text" id="name_' . $language['id_lang'] . '" name="name_' . $language['id_lang'] . '"
								value="' . stripslashes(htmlspecialchars($this->getFieldValue($obj, 'name', $language['id_lang']))) . '"' . (!$obj->id ? ' onkeyup="if (isArrowKey(event)) return; copy2friendlyURL();"' : '') . ' onkeyup="if (isArrowKey(event)) return; updateCurrentText();" onchange="updateCurrentText();" /><sup> *</sup>
								<span class="hint" name="help_box">' . $this->l('Invalid characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
							</div>';
        }
        echo '		</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Reference:') . '</td>
						<td style="padding-bottom:5px;">
							<input size="55" type="text" name="reference" value="' . htmlentities($this->getFieldValue($obj, 'reference'), ENT_COMPAT, 'UTF-8') . '" style="width: 130px; margin-right: 44px;" />
							<span class="hint" name="help_box">' . $this->l('Special characters allowed:') . ' .-_#\\<span class="hint-pointer">&nbsp;</span></span>
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Supplier Reference:') . '</td>
						<td style="padding-bottom:5px;">
							<input size="55" type="text" name="supplier_reference" value="' . htmlentities($this->getFieldValue($obj, 'supplier_reference'), ENT_COMPAT, 'UTF-8') . '" style="width: 130px; margin-right: 44px;" />
							<span class="hint" name="help_box">' . $this->l('Special characters allowed:') . ' .-_#\\<span class="hint-pointer">&nbsp;</span></span>
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('EAN13 or JAN:') . '</td>
						<td style="padding-bottom:5px;">
							<input size="55" maxlength="13" type="text" name="ean13" value="' . htmlentities($this->getFieldValue($obj, 'ean13'), ENT_COMPAT, 'UTF-8') . '" style="width: 130px; margin-right: 5px;" /> <span class="small">' . $this->l('(Europe, Japan)') . '</span>
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('UPC:') . '</td>
						<td style="padding-bottom:5px;">
							<input size="55" maxlength="12" type="text" name="upc" value="' . htmlentities($this->getFieldValue($obj, 'upc'), ENT_COMPAT, 'UTF-8') . '" style="width: 130px; margin-right: 5px;" /> <span class="small">' . $this->l('(US, Canada)') . '</span>
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Location (warehouse):') . '</td>
						<td style="padding-bottom:5px;">
							<input size="55" type="text" name="location" value="' . htmlentities($this->getFieldValue($obj, 'location'), ENT_COMPAT, 'UTF-8') . '" style="width: 130px; margin-right: 44px;" />
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Width ( package ) :') . '</td>
						<td style="padding-bottom:5px;">
							<input size="6" maxlength="6" name="width" type="text" value="' . htmlentities($this->getFieldValue($obj, 'width'), ENT_COMPAT, 'UTF-8') . '" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, \'.\');" /> ' . Configuration::get('PS_DIMENSION_UNIT') . '
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Height ( package ) :') . '</td>
						<td style="padding-bottom:5px;">
							<input size="6" maxlength="6" name="height" type="text" value="' . htmlentities($this->getFieldValue($obj, 'height'), ENT_COMPAT, 'UTF-8') . '" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, \'.\');" /> ' . Configuration::get('PS_DIMENSION_UNIT') . '
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Deep ( package ) :') . '</td>
						<td style="padding-bottom:5px;">
							<input size="6" maxlength="6" name="depth" type="text" value="' . htmlentities($this->getFieldValue($obj, 'depth'), ENT_COMPAT, 'UTF-8') . '" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, \'.\');" /> ' . Configuration::get('PS_DIMENSION_UNIT') . '
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Weight ( package ) :') . '</td>
						<td style="padding-bottom:5px;">
							<input size="6" maxlength="6" name="weight" type="text" value="' . htmlentities($this->getFieldValue($obj, 'weight'), ENT_COMPAT, 'UTF-8') . '" onKeyUp="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, \'.\');" /> ' . Configuration::get('PS_WEIGHT_UNIT') . '
						</td>
					</tr>
				</table>
				<table cellpadding="5" style="width: 40%; float: left; margin-left: 10px;">
					<tr>
						<td style="vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">' . $this->l('Status:') . '</td>
						<td style="padding-bottom:5px;">
							<input style="float:left;" onclick="toggleDraftWarning(false);showOptions(true);" type="radio" name="active" id="active_on" value="1" ' . ($this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '') . '/>
							<label for="active_on" class="t"><img src="../img/admin/enabled.gif" alt="' . $this->l('Enabled') . '" title="' . $this->l('Enabled') . '" style="float:left; padding:0px 5px 0px 5px;" />' . $this->l('Enabled') . '</label>
							<br class="clear" />
							<input style="float:left;" onclick="toggleDraftWarning(true);showOptions(false);"  type="radio" name="active" id="active_off" value="0" ' . (!$this->getFieldValue($obj, 'active') ? 'checked="checked" ' : '') . '/>
							<label for="active_off" class="t"><img src="../img/admin/disabled.gif" alt="' . $this->l('Disabled') . '" title="' . $this->l('Disabled') . '" style="float:left; padding:0px 5px 0px 5px" />' . $this->l('Disabled') . ($obj->active ? '' : ' (<a href="' . $preview_url . '" alt="" target="_blank">' . $this->l('View product in shop') . '</a>)') . '</label>
						</td>
					</tr>
					<tr id="product_options" ' . (!$obj->active ? 'style="display:none"' : '') . '>
						<td style="vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">' . $this->l('Options:') . '</td>
						<td style="padding-bottom:5px;">
							<input style="float: left;" type="checkbox" name="available_for_order" id="available_for_order" value="1" ' . ($this->getFieldValue($obj, 'available_for_order') ? 'checked="checked" ' : '') . ' onclick="if ($(this).is(\':checked\')){$(\'#show_price\').attr(\'checked\', \'checked\');$(\'#show_price\').attr(\'disabled\', \'disabled\');}else{$(\'#show_price\').attr(\'disabled\', \'\');}"/>
							<label for="available_for_order" class="t"><img src="../img/admin/products.gif" alt="' . $this->l('available for order') . '" title="' . $this->l('available for order') . '" style="float:left; padding:0px 5px 0px 5px" />' . $this->l('available for order') . '</label>
							<br class="clear" />
							<input style="float: left;" type="checkbox" name="show_price" id="show_price" value="1" ' . ($this->getFieldValue($obj, 'show_price') ? 'checked="checked" ' : '') . ' />
							<label for="show_price" class="t"><img src="../img/admin/gold.gif" alt="' . $this->l('display price') . '" title="' . $this->l('show price') . '" style="float:left; padding:0px 5px 0px 5px" />' . $this->l('show price') . '</label>
							<br class="clear" />
							<input style="float: left;" type="checkbox" name="online_only" id="online_only" value="1" ' . ($this->getFieldValue($obj, 'online_only') ? 'checked="checked" ' : '') . ' />
							<label for="online_only" class="t"><img src="../img/admin/basket_error.png" alt="' . $this->l('online only') . '" title="' . $this->l('online only') . '" style="float:left; padding:0px 5px 0px 5px" />' . $this->l('online only (not sold in store)') . '</label>
						</td>
					</tr>
					<tr>
						<td style="vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">' . $this->l('Condition:') . '</td>
						<td style="padding-bottom:5px;">
							<select name="condition" id="condition">
								<option value="new" ' . ($obj->condition == 'new' ? 'selected="selected"' : '') . '>' . $this->l('New') . '</option>
								<option value="used" ' . ($obj->condition == 'used' ? 'selected="selected"' : '') . '>' . $this->l('Used') . '</option>
								<option value="refurbished" ' . ($obj->condition == 'refurbished' ? 'selected="selected"' : '') . '>' . $this->l('Refurbished') . '</option>
							</select>
						</td>
					</tr>
					<tr>
						<td style="vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">' . $this->l('Manufacturer:') . '</td>
						<td style="padding-bottom:5px;">
							<select name="id_manufacturer" id="id_manufacturer">
								<option value="0">-- ' . $this->l('Choose (optional)') . ' --</option>';
        if ($id_manufacturer = $this->getFieldValue($obj, 'id_manufacturer')) {
            echo '				<option value="' . $id_manufacturer . '" selected="selected">' . Manufacturer::getNameById($id_manufacturer) . '</option>
								<option disabled="disabled">----------</option>';
        }
        echo '
							</select>&nbsp;&nbsp;&nbsp;<a href="?tab=AdminManufacturers&addmanufacturer&token=' . Tools::getAdminToken('AdminManufacturers' . (int) Tab::getIdFromClassName('AdminManufacturers') . (int) $cookie->id_employee) . '" onclick="return confirm(\'' . $this->l('Are you sure you want to delete product information entered?', __CLASS__, true, false) . '\');"><img src="../img/admin/add.gif" alt="' . $this->l('Create') . '" title="' . $this->l('Create') . '" /> <b>' . $this->l('Create') . '</b></a>
						</td>
					</tr>
					<tr>
						<td style="vertical-align:top;text-align:right;padding-right:10px;font-weight:bold;">' . $this->l('Supplier:') . '</td>
						<td style="padding-bottom:5px;">
							<select name="id_supplier" id="id_supplier">
								<option value="0">-- ' . $this->l('Choose (optional)') . ' --</option>';
        if ($id_supplier = $this->getFieldValue($obj, 'id_supplier')) {
            echo '				<option value="' . $id_supplier . '" selected="selected">' . Supplier::getNameById($id_supplier) . '</option>
								<option disabled="disabled">----------</option>';
        }
        echo '
							</select>&nbsp;&nbsp;&nbsp;<a href="?tab=AdminSuppliers&addsupplier&token=' . Tools::getAdminToken('AdminSuppliers' . (int) Tab::getIdFromClassName('AdminSuppliers') . (int) $cookie->id_employee) . '" onclick="return confirm(\'' . $this->l('Are you sure you want to delete entered product information?', __CLASS__, true, false) . '\');"><img src="../img/admin/add.gif" alt="' . $this->l('Create') . '" title="' . $this->l('Create') . '" /> <b>' . $this->l('Create') . '</b></a>
						</td>
					</tr>
				</table>
				<div class="clear"></div>
				<table cellpadding="5" style="width: 100%;">
					<tr><td colspan="2"><hr style="width:100%;" /></td></tr>';
        $this->displayPack($obj);
        echo '		<tr><td colspan="2"><hr style="width:100%;" /></td></tr>';
        /*
         * Form for add a virtual product like software, mp3, etc...
         */
        $productDownload = new ProductDownload();
        if ($id_product_download = $productDownload->getIdFromIdProduct($this->getFieldValue($obj, 'id'))) {
            $productDownload = new ProductDownload($id_product_download);
        }
        ?>
	<script type="text/javascript">
	// <![CDATA[
		ThickboxI18nImage = '<?php 
        echo $this->l('Image');
        ?>
';
		ThickboxI18nOf = '<?php 
        echo $this->l('of');
        ?>
';
		ThickboxI18nClose = '<?php 
        echo $this->l('Close');
        ?>
';
		ThickboxI18nOrEscKey = '<?php 
        echo $this->l('(or "Esc")');
        ?>
';
		ThickboxI18nNext = '<?php 
        echo $this->l('Next >');
        ?>
';
		ThickboxI18nPrev = '<?php 
        echo $this->l('< Previous');
        ?>
';
		tb_pathToImage = '../img/loadingAnimation.gif';
	//]]>
	</script>
	<script type="text/javascript" src="<?php 
        echo _PS_JS_DIR_;
        ?>
jquery/thickbox-modified.js"></script>
	<script type="text/javascript" src="<?php 
        echo _PS_JS_DIR_;
        ?>
jquery/ajaxfileupload.js"></script>
	<script type="text/javascript" src="<?php 
        echo _PS_JS_DIR_;
        ?>
date.js"></script>
	<style type="text/css">
		<!--
		@import url(<?php 
        echo _PS_CSS_DIR_;
        ?>
thickbox.css);
		-->
	</style>
	<script type="text/javascript">
	//<![CDATA[
	function toggleVirtualProduct(elt)
	{
		if (elt.checked)
		{
			$('#virtual_good').show('slow');
			$('#virtual_good_more').show('slow');
			getE('out_of_stock_1').checked = 'checked';
			getE('out_of_stock_2').disabled = 'disabled';
			getE('out_of_stock_3').disabled = 'disabled';
			getE('label_out_of_stock_2').setAttribute('for', '');
			getE('label_out_of_stock_3').setAttribute('for', '');
		}
		else
		{
			$('#virtual_good').hide('slow');
			$('#virtual_good_more').hide('slow');
			getE('out_of_stock_2').disabled = false;
			getE('out_of_stock_3').disabled = false;
			getE('label_out_of_stock_2').setAttribute('for', 'out_of_stock_2');
			getE('label_out_of_stock_3').setAttribute('for', 'out_of_stock_3');
		}
	}

	function uploadFile()
	{
		$.ajaxFileUpload (
			{
				url:'./uploadProductFile.php',
				secureuri:false,
				fileElementId:'virtual_product_file',
				dataType: 'xml',

				success: function (data, status)
				{
					data = data.getElementsByTagName('return')[0];
					var result = data.getAttribute("result");
					var msg = data.getAttribute("msg");
					var fileName = data.getAttribute("filename");

					if (result == "error")
					{
						$("#upload-confirmation").html('<p>error: ' + msg + '</p>');
					}
					else
					{
						$('#virtual_product_file').remove();
						$('#virtual_product_file_label').hide();
						$('#file_missing').hide();
						new_href = $('#delete_downloadable_product').attr('href').replace('%26deleteVirtualProduct%3Dtrue', '%26file%3D'+msg+'%26deleteVirtualProduct%3Dtrue');
						$('#delete_downloadable_product').attr('href', new_href);
						$('#delete_downloadable_product').show();
						$('#virtual_product_name').attr('value', fileName);
						$('#upload-confirmation').html(
							'<a class="link" href="get-file-admin.php?file='+msg+'&filename='+fileName+'"><?php 
        echo $this->l('The file');
        ?>
&nbsp;"' + fileName + '"&nbsp;<?php 
        echo $this->l('has successfully been uploaded');
        ?>
</a>' +
							'<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="' + msg + '" />');
					}
				}
			}
		);
	}

	//]]>
	</script>
	<?php 
        echo '
		<script type="text/javascript" src="../js/price.js"></script>
		<script type="text/javascript">
			var newLabel = \'' . $this->l('New label') . '\';
			var choose_language = \'' . $this->l('Choose language:') . '\';
			var required = \'' . $this->l('required') . '\';
			var customizationUploadableFileNumber = ' . (int) $this->getFieldValue($obj, 'uploadable_files') . ';
			var customizationTextFieldNumber = ' . (int) $this->getFieldValue($obj, 'text_fields') . ';
			var uploadableFileLabel = 0;
			var textFieldLabel = 0;
		</script>';
        ?>
	<tr>
		<td colspan="2">
			<p><input type="checkbox" id="is_virtual_good" name="is_virtual_good" value="true" onclick="toggleVirtualProduct(this);" <?php 
        if (($productDownload->id or Tools::getValue('is_virtual_good') == 'true') and $productDownload->active) {
            echo 'checked="checked"';
        }
        ?>
 />
			<label for="is_virtual_good" class="t bold" style="color: black;"><?php 
        echo $this->l('Is this a downloadable product?');
        ?>
</label></p>
			<div id="virtual_good" <?php 
        if (!$productDownload->id or !$productDownload->active) {
            echo 'style="display:none;"';
        }
        ?>
 >
	<?php 
        if (!ProductDownload::checkWritableDir()) {
            ?>
		<p class="alert">
			<?php 
            echo $this->l('Your download repository is not writable.');
            ?>
<br/>
			<?php 
            echo realpath(_PS_DOWNLOAD_DIR_);
            ?>
		</p>
	<?php 
        } else {
            ?>
			<?php 
            if ($productDownload->id) {
                echo '<input type="hidden" id="virtual_product_id" name="virtual_product_id" value="' . $productDownload->id . '" />';
            }
            ?>
				<p class="block">
	<?php 
            if (!$productDownload->checkFile()) {
                ?>

				<div style="padding:5px;width:50%;float:left;margin-right:20px;border-right:1px solid #E0D0B1">
		<?php 
                if ($productDownload->id) {
                    ?>
					<p class="alert" id="file_missing">
						<?php 
                    echo $this->l('This product is missing');
                    ?>
:<br/>
						<?php 
                    echo realpath(_PS_DOWNLOAD_DIR_) . '/' . $productDownload->physically_filename;
                    ?>
					</p>
		<?php 
                }
                ?>
					<p><?php 
                $max_upload = (int) ini_get('upload_max_filesize');
                $max_post = (int) ini_get('post_max_size');
                $upload_mb = min($max_upload, $max_post);
                echo $this->l('Your server\'s maximum upload file size is') . ':&nbsp;' . $upload_mb . $this->l('Mb');
                ?>
</p>
					<?php 
                if (!strval(Tools::getValue('virtual_product_filename'))) {
                    ?>
					<label id="virtual_product_file_label" for="virtual_product_file" class="t"><?php 
                    echo $this->l('Upload a file');
                    ?>
</label>
					<p><input type="file" id="virtual_product_file" name="virtual_product_file" onchange="uploadFile();" /></p>
					<?php 
                }
                ?>
					<div id="upload-confirmation">
					<?php 
                if ($up_filename = strval(Tools::getValue('virtual_product_filename'))) {
                    ?>
						<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="<?php 
                    echo $up_filename;
                    ?>
" />
					<?php 
                }
                ?>
					</div>
					<a id="delete_downloadable_product" style="display:none;" href="confirm.php?height=200&amp;width=300&amp;modal=true&amp;referer=<?php 
                echo rawurlencode($_SERVER['REQUEST_URI'] . '&deleteVirtualProduct=true');
                ?>
" class="thickbox red" title="<?php 
                echo $this->l('Delete this file');
                ?>
"><?php 
                echo $this->l('Delete this file');
                ?>
</a>
	<?php 
            } else {
                ?>
					<input type="hidden" id="virtual_product_filename" name="virtual_product_filename" value="<?php 
                echo $productDownload->physically_filename;
                ?>
" />
					<?php 
                echo $this->l('This is the link') . ':&nbsp;' . $productDownload->getHtmlLink(false, true);
                ?>
					<a href="confirm.php?height=200&amp;width=300&amp;modal=true&amp;referer=<?php 
                echo rawurlencode($_SERVER['REQUEST_URI'] . '&deleteVirtualProduct=true');
                ?>
" class="thickbox red" title="<?php 
                echo $this->l('Delete this file');
                ?>
"><?php 
                echo $this->l('Delete this file');
                ?>
</a>
	<?php 
            }
            // check if file exists
            ?>
				</p>
				<p class="block">
					<label for="virtual_product_name" class="t"><?php 
            echo $this->l('Filename');
            ?>
</label>
					<input type="text" id="virtual_product_name" name="virtual_product_name" style="width:200px" value="<?php 
            echo $productDownload->id > 0 ? $productDownload->display_filename : htmlentities(Tools::getValue('virtual_product_name'), ENT_COMPAT, 'UTF-8');
            ?>
" />
					<span class="hint" name="help_box" style="display:none;"><?php 
            echo $this->l('The full filename with its extension (e.g., Book.pdf)');
            ?>
</span>
				</p>

				</div>
				<div id="virtual_good_more" style="<?php 
            if (!$productDownload->id or !$productDownload->active) {
                echo 'display:none;';
            }
            ?>
padding:5px;width:40%;float:left;margin-left:10px">

				<p class="block">
					<label for="virtual_product_nb_downloable" class="t"><?php 
            echo $this->l('Number of downloads');
            ?>
</label>
					<input type="text" id="virtual_product_nb_downloable" name="virtual_product_nb_downloable" value="<?php 
            echo $productDownload->id > 0 ? $productDownload->nb_downloadable : htmlentities(Tools::getValue('virtual_product_nb_downloable'), ENT_COMPAT, 'UTF-8');
            ?>
" class="" size="6" />
					<span class="hint" name="help_box" style="display:none"><?php 
            echo $this->l('Number of authorized downloads per customer');
            ?>
</span>
				</p>
				<p class="block">
					<label for="virtual_product_expiration_date" class="t"><?php 
            echo $this->l('Expiration date');
            ?>
</label>
					<input type="text" id="virtual_product_expiration_date" name="virtual_product_expiration_date" value="<?php 
            echo $productDownload->id > 0 ? (!empty($productDownload->date_expiration) and $productDownload->date_expiration != '0000-00-00 00:00:00') ? date('Y-m-d', strtotime($productDownload->date_expiration)) : '' : htmlentities(Tools::getValue('virtual_product_expiration_date'), ENT_COMPAT, 'UTF-8');
            ?>
" size="11" maxlength="10" autocomplete="off" /> <?php 
            echo $this->l('Format: YYYY-MM-DD');
            ?>
					<span class="hint" name="help_box" style="display:none"><?php 
            echo $this->l('No expiration date if you leave this blank');
            ?>
</span>
				</p>
				<p class="block">
					<label for="virtual_product_nb_days" class="t"><?php 
            echo $this->l('Number of days');
            ?>
</label>
					<input type="text" id="virtual_product_nb_days" name="virtual_product_nb_days" value="<?php 
            echo $productDownload->id > 0 ? $productDownload->nb_days_accessible : htmlentities(Tools::getValue('virtual_product_nb_days'), ENT_COMPAT, 'UTF-8');
            ?>
" class="" size="4" /><sup> *</sup>
					<span class="hint" name="help_box" style="display:none"><?php 
            echo $this->l('How many days this file can be accessed by customers');
            ?>
 - <em>(<?php 
            echo $this->l('set to zero for unlimited access');
            ?>
)</em></span>
				</p>
				</div>
	<?php 
        }
        // check if download directory is writable
        ?>
			</div>
		</td>
	</tr>
	<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
	<script type="text/javascript">
		if ($('#is_virtual_good').attr('checked'))
		{
			$('#virtual_good').show('slow');
			$('#virtual_good_more').show('slow');
		}
	</script>

<?php 
        echo '
					<tr>
						<td class="col-left">' . $this->l('Pre-tax wholesale price:') . '</td>
						<td style="padding-bottom:5px;">
							' . ($currency->format % 2 != 0 ? $currency->sign . ' ' : '') . '<input size="11" maxlength="14" name="wholesale_price" type="text" value="' . htmlentities($this->getFieldValue($obj, 'wholesale_price'), ENT_COMPAT, 'UTF-8') . '" onchange="this.value = this.value.replace(/,/g, \'.\');" />' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . '
							<span style="margin-left:10px">' . $this->l('The wholesale price at which you bought this product') . '</span>
						</td>
					</tr>';
        echo '
					<tr>
						<td class="col-left">' . $this->l('Pre-tax retail price:') . '</td>
						<td style="padding-bottom:5px;">
							' . ($currency->format % 2 != 0 ? $currency->sign . ' ' : '') . '<input size="11" maxlength="14" id="priceTE" name="price" type="text" value="' . htmlentities($this->getFieldValue($obj, 'price'), ENT_COMPAT, 'UTF-8') . '" onchange="this.value = this.value.replace(/,/g, \'.\');" onkeyup="if (isArrowKey(event)) return; calcPriceTI();" />' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . '<sup> *</sup>
							<span style="margin-left:2px">' . $this->l('The pre-tax retail price to sell this product') . '</span>
						</td>
					</tr>';
        $tax_rules_groups = TaxRulesGroup::getTaxRulesGroups(true);
        $taxesRatesByGroup = TaxRulesGroup::getAssociatedTaxRatesByIdCountry(Country::getDefaultCountryId());
        $ecotaxTaxRate = Tax::getProductEcotaxRate();
        echo '<script type="text/javascript">';
        echo 'noTax = ' . (Tax::excludeTaxeOption() ? 'true' : 'false'), ";\n";
        echo 'taxesArray = new Array ();' . "\n";
        echo 'taxesArray[0] = 0', ";\n";
        foreach ($tax_rules_groups as $tax_rules_group) {
            $tax_rate = array_key_exists($tax_rules_group['id_tax_rules_group'], $taxesRatesByGroup) ? $taxesRatesByGroup[$tax_rules_group['id_tax_rules_group']] : 0;
            echo 'taxesArray[' . $tax_rules_group['id_tax_rules_group'] . ']=' . $tax_rate . "\n";
        }
        echo '
						ecotaxTaxRate = ' . $ecotaxTaxRate / 100 . ';
					</script>';
        echo '
					<tr>
						<td class="col-left">' . $this->l('Tax rule:') . '</td>
						<td style="padding-bottom:5px;">
					<span ' . (Tax::excludeTaxeOption() ? 'style="display:none;"' : '') . '>
					 <select onChange="javascript:calcPriceTI(); unitPriceWithTax(\'unit\');" name="id_tax_rules_group" id="id_tax_rules_group" ' . (Tax::excludeTaxeOption() ? 'disabled="disabled"' : '') . '>
						 <option value="0">' . $this->l('No Tax') . '</option>';
        foreach ($tax_rules_groups as $tax_rules_group) {
            echo '<option value="' . $tax_rules_group['id_tax_rules_group'] . '" ' . ($this->getFieldValue($obj, 'id_tax_rules_group') == $tax_rules_group['id_tax_rules_group'] ? ' selected="selected"' : '') . '>' . Tools::htmlentitiesUTF8($tax_rules_group['name']) . '</option>';
        }
        echo '</select>

				<a href="?tab=AdminTaxRulesGroup&addtax_rules_group&token=' . Tools::getAdminToken('AdminTaxRulesGroup' . (int) Tab::getIdFromClassName('AdminTaxRulesGroup') . (int) $cookie->id_employee) . '&id_product=' . (int) $obj->id . '" onclick="return confirm(\'' . $this->l('Are you sure you want to delete entered product information?', __CLASS__, true, false) . '\');"><img src="../img/admin/add.gif" alt="' . $this->l('Create') . '" title="' . $this->l('Create') . '" /> <b>' . $this->l('Create') . '</b></a></span>
				';
        if (Tax::excludeTaxeOption()) {
            echo '<span style="margin-left:10px; color:red;">' . $this->l('Taxes are currently disabled') . '</span> (<b><a href="index.php?tab=AdminTaxes&token=' . Tools::getAdminToken('AdminTaxes' . (int) Tab::getIdFromClassName('AdminTaxes') . (int) $cookie->id_employee) . '">' . $this->l('Tax options') . '</a></b>)';
            echo '<input type="hidden" value="' . (int) $this->getFieldValue($obj, 'id_tax_rules_group') . '" name="id_tax_rules_group" />';
        }
        echo '</td>
					</tr>
				';
        if (Configuration::get('PS_USE_ECOTAX')) {
            echo '
					<tr>
						<td class="col-left">' . $this->l('Eco-tax (tax incl.):') . '</td>
						<td style="padding-bottom:5px;">
							' . ($currency->format % 2 != 0 ? $currency->sign . ' ' : '') . '<input size="11" maxlength="14" id="ecotax" name="ecotax" type="text" value="' . $this->getFieldValue($obj, 'ecotax') . '" onkeyup="if (isArrowKey(event))return; calcPriceTE(); this.value = this.value.replace(/,/g, \'.\'); if (parseInt(this.value) > getE(\'priceTE\').value) this.value = getE(\'priceTE\').value; if (isNaN(this.value)) this.value = 0;" />' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . '
							<span style="margin-left:10px">(' . $this->l('already included in price') . ')</span>
						</td>
					</tr>';
        }
        if ($default_country->display_tax_label) {
            echo '
						<tr ' . (Tax::excludeTaxeOption() ? 'style="display:none"' : '') . '>
							<td class="col-left">' . $this->l('Retail price with tax:') . '</td>
							<td style="padding-bottom:5px;">
								' . ($currency->format % 2 != 0 ? ' ' . $currency->sign : '') . ' <input size="11" maxlength="14" id="priceTI" type="text" value="" onchange="noComma(\'priceTI\');" onkeyup="if (isArrowKey(event)) return;  calcPriceTE();" />' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . '
							</td>
						</tr>';
        } else {
            echo '<input size="11" maxlength="14" id="priceTI" type="hidden" value="" onchange="noComma(\'priceTI\');" onkeyup="if (isArrowKey(event)) return;  calcPriceTE();" />';
        }
        echo '
					<tr id="tr_unit_price">
						<td class="col-left">' . $this->l('Unit price without tax:') . '</td>
						<td style="padding-bottom:5px;">
							' . ($currency->format % 2 != 0 ? ' ' . $currency->sign : '') . ' <input size="11" maxlength="14" id="unit_price" name="unit_price" type="text" value="' . ($this->getFieldValue($obj, 'unit_price_ratio') != 0 ? Tools::ps_round($this->getFieldValue($obj, 'price') / $this->getFieldValue($obj, 'unit_price_ratio'), 2) : 0) . '" onkeyup="if (isArrowKey(event)) return ;this.value = this.value.replace(/,/g, \'.\'); unitPriceWithTax(\'unit\');"/>' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . ' ' . $this->l('per') . ' <input size="6" maxlength="10" id="unity" name="unity" type="text" value="' . (Validate::isCleanHtml($this->getFieldValue($obj, 'unity')) ? htmlentities($this->getFieldValue($obj, 'unity'), ENT_QUOTES, 'UTF-8') : '') . '" onkeyup="if (isArrowKey(event)) return ;unitySecond();" onchange="unitySecond();"/>' . (Configuration::get('PS_TAX') && $default_country->display_tax_label ? '<span style="margin-left:15px">' . $this->l('or') . ' ' . ($currency->format % 2 != 0 ? ' ' . $currency->sign : '') . '<span id="unit_price_with_tax">0.00</span>' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . ' ' . $this->l('per') . ' <span id="unity_second">' . (Validate::isCleanHtml($this->getFieldValue($obj, 'unity')) ? htmlentities($this->getFieldValue($obj, 'unity'), ENT_QUOTES, 'UTF-8') : '') . '</span> ' . $this->l('with tax') : '') . '</span>
							<p>' . $this->l('Eg. $15 per Lb') . '</p>
						</td>
					</tr>
					<tr>
						<td class="col-left">&nbsp;</td>
						<td style="padding-bottom:5px;">
							<input type="checkbox" name="on_sale" id="on_sale" style="padding-top: 5px;" ' . ($this->getFieldValue($obj, 'on_sale') ? 'checked="checked"' : '') . 'value="1" />&nbsp;<label for="on_sale" class="t">' . $this->l('Display "on sale" icon on product page and text on product listing') . '</label>
						</td>
					</tr>
					<tr>
						<td class="col-left"><b>' . $this->l('Final retail price:') . '</b></td>
						<td style="padding-bottom:5px;">
							<span style="' . ($default_country->display_tax_label ? '' : 'display:none') . '">
							' . ($currency->format % 2 != 0 ? $currency->sign . ' ' : '') . '<span id="finalPrice" style="font-weight: bold;"></span>' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . '<span' . (!Configuration::get('PS_TAX') ? ' style="display:none;"' : '') . '> (' . $this->l('tax incl.') . ')</span>
							</span>
							<span' . (!Configuration::get('PS_TAX') ? ' style="display:none;"' : '') . '>';
        if ($default_country->display_tax_label) {
            echo ' / ';
        }
        echo ($currency->format % 2 != 0 ? $currency->sign . ' ' : '') . '<span id="finalPriceWithoutTax" style="font-weight: bold;"></span>' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '') . ' ' . ($default_country->display_tax_label ? '(' . $this->l('tax excl.') . ')' : '') . '</span>
						</td>
					</tr>
					<tr>
						<td class="col-left">&nbsp;</td>
						<td>
							<div class="hint clear" style="display: block;width: 70%;">' . $this->l('You can define many discounts and specific price rules in the Prices tab') . '</div>
						</td>
					</tr>
					<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>';
        if ((int) Configuration::get('PS_STOCK_MANAGEMENT')) {
            if (!$has_attribute) {
                if ($obj->id) {
                    echo '
							<tr><td class="col-left">' . $this->l('Stock Movement:') . '</td>
								<td style="padding-bottom:5px;">
									<select id="id_mvt_reason" name="id_mvt_reason">
										<option value="-1">--</option>';
                    $reasons = StockMvtReason::getStockMvtReasons((int) $cookie->id_lang);
                    foreach ($reasons as $reason) {
                        echo '<option rel="' . $reason['sign'] . '" value="' . $reason['id_stock_mvt_reason'] . '" ' . (Configuration::get('PS_STOCK_MVT_REASON_DEFAULT') == $reason['id_stock_mvt_reason'] ? 'selected="selected"' : '') . '>' . $reason['name'] . '</option>';
                    }
                    echo '</select>
									<input id="mvt_quantity" type="text" name="mvt_quantity" size="3" maxlength="10" value="0"/>&nbsp;&nbsp;
									<span style="display:none;" id="mvt_sign"></span>
								</td>
							</tr>
							<tr>
								<td class="col-left">&nbsp;</td>
								<td>
									<div class="hint clear" style="display: block;width: 70%;">' . $this->l('Choose the reason and enter the quantity that you want to increase or decrease in your stock') . '</div>
								</td>
							</tr>';
                } else {
                    echo '<tr><td class="col-left">' . $this->l('Initial stock:') . '</td>
									<td style="padding-bottom:5px;">
										<input size="3" maxlength="10" name="quantity" type="text" value="0" />
									</td>';
                }
                echo '<tr>
								<td class="col-left">' . $this->l('Minimum quantity:') . '</td>
									<td style="padding-bottom:5px;">
										<input size="3" maxlength="10" name="minimal_quantity" id="minimal_quantity" type="text" value="' . ($this->getFieldValue($obj, 'minimal_quantity') ? $this->getFieldValue($obj, 'minimal_quantity') : 1) . '" />
										<p>' . $this->l('The minimum quantity to buy this product (set to 1 to disable this feature)') . '</p>
									</td>
								</tr>';
            }
            if ($obj->id) {
                echo '
							<tr><td class="col-left">' . $this->l('Quantity in stock:') . '</td>
								<td style="padding-bottom:5px;"><b>' . $qty . '</b><input type="hidden" name="quantity" value="' . $qty . '" /></td>
							</tr>
						';
            }
            if ($has_attribute) {
                echo '<tr>
								<td class="col-left">&nbsp;</td>
								<td>
									<div class="hint clear" style="display: block;width: 70%;">' . $this->l('You used combinations, for this reason you cannot edit your stock quantity here, but in the Combinations tab') . '</div>
								</td>
							</tr>';
            }
        } else {
            echo '<tr>
							<td colspan="2">' . $this->l('The stock management is disabled') . '</td>
						</tr>';
            echo '
						<tr>
							<td class="col-left">' . $this->l('Minimum quantity:') . '</td>
							<td style="padding-bottom:5px;">
								<input size="3" maxlength="10" name="minimal_quantity" id="minimal_quantity" type="text" value="' . ($this->getFieldValue($obj, 'minimal_quantity') ? $this->getFieldValue($obj, 'minimal_quantity') : 1) . '" />
								<p>' . $this->l('The minimum quantity to buy this product (set to 1 to disable this feature)') . '</p>
							</td>
						</tr>
					';
        }
        echo '
					<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
					<tr>
						<td class="col-left">' . $this->l('Additional shipping cost:') . '</td>
						<td style="padding-bottom:5px;">
							<input type="text" name="additional_shipping_cost" value="' . Tools::safeOutput($this->getFieldValue($obj, 'additional_shipping_cost')) . '" />' . ($currency->format % 2 == 0 ? ' ' . $currency->sign : '');
        if ($default_country->display_tax_label) {
            echo ' (' . $this->l('tax excl.') . ')';
        }
        echo '<p>' . $this->l('Carrier tax will be applied.') . '</p>
						</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Displayed text when in-stock:') . '</td>
						<td style="padding-bottom:5px;" class="translatable">';
        foreach ($this->_languages as $language) {
            echo '		<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
								<input size="30" type="text" id="available_now_' . $language['id_lang'] . '" name="available_now_' . $language['id_lang'] . '"
								value="' . stripslashes(htmlentities($this->getFieldValue($obj, 'available_now', $language['id_lang']), ENT_COMPAT, 'UTF-8')) . '" />
								<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
							</div>';
        }
        echo '			</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Displayed text when allowed to be back-ordered:') . '</td>
						<td style="padding-bottom:5px;" class="translatable">';
        foreach ($this->_languages as $language) {
            echo '		<div  class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
								<input size="30" type="text" id="available_later_' . $language['id_lang'] . '" name="available_later_' . $language['id_lang'] . '"
								value="' . stripslashes(htmlentities($this->getFieldValue($obj, 'available_later', $language['id_lang']), ENT_COMPAT, 'UTF-8')) . '" />
								<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
							</div>';
        }
        echo '	</td>
					</tr>

					<script type="text/javascript">
						calcPriceTI();
					</script>

					<tr>
						<td class="col-left">' . $this->l('When out of stock:') . '</td>
						<td style="padding-bottom:5px;">
							<input type="radio" name="out_of_stock" id="out_of_stock_1" value="0" ' . ((int) $this->getFieldValue($obj, 'out_of_stock') == 0 ? 'checked="checked"' : '') . '/> <label for="out_of_stock_1" class="t" id="label_out_of_stock_1">' . $this->l('Deny orders') . '</label>
							<br /><input type="radio" name="out_of_stock" id="out_of_stock_2" value="1" ' . ($this->getFieldValue($obj, 'out_of_stock') == 1 ? 'checked="checked"' : '') . '/> <label for="out_of_stock_2" class="t" id="label_out_of_stock_2">' . $this->l('Allow orders') . '</label>
							<br /><input type="radio" name="out_of_stock" id="out_of_stock_3" value="2" ' . ($this->getFieldValue($obj, 'out_of_stock') == 2 ? 'checked="checked"' : '') . '/> <label for="out_of_stock_3" class="t" id="label_out_of_stock_3">' . $this->l('Default:') . ' <i>' . $this->l((int) Configuration::get('PS_ORDER_OUT_OF_STOCK') ? 'Allow orders' : 'Deny orders') . '</i> (' . $this->l('as set in') . ' <a href="index.php?tab=AdminPPreferences&token=' . Tools::getAdminToken('AdminPPreferences' . (int) Tab::getIdFromClassName('AdminPPreferences') . (int) $cookie->id_employee) . '"  onclick="return confirm(\'' . $this->l('Are you sure you want to delete entered product information?', __CLASS__, true, false) . '\');">' . $this->l('Preferences') . '</a>)</label>
						</td>
					</tr>
					<tr>
						<td colspan="2" style="padding-bottom:5px;">
							<hr style="width:100%;" />
						</td>
					</tr>
					<tr>
						<td class="col-left"><label for="id_category_default" class="t">' . $this->l('Default category:') . '</label></td>
						<td>
						<div id="no_default_category" style="color: red;font-weight: bold;display: none;">' . $this->l('Please check a category in order to select the default category.') . '</div>
						<script type="text/javascript">
							var post_selected_cat;
						</script>';
        $default_category = Tools::getValue('id_category', 1);
        if (!$obj->id) {
            $selectedCat = Category::getCategoryInformations(Tools::getValue('categoryBox', array($default_category)), $this->_defaultFormLanguage);
            echo '
							<script type="text/javascript">
								post_selected_cat = \'' . implode(',', array_keys($selectedCat)) . '\';
							</script>';
        } else {
            if (Tools::isSubmit('categoryBox')) {
                $selectedCat = Category::getCategoryInformations(Tools::getValue('categoryBox', array($default_category)), $this->_defaultFormLanguage);
            } else {
                $selectedCat = Product::getProductCategoriesFull($obj->id, $this->_defaultFormLanguage);
            }
        }
        echo '<select id="id_category_default" name="id_category_default">';
        foreach ($selectedCat as $cat) {
            echo '<option value="' . $cat['id_category'] . '" ' . ($obj->id_category_default == $cat['id_category'] ? 'selected' : '') . '>' . $cat['name'] . '</option>';
        }
        echo '</select>
						</td>
					</tr>
					<tr id="tr_categories">
						<td colspan="2">
						';
        // Translations are not automatic for the moment ;)
        $trads = array('Home' => $this->l('Home'), 'selected' => $this->l('selected'), 'Collapse All' => $this->l('Collapse All'), 'Expand All' => $this->l('Expand All'), 'Check All' => $this->l('Check All'), 'Uncheck All' => $this->l('Uncheck All'));
        echo Helper::renderAdminCategorieTree($trads, $selectedCat) . '
						</td>
					</tr>
					<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
					<tr><td colspan="2">
						<span onclick="$(\'#seo\').slideToggle();" style="cursor: pointer"><img src="../img/admin/arrow.gif" alt="' . $this->l('SEO') . '" title="' . $this->l('SEO') . '" style="float:left; margin-right:5px;"/>' . $this->l('Click here to improve product\'s rank in search engines (SEO)') . '</span><br />
						<div id="seo" style="display: none; padding-top: 15px;">
							<table>
								<tr>
									<td class="col-left">' . $this->l('Meta title:') . '</td>
									<td class="translatable">';
        foreach ($this->_languages as $language) {
            echo '					<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
											<input size="55" type="text" id="meta_title_' . $language['id_lang'] . '" name="meta_title_' . $language['id_lang'] . '"
											value="' . htmlentities($this->getFieldValue($obj, 'meta_title', $language['id_lang']), ENT_COMPAT, 'UTF-8') . '" />
											<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
										</div>';
        }
        echo '						<p class="clear">' . $this->l('Product page title; leave blank to use product name') . '</p>
									</td>
								</tr>
								<tr>
									<td class="col-left">' . $this->l('Meta description:') . '</td>
									<td class="translatable">';
        foreach ($this->_languages as $language) {
            echo '					<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
											<input size="55" type="text" id="meta_description_' . $language['id_lang'] . '" name="meta_description_' . $language['id_lang'] . '"
											value="' . htmlentities($this->getFieldValue($obj, 'meta_description', $language['id_lang']), ENT_COMPAT, 'UTF-8') . '" />
											<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
										</div>';
        }
        echo '						<p class="clear">' . $this->l('A single sentence for HTML header') . '</p>
									</td>
								</tr>
								<tr>
									<td class="col-left">' . $this->l('Meta keywords:') . '</td>
									<td class="translatable">';
        foreach ($this->_languages as $language) {
            echo '					<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
											<input size="55" type="text" id="meta_keywords_' . $language['id_lang'] . '" name="meta_keywords_' . $language['id_lang'] . '"
											value="' . htmlentities($this->getFieldValue($obj, 'meta_keywords', $language['id_lang']), ENT_COMPAT, 'UTF-8') . '" />
											<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' <>;=#{}<span class="hint-pointer">&nbsp;</span></span>
										</div>';
        }
        echo '						<p class="clear">' . $this->l('Keywords for HTML header, separated by a comma') . '</p>
									</td>
								</tr>
								<tr>
									<td class="col-left">' . $this->l('Friendly URL:') . '</td>
									<td class="translatable">';
        foreach ($this->_languages as $language) {
            echo '					<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
											<input size="55" type="text" id="link_rewrite_' . $language['id_lang'] . '" name="link_rewrite_' . $language['id_lang'] . '"
											value="' . htmlentities($this->getFieldValue($obj, 'link_rewrite', $language['id_lang']), ENT_COMPAT, 'UTF-8') . '" onkeyup="if (isArrowKey(event)) return ;updateFriendlyURL();" onchange="updateFriendlyURL();" /><sup> *</sup>
											<span class="hint" name="help_box">' . $this->l('Only letters and the "less" character are allowed') . '<span class="hint-pointer">&nbsp;</span></span>
										</div>';
        }
        echo '						<p class="clear" style="padding:10px 0 0 0">' . '<a style="cursor:pointer" class="button" onmousedown="updateFriendlyURLByName();">' . $this->l('Generate') . '</a>&nbsp;' . $this->l('Friendly-url from product\'s name.') . '<br /><br />';
        echo '						' . $this->l('Product link will look like this:') . ' ' . (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . '/<b>id_product</b>-<span id="friendly-url"></span>.html</p>
									</td>
								</tr>';
        echo '</td></tr></table>
						</div>
					</td></tr>
					<tr><td colspan="2" style="padding-bottom:5px;"><hr style="width:100%;" /></td></tr>
					<tr>
						<td class="col-left">' . $this->l('Short description:') . '<br /><br /><i>(' . $this->l('appears in the product lists and on the top of the product page') . ')</i></td>
						<td style="padding-bottom:5px;" class="translatable">';
        foreach ($this->_languages as $language) {
            echo '		<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . ';float: left;">
								<textarea class="rte" cols="100" rows="10" id="description_short_' . $language['id_lang'] . '" name="description_short_' . $language['id_lang'] . '">' . htmlentities(stripslashes($this->getFieldValue($obj, 'description_short', $language['id_lang'])), ENT_COMPAT, 'UTF-8') . '</textarea>
							</div>';
        }
        echo '		</td>
					</tr>
					<tr>
						<td class="col-left">' . $this->l('Description:') . '<br /><br /><i>(' . $this->l('appears in the body of the product page') . ')</i></td>
						<td style="padding-bottom:5px;" class="translatable">';
        foreach ($this->_languages as $language) {
            echo '		<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . ';float: left;">
								<textarea class="rte" cols="100" rows="20" id="description_' . $language['id_lang'] . '" name="description_' . $language['id_lang'] . '">' . htmlentities(stripslashes($this->getFieldValue($obj, 'description', $language['id_lang'])), ENT_COMPAT, 'UTF-8') . '</textarea>
							</div>';
        }
        echo '		</td>
					</tr>';
        echo '
					<tr>
						<td class="col-left">' . $this->l('Tags:') . '</td>
						<td style="padding-bottom:5px;" class="translatable">';
        if ($obj->id) {
            $obj->tags = Tag::getProductTags((int) $obj->id);
        }
        foreach ($this->_languages as $language) {
            echo '<div class="lang_' . $language['id_lang'] . '" style="display: ' . ($language['id_lang'] == $this->_defaultFormLanguage ? 'block' : 'none') . '; float: left;">
							<input size="55" type="text" id="tags_' . $language['id_lang'] . '" name="tags_' . $language['id_lang'] . '"
							value="' . htmlentities(Tools::getValue('tags_' . $language['id_lang'], $obj->getTags($language['id_lang'], true)), ENT_COMPAT, 'UTF-8') . '" />
							<span class="hint" name="help_box">' . $this->l('Forbidden characters:') . ' !<>;?=+#"&deg;{}_$%<span class="hint-pointer">&nbsp;</span></span>
						  </div>';
        }
        echo '	<p class="clear">' . $this->l('Tags separated by commas (e.g., dvd, dvd player, hifi)') . '</p>
						</td>
					</tr>';
        $accessories = Product::getAccessoriesLight((int) $cookie->id_lang, $obj->id);
        if ($postAccessories = Tools::getValue('inputAccessories')) {
            $postAccessoriesTab = explode('-', Tools::getValue('inputAccessories'));
            foreach ($postAccessoriesTab as $accessoryId) {
                if (!$this->haveThisAccessory($accessoryId, $accessories) and $accessory = Product::getAccessoryById($accessoryId)) {
                    $accessories[] = $accessory;
                }
            }
        }
        echo '
					<tr>
						<td class="col-left">' . $this->l('Accessories:') . '<br /><br /><i>' . $this->l('(Do not forget to Save the product afterward)') . '</i></td>
						<td style="padding-bottom:5px;">
							<div id="divAccessories">';
        foreach ($accessories as $accessory) {
            echo htmlentities($accessory['name'], ENT_COMPAT, 'UTF-8') . (!empty($accessory['reference']) ? ' (' . $accessory['reference'] . ')' : '') . ' <span onclick="delAccessory(' . $accessory['id_product'] . ');" style="cursor: pointer;"><img src="../img/admin/delete.gif" class="middle" alt="" /></span><br />';
        }
        echo '</div>
							<input type="hidden" name="inputAccessories" id="inputAccessories" value="';
        foreach ($accessories as $accessory) {
            echo (int) $accessory['id_product'] . '-';
        }
        echo '" />
							<input type="hidden" name="nameAccessories" id="nameAccessories" value="';
        foreach ($accessories as $accessory) {
            echo htmlentities($accessory['name'], ENT_COMPAT, 'UTF-8') . '¤';
        }
        echo '" />
							<script type="text/javascript">
								var formProduct;
								var accessories = new Array();
							</script>

							<link rel="stylesheet" type="text/css" href="' . __PS_BASE_URI__ . 'css/jquery.autocomplete.css" />
							<script type="text/javascript" src="' . __PS_BASE_URI__ . 'js/jquery/jquery.autocomplete.js"></script>
							<div id="ajax_choose_product" style="padding:6px; padding-top:2px; width:600px;">
								<p class="clear">' . $this->l('Begin typing the first letters of the product name, then select the product from the drop-down list:') . '</p>
								<input type="text" value="" id="product_autocomplete_input" />
								<img onclick="$(this).prev().search();" style="cursor: pointer;" src="../img/admin/add.gif" alt="' . $this->l('Add an accessory') . '" title="' . $this->l('Add an accessory') . '" />
							</div>
							<script type="text/javascript">
								urlToCall = null;
								/* function autocomplete */
								$(function() {
									$(\'#product_autocomplete_input\')
										.autocomplete(\'ajax_products_list.php\', {
											minChars: 1,
											autoFill: true,
											max:20,
											matchContains: true,
											mustMatch:true,
											scroll:false,
											cacheLength:0,
											formatItem: function(item) {
												return item[1]+\' - \'+item[0];
											}
										}).result(addAccessory);
									$(\'#product_autocomplete_input\').setOptions({
										extraParams: {excludeIds : getAccessorieIds()}
									});
								});
							</script>
						</td>
					</tr>
					<tr><td colspan="2" style="padding-bottom:10px;"><hr style="width:100%;" /></td></tr>
					<tr>
						<td colspan="2" style="text-align:center;">
							<input type="submit" value="' . $this->l('Save') . '" name="submitAdd' . $this->table . '" class="button" />
							&nbsp;<input type="submit" value="' . $this->l('Save and stay') . '" name="submitAdd' . $this->table . 'AndStay" class="button" /></td>
					</tr>
				</table>
			<br />
			</div>';
        // TinyMCE
        global $cookie;
        $iso = Language::getIsoById((int) $cookie->id_lang);
        $isoTinyMCE = file_exists(_PS_ROOT_DIR_ . '/js/tiny_mce/langs/' . $iso . '.js') ? $iso : 'en';
        $ad = dirname($_SERVER["PHP_SELF"]);
        echo '
			<script type="text/javascript">
			var iso = \'' . $isoTinyMCE . '\' ;
			var pathCSS = \'' . _THEME_CSS_DIR_ . '\' ;
			var ad = \'' . $ad . '\' ;
			</script>
			<script type="text/javascript" src="' . __PS_BASE_URI__ . 'js/tiny_mce/tiny_mce.js"></script>
			<script type="text/javascript" src="' . __PS_BASE_URI__ . 'js/tinymce.inc.js"></script>
			<script type="text/javascript">
					toggleVirtualProduct(getE(\'is_virtual_good\'));
					unitPriceWithTax(\'unit\');
			</script>';
        $categoryBox = Tools::getValue('categoryBox', array());
    }
 public function process()
 {
     global $cart, $currency;
     parent::process();
     if (!Validate::isLoadedObject($this->product)) {
         $this->errors[] = Tools::displayError('Product not found');
     } else {
         if (!$this->product->active and Tools::getValue('adtoken') != Tools::encrypt('PreviewProduct' . $this->product->id) || !file_exists(dirname(__FILE__) . '/../' . Tools::getValue('ad') . '/ajax.php')) {
             header('HTTP/1.1 404 page not found');
             $this->errors[] = Tools::displayError('Product is no longer available.');
         } elseif (!$this->product->checkAccess((int) self::$cookie->id_customer)) {
             $this->errors[] = Tools::displayError('You do not have access to this product.');
         } else {
             self::$smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int) $this->product->id));
             if (!$this->product->active) {
                 self::$smarty->assign('adminActionDisplay', true);
             }
             /* Product pictures management */
             require_once 'images.inc.php';
             if ($this->product->customizable) {
                 self::$smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
                 if (Tools::isSubmit('submitCustomizedDatas')) {
                     $this->pictureUpload($this->product, $cart);
                     $this->textRecord($this->product, $cart);
                     $this->formTargetFormat();
                 } elseif (isset($_GET['deletePicture']) and !$cart->deletePictureToProduct((int) $this->product->id, (int) Tools::getValue('deletePicture'))) {
                     $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture');
                 }
                 $files = self::$cookie->getFamily('pictures_' . (int) $this->product->id);
                 $textFields = self::$cookie->getFamily('textFields_' . (int) $this->product->id);
                 foreach ($textFields as $key => $textField) {
                     $textFields[$key] = str_replace('<br />', "\n", $textField);
                 }
                 self::$smarty->assign(array('pictures' => $files, 'textFields' => $textFields));
             }
             /* Features / Values */
             $features = $this->product->getFrontFeatures((int) self::$cookie->id_lang);
             $attachments = $this->product->cache_has_attachments ? $this->product->getAttachments((int) self::$cookie->id_lang) : array();
             /* Category */
             $category = false;
             if (isset($_SERVER['HTTP_REFERER']) and preg_match('!^(.*)\\/([0-9]+)\\-(.*[^\\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs) and !strstr($_SERVER['HTTP_REFERER'], '.html')) {
                 if (isset($regs[2]) and is_numeric($regs[2])) {
                     if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[2])))) {
                         $category = new Category((int) $regs[2], (int) self::$cookie->id_lang);
                     }
                 } elseif (isset($regs[5]) and is_numeric($regs[5])) {
                     if (Product::idIsOnCategoryId((int) $this->product->id, array('0' => array('id_category' => (int) $regs[5])))) {
                         $category = new Category((int) $regs[5], (int) self::$cookie->id_lang);
                     }
                 }
             }
             if (!$category) {
                 $category = new Category($this->product->id_category_default, (int) self::$cookie->id_lang);
             }
             if (isset($category) and Validate::isLoadedObject($category)) {
                 self::$smarty->assign(array('path' => Tools::getPath((int) $category->id, $this->product->name, true), 'category' => $category, 'subCategories' => $category->getSubCategories((int) self::$cookie->id_lang, true), 'id_category_current' => (int) $category->id, 'id_category_parent' => (int) $category->id_parent, 'return_category_name' => Tools::safeOutput($category->name)));
             } else {
                 self::$smarty->assign('path', Tools::getPath((int) $this->product->id_category_default, $this->product->name));
             }
             self::$smarty->assign('return_link', (isset($category->id) and $category->id) ? Tools::safeOutput(self::$link->getCategoryLink($category)) : 'javascript: history.back();');
             if (Pack::isPack((int) $this->product->id) and !Pack::isInStock((int) $this->product->id)) {
                 $this->product->quantity = 0;
             }
             $group_reduction = (100 - Group::getReduction((int) self::$cookie->id_customer)) / 100;
             $id_customer = (isset(self::$cookie->id_customer) and self::$cookie->id_customer) ? (int) self::$cookie->id_customer : 0;
             $id_group = $id_customer ? (int) Customer::getDefaultGroupId($id_customer) : _PS_DEFAULT_CUSTOMER_GROUP_;
             $id_country = (int) ($id_customer ? Customer::getCurrentCountry($id_customer) : Configuration::get('PS_COUNTRY_DEFAULT'));
             // Tax
             $tax = (double) Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             self::$smarty->assign('tax_rate', $tax);
             $productPriceWithTax = Product::getPriceStatic($this->product->id, true, NULL, 6);
             if (Product::$_taxCalculationMethod == PS_TAX_INC) {
                 $productPriceWithTax = Tools::ps_round($productPriceWithTax, 2);
             }
             $productPriceWithoutEcoTax = (double) ($productPriceWithTax - $this->product->ecotax);
             $ecotax_rate = (double) Tax::getProductEcotaxRate($cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $ecotaxTaxAmount = Tools::ps_round($this->product->ecotax, 2);
             if (Product::$_taxCalculationMethod == PS_TAX_INC && (int) Configuration::get('PS_TAX')) {
                 $ecotaxTaxAmount = Tools::ps_round($ecotaxTaxAmount * (1 + $ecotax_rate / 100), 2);
             }
             self::$smarty->assign(array('quantity_discounts' => $this->formatQuantityDiscounts(SpecificPrice::getQuantityDiscounts((int) $this->product->id, (int) Shop::getCurrentShop(), (int) self::$cookie->id_currency, $id_country, $id_group), $this->product->getPrice(Product::$_taxCalculationMethod == PS_TAX_INC, false), (double) $tax), 'product' => $this->product, 'ecotax_tax_inc' => $ecotaxTaxAmount, 'ecotax_tax_exc' => Tools::ps_round($this->product->ecotax, 2), 'ecotaxTax_rate' => $ecotax_rate, 'homeSize' => Image::getSize('home'), 'product_manufacturer' => new Manufacturer((int) $this->product->id_manufacturer, self::$cookie->id_lang), 'token' => Tools::getToken(false), 'productPriceWithoutEcoTax' => (double) $productPriceWithoutEcoTax, 'features' => $features, 'attachments' => $attachments, 'allow_oosp' => $this->product->isAvailableWhenOutOfStock((int) $this->product->out_of_stock), 'last_qties' => (int) Configuration::get('PS_LAST_QTIES'), 'group_reduction' => $group_reduction, 'col_img_dir' => _PS_COL_IMG_DIR_));
             self::$smarty->assign(array('HOOK_EXTRA_LEFT' => Module::hookExec('extraLeft'), 'HOOK_EXTRA_RIGHT' => Module::hookExec('extraRight'), 'HOOK_PRODUCT_OOS' => Hook::productOutOfStock($this->product), 'HOOK_PRODUCT_FOOTER' => Hook::productFooter($this->product, $category), 'HOOK_PRODUCT_ACTIONS' => Module::hookExec('productActions'), 'HOOK_PRODUCT_TAB' => Module::hookExec('productTab'), 'HOOK_PRODUCT_TAB_CONTENT' => Module::hookExec('productTabContent')));
             $images = $this->product->getImages((int) self::$cookie->id_lang);
             $productImages = array();
             foreach ($images as $k => $image) {
                 if ($image['cover']) {
                     self::$smarty->assign('mainImage', $images[0]);
                     $cover = $image;
                     $cover['id_image'] = Configuration::get('PS_LEGACY_IMAGES') ? $this->product->id . '-' . $image['id_image'] : $image['id_image'];
                     $cover['id_image_only'] = (int) $image['id_image'];
                 }
                 $productImages[(int) $image['id_image']] = $image;
             }
             if (!isset($cover)) {
                 $cover = array('id_image' => Language::getIsoById(self::$cookie->id_lang) . '-default', 'legend' => 'No picture', 'title' => 'No picture');
             }
             $size = Image::getSize('large');
             self::$smarty->assign(array('cover' => $cover, 'imgWidth' => (int) $size['width'], 'mediumSize' => Image::getSize('medium'), 'largeSize' => Image::getSize('large'), 'accessories' => $this->product->getAccessories((int) self::$cookie->id_lang)));
             if (count($productImages)) {
                 self::$smarty->assign('images', $productImages);
             }
             /* Attributes / Groups & colors */
             $colors = array();
             $attributesGroups = $this->product->getAttributesGroups((int) self::$cookie->id_lang);
             // @todo (RM) should only get groups and not all declination ?
             if (is_array($attributesGroups) and $attributesGroups) {
                 $groups = array();
                 $combinationImages = $this->product->getCombinationImages((int) self::$cookie->id_lang);
                 foreach ($attributesGroups as $k => $row) {
                     /* Color management */
                     if ((isset($row['attribute_color']) and $row['attribute_color'] or file_exists(_PS_COL_IMG_DIR_ . $row['id_attribute'] . '.jpg')) and $row['id_attribute_group'] == $this->product->id_color_default) {
                         $colors[$row['id_attribute']]['value'] = $row['attribute_color'];
                         $colors[$row['id_attribute']]['name'] = $row['attribute_name'];
                         if (!isset($colors[$row['id_attribute']]['attributes_quantity'])) {
                             $colors[$row['id_attribute']]['attributes_quantity'] = 0;
                         }
                         $colors[$row['id_attribute']]['attributes_quantity'] += (int) $row['quantity'];
                     }
                     if (!isset($groups[$row['id_attribute_group']])) {
                         $groups[$row['id_attribute_group']] = array('name' => $row['public_group_name'], 'is_color_group' => $row['is_color_group'], 'default' => -1);
                     }
                     $groups[$row['id_attribute_group']]['attributes'][$row['id_attribute']] = $row['attribute_name'];
                     if ($row['default_on'] && $groups[$row['id_attribute_group']]['default'] == -1) {
                         $groups[$row['id_attribute_group']]['default'] = (int) $row['id_attribute'];
                     }
                     if (!isset($groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']])) {
                         $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] = 0;
                     }
                     $groups[$row['id_attribute_group']]['attributes_quantity'][$row['id_attribute']] += (int) $row['quantity'];
                     $combinations[$row['id_product_attribute']]['attributes_values'][$row['id_attribute_group']] = $row['attribute_name'];
                     $combinations[$row['id_product_attribute']]['attributes'][] = (int) $row['id_attribute'];
                     $combinations[$row['id_product_attribute']]['price'] = (double) $row['price'];
                     $combinations[$row['id_product_attribute']]['ecotax'] = (double) $row['ecotax'];
                     $combinations[$row['id_product_attribute']]['weight'] = (double) $row['weight'];
                     $combinations[$row['id_product_attribute']]['quantity'] = (int) $row['quantity'];
                     $combinations[$row['id_product_attribute']]['reference'] = $row['reference'];
                     $combinations[$row['id_product_attribute']]['unit_impact'] = $row['unit_price_impact'];
                     $combinations[$row['id_product_attribute']]['minimal_quantity'] = $row['minimal_quantity'];
                     $combinations[$row['id_product_attribute']]['id_image'] = isset($combinationImages[$row['id_product_attribute']][0]['id_image']) ? $combinationImages[$row['id_product_attribute']][0]['id_image'] : -1;
                 }
                 //wash attributes list (if some attributes are unavailables and if allowed to wash it)
                 if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get('PS_DISP_UNAVAILABLE_ATTR') == 0) {
                     foreach ($groups as &$group) {
                         foreach ($group['attributes_quantity'] as $key => &$quantity) {
                             if (!$quantity) {
                                 unset($group['attributes'][$key]);
                             }
                         }
                     }
                     foreach ($colors as $key => $color) {
                         if (!$color['attributes_quantity']) {
                             unset($colors[$key]);
                         }
                     }
                 }
                 foreach ($groups as &$group) {
                     natcasesort($group['attributes']);
                 }
                 foreach ($combinations as $id_product_attribute => $comb) {
                     $attributeList = '';
                     foreach ($comb['attributes'] as $id_attribute) {
                         $attributeList .= '\'' . (int) $id_attribute . '\',';
                     }
                     $attributeList = rtrim($attributeList, ',');
                     $combinations[$id_product_attribute]['list'] = $attributeList;
                 }
                 self::$smarty->assign(array('groups' => $groups, 'combinaisons' => $combinations, 'combinations' => $combinations, 'colors' => (sizeof($colors) and $this->product->id_color_default) ? $colors : false, 'combinationImages' => $combinationImages));
             }
             self::$smarty->assign(array('no_tax' => Tax::excludeTaxeOption() or !Tax::getProductTaxRate((int) $this->product->id, $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}), 'customizationFields' => $this->product->customizable ? $this->product->getCustomizationFields((int) self::$cookie->id_lang) : false));
             // Pack management
             self::$smarty->assign('packItems', $this->product->cache_is_pack ? Pack::getItemTable($this->product->id, (int) self::$cookie->id_lang, true) : array());
             self::$smarty->assign('packs', Pack::getPacksTable($this->product->id, (int) self::$cookie->id_lang, true, 1));
         }
     }
     self::$smarty->assign(array('ENT_NOQUOTES' => ENT_NOQUOTES, 'outOfStockAllowed' => (int) Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'errors' => $this->errors, 'categories' => Category::getHomeCategories((int) self::$cookie->id_lang), 'have_image' => isset($cover) ? (int) $cover['id_image'] : false, 'tax_enabled' => Configuration::get('PS_TAX'), 'display_qties' => (int) Configuration::get('PS_DISPLAY_QTIES'), 'display_ht' => !Tax::excludeTaxeOption(), 'ecotax' => !sizeof($this->errors) and $this->product->ecotax > 0 ? Tools::convertPrice((double) $this->product->ecotax) : 0, 'currencySign' => $currency->sign, 'currencyRate' => $currency->conversion_rate, 'currencyFormat' => $currency->format, 'currencyBlank' => $currency->blank, 'jqZoomEnabled' => Configuration::get('PS_DISPLAY_JQZOOM')));
 }
Esempio n. 11
0
 function getCartTotalForBrands($brands)
 {
     $brand_ids = explode(',', $brands);
     $products = $this->getProducts();
     $order_total = 0;
     // if (Tax::excludeTaxeOption())
     $withTaxes = true;
     foreach ($products as $product) {
         $total_price = 0;
         if (!in_array($product['id_manufacturer'], $brand_ids)) {
             continue;
         }
         if ($this->_taxCalculationMethod == PS_TAX_EXC) {
             // Here taxes are computed only once the quantity has been applied to the product price
             $price = Product::getPriceStatic((int) $product['id_product'], false, (int) $product['id_product_attribute'], 2, NULL, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : NULL, (int) $this->id, $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $total_ecotax = $product['ecotax'] * (int) $product['cart_quantity'];
             $total_price = $price * (int) $product['cart_quantity'];
             if ($withTaxes) {
                 $total_price = ($total_price - $total_ecotax) * (1 + (double) Tax::getProductTaxRate((int) $product['id_product'], (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) / 100);
                 $total_ecotax = $total_ecotax * (1 + Tax::getProductEcotaxRate((int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}) / 100);
                 $total_price = Tools::ps_round($total_price + $total_ecotax, 2);
             }
         } else {
             $price = Product::getPriceStatic((int) $product['id_product'], $withTaxes, (int) $product['id_product_attribute'], 2, NULL, false, true, $product['cart_quantity'], false, (int) $this->id_customer ? (int) $this->id_customer : NULL, (int) $this->id, (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')} ? (int) $this->{Configuration::get('PS_TAX_ADDRESS_TYPE')} : NULL);
             $total_price = Tools::ps_round($price) * (int) $product['cart_quantity'];
         }
         $order_total += $total_price;
     }
     return $order_total;
 }
 private function initContentForPrices()
 {
     $wmpydnbicsf = "address";
     $sruhlrcndhjm = "tax_rules_groups";
     if ($this->object->id) {
         $gtrjxicj = "shops";
         ${"GLOBALS"}["hjxmueveb"] = "countries";
         ${$gtrjxicj} = Shop::getShops();
         ${"GLOBALS"}["yowiestuulby"] = "attributes";
         ${${"GLOBALS"}["hjxmueveb"]} = Country::getCountries($this->context->language->id);
         ${"GLOBALS"}["mcoohbnxpq"] = "combinations";
         ${${"GLOBALS"}["nfmuhudxx"]} = Group::getGroups($this->context->language->id);
         $limfcnldomcm = "attribute";
         ${${"GLOBALS"}["dslefjdrw"]} = Currency::getCurrencies();
         ${"GLOBALS"}["okgjebdqaj"] = "shops";
         $kwrbzzlqr = "combinations";
         $sctnqfirln = "countries";
         ${${"GLOBALS"}["yowiestuulby"]} = $this->object->getAttributesGroups((int) $this->context->language->id);
         ${${"GLOBALS"}["dnwvljcs"]} = array();
         foreach (${${"GLOBALS"}["ecblflvypvt"]} as ${$limfcnldomcm}) {
             ${"GLOBALS"}["exvidwpsyt"] = "combinations";
             $zmezdzncid = "combinations";
             $xdjwtnaj = "attribute";
             ${"GLOBALS"}["mrhqrnk"] = "combinations";
             ${${"GLOBALS"}["dnwvljcs"]}[${$xdjwtnaj}["id_product_attribute"]]["id_product_attribute"] = ${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"];
             if (!isset(${${"GLOBALS"}["mrhqrnk"]}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]]["attributes"])) {
                 ${${"GLOBALS"}["exvidwpsyt"]}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]]["attributes"] = "";
             }
             ${$zmezdzncid}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]]["attributes"] .= ${${"GLOBALS"}["iixdipeiyldv"]}["attribute_name"] . " - ";
             ${${"GLOBALS"}["dnwvljcs"]}[${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]]["price"] = Tools::displayPrice(Tools::convertPrice(Product::getPriceStatic((int) $this->object->id, false, ${${"GLOBALS"}["iixdipeiyldv"]}["id_product_attribute"]), new Currency((int) Configuration::get("PS_CURRENCY_DEFAULT"))), new Currency((int) Configuration::get("PS_CURRENCY_DEFAULT")));
         }
         foreach (${${"GLOBALS"}["mcoohbnxpq"]} as &${${"GLOBALS"}["yedtbmwbugs"]}) {
             ${${"GLOBALS"}["yedtbmwbugs"]}["attributes"] = rtrim(${${"GLOBALS"}["yedtbmwbugs"]}["attributes"], " - ");
         }
         ${"GLOBALS"}["hkhfis"] = "currencies";
         $fstmkpjgddtx = "groups";
         self::$smarty->assign("specificPriceModificationForm", $this->_displaySpecificPriceModificationForm(new Currency((int) Configuration::get("PS_CURRENCY_DEFAULT")), ${${"GLOBALS"}["vezxdvt"]}, ${${"GLOBALS"}["hkhfis"]}, ${$sctnqfirln}, ${$fstmkpjgddtx}));
         self::$smarty->assign(array("shops" => ${${"GLOBALS"}["okgjebdqaj"]}, "currencies" => ${${"GLOBALS"}["dslefjdrw"]}, "countries" => ${${"GLOBALS"}["ssxtkrofaehj"]}, "groups" => ${${"GLOBALS"}["nfmuhudxx"]}, "combinations" => ${$kwrbzzlqr}, "multi_shop" => Shop::isFeatureActive(), "link" => new Link()));
     } else {
         $this->displayWarning($this->getMessage("You must save this product before adding specific prices"));
     }
     $prspcoqnd = "tax_rules_group";
     ${"GLOBALS"}["zlokkqqmp"] = "tax_rules_groups";
     ${"GLOBALS"}["gojqtdbe"] = "tax_rates";
     ${$wmpydnbicsf} = new Address();
     $address->id_country = (int) $this->context->country->id;
     ${${"GLOBALS"}["zlokkqqmp"]} = TaxRulesGroup::getTaxRulesGroups(true);
     ${${"GLOBALS"}["gojqtdbe"]} = array(0 => array("id_tax_rules_group" => 0, "rates" => array(0), "computation_method" => 0));
     foreach (${${"GLOBALS"}["wwxeejcfd"]} as ${$prspcoqnd}) {
         ${"GLOBALS"}["roktqs"] = "id_tax_rules_group";
         ${"GLOBALS"}["synkmytf"] = "id_tax_rules_group";
         ${${"GLOBALS"}["ecsnliefhwus"]} = (int) ${${"GLOBALS"}["bbjbzqwyg"]}["id_tax_rules_group"];
         ${${"GLOBALS"}["kpkwjtrmp"]} = TaxManagerFactory::getManager(${${"GLOBALS"}["uqzwfulhdh"]}, ${${"GLOBALS"}["ecsnliefhwus"]})->getTaxCalculator();
         ${${"GLOBALS"}["slcvwfnf"]}[${${"GLOBALS"}["synkmytf"]}] = array("id_tax_rules_group" => ${${"GLOBALS"}["roktqs"]}, "rates" => array(), "computation_method" => (int) $tax_calculator->computation_method);
         if (isset($tax_calculator->taxes) && count($tax_calculator->taxes)) {
             foreach ($tax_calculator->taxes as ${${"GLOBALS"}["gcykbmm"]}) {
                 ${"GLOBALS"}["pqutmfdbhbd"] = "tax_rates";
                 $gsiilxrk = "id_tax_rules_group";
                 ${${"GLOBALS"}["pqutmfdbhbd"]}[${$gsiilxrk}]["rates"][] = (double) $tax->rate;
             }
         } else {
             $qjsphrpq = "tax_rates";
             ${$qjsphrpq}[${${"GLOBALS"}["ecsnliefhwus"]}]["rates"][] = 0;
         }
     }
     ${${"GLOBALS"}["lixyhrpqnh"]} = new Language($this->id_language);
     self::$smarty->assign("iso_code", $lang->iso_code);
     self::$smarty->assign("ps_use_ecotax", Configuration::get("PS_USE_ECOTAX"));
     self::$smarty->assign("ecotax_tax_excl", $this->object->ecotax);
     $dhllyvw = "tax_rates";
     self::$smarty->assign("currency", new Currency((int) Configuration::get("PS_CURRENCY_DEFAULT")));
     self::$smarty->assign("tax_rules_groups", ${$sruhlrcndhjm});
     self::$smarty->assign("taxesRatesByGroup", ${$dhllyvw});
     self::$smarty->assign("ecotaxTaxRate", Tax::getProductEcotaxRate());
     self::$smarty->assign("tax_exclude_taxe_option", Tax::excludeTaxeOption());
     if ($this->object->unit_price_ratio != 0) {
         self::$smarty->assign("unit_price", Tools::ps_round($this->object->price / $this->object->unit_price_ratio, 2));
     } else {
         self::$smarty->assign("unit_price", 0);
     }
     self::$smarty->assign("ps_tax", Configuration::get("PS_TAX"));
     self::$smarty->assign("country_display_tax_label", $this->context->country->display_tax_label);
     self::$smarty->assign(array("currency", new Currency((int) Configuration::get("PS_CURRENCY_DEFAULT"))));
 }
Esempio n. 13
0
    /**
     * Validate an order in database
     * Function called from a payment module
     *
     * @param integer $id_cart Value
     * @param integer $id_order_state Value
     * @param float $amountPaid Amount really paid by customer (in the default currency)
     * @param string $paymentMethod Payment method (eg. 'Credit card')
     * @param string $message Message to attach to order
     */
    public function validateOrder($id_cart, $id_order_state, $amountPaid, $paymentMethod = 'Unknown', $message = NULL, $extraVars = array(), $currency_special = NULL, $dont_touch_amount = false, $secure_key = false)
    {
        global $cart;
        $cart = new Cart((int) $id_cart);
        // Does order already exists ?
        if (!$this->active) {
            die(Tools::displayError());
        }
        if (Validate::isLoadedObject($cart) && $cart->OrderExists() == false) {
            if ($secure_key !== false && $secure_key != $cart->secure_key) {
                die(Tools::displayError());
            }
            // Copying data from cart
            $order = new Order();
            $order->id_carrier = (int) $cart->id_carrier;
            $order->id_customer = (int) $cart->id_customer;
            $order->id_address_invoice = (int) $cart->id_address_invoice;
            $order->id_address_delivery = (int) $cart->id_address_delivery;
            $vat_address = new Address((int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $order->id_currency = $currency_special ? (int) $currency_special : (int) $cart->id_currency;
            $order->id_lang = (int) $cart->id_lang;
            $order->id_cart = (int) $cart->id;
            $customer = new Customer((int) $order->id_customer);
            $order->secure_key = $secure_key ? pSQL($secure_key) : pSQL($customer->secure_key);
            $order->payment = $paymentMethod;
            if (isset($this->name)) {
                $order->module = $this->name;
            }
            $order->recyclable = $cart->recyclable;
            $order->gift = (int) $cart->gift;
            $order->gift_message = $cart->gift_message;
            $currency = new Currency($order->id_currency);
            $order->conversion_rate = $currency->conversion_rate;
            $amountPaid = !$dont_touch_amount ? Tools::ps_round((double) $amountPaid, 2) : $amountPaid;
            $order->total_paid_real = $amountPaid;
            $order->total_products = (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
            $order->total_products_wt = (double) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
            $order->total_discounts = (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
            $order->total_shipping = (double) $cart->getOrderShippingCost();
            $order->carrier_tax_rate = (double) Tax::getCarrierTaxRate($cart->id_carrier, (int) $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $order->total_wrapping = (double) abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING));
            $order->total_paid = (double) Tools::ps_round((double) $cart->getOrderTotal(true, Cart::BOTH), 2);
            $order->invoice_date = '0000-00-00 00:00:00';
            $order->delivery_date = '0000-00-00 00:00:00';
            // 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 (number_format($order->total_paid, 2) != number_format($order->total_paid_real, 2)) {
                $id_order_state = Configuration::get('PS_OS_ERROR');
            }
            // Creating order
            if ($cart->OrderExists() == false) {
                $result = $order->add();
            } else {
                $errorMessage = Tools::displayError('An order has already been placed using this cart.');
                Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
            // Next !
            if ($result and isset($order->id)) {
                if (!$secure_key) {
                    $message .= $this->l('Warning : the secure key is empty, check your payment account before validation');
                }
                // Optional message to attach to this order
                if (isset($message) and !empty($message)) {
                    $msg = new Message();
                    $message = strip_tags($message, '<br>');
                    if (Validate::isCleanHtml($message)) {
                        $msg->message = $message;
                        $msg->id_order = intval($order->id);
                        $msg->private = 1;
                        $msg->add();
                    }
                }
                // Insert products from cart into order_detail table
                $products = $cart->getProducts();
                $productsList = '';
                $db = Db::getInstance();
                $query = 'INSERT INTO `' . _DB_PREFIX_ . 'order_detail`
					(`id_order`, `product_id`, `product_attribute_id`, `product_name`, `product_quantity`, `product_quantity_in_stock`, `product_price`, `reduction_percent`, `reduction_amount`, `group_reduction`, `product_quantity_discount`, `product_ean13`, `product_upc`, `product_reference`, `product_supplier_reference`, `product_weight`, `tax_name`, `tax_rate`, `ecotax`, `ecotax_tax_rate`, `discount_quantity_applied`, `download_deadline`, `download_hash`)
				VALUES ';
                $customizedDatas = Product::getAllCustomizedDatas((int) $order->id_cart);
                Product::addCustomizationPrice($products, $customizedDatas);
                $outOfStock = false;
                $store_all_taxes = array();
                foreach ($products as $key => $product) {
                    $productQuantity = (int) Product::getQuantity((int) $product['id_product'], $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL);
                    $quantityInStock = $productQuantity - (int) $product['cart_quantity'] < 0 ? $productQuantity : (int) $product['cart_quantity'];
                    if ($id_order_state != Configuration::get('PS_OS_CANCELED') and $id_order_state != Configuration::get('PS_OS_ERROR')) {
                        if (Product::updateQuantity($product, (int) $order->id)) {
                            $product['stock_quantity'] -= $product['cart_quantity'];
                        }
                        if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
                            $outOfStock = true;
                        }
                        Product::updateDefaultAttribute($product['id_product']);
                    }
                    $price = Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, 6, NULL, false, true, $product['cart_quantity'], 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, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    /* Store tax info */
                    $id_country = (int) Country::getDefaultCountryId();
                    $id_state = 0;
                    $id_county = 0;
                    $rate = 0;
                    $id_address = $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
                    $address_infos = Address::getCountryAndState($id_address);
                    if ($address_infos['id_country']) {
                        $id_country = (int) $address_infos['id_country'];
                        $id_state = (int) $address_infos['id_state'];
                        $id_county = (int) County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
                    }
                    $allTaxes = TaxRulesGroup::getTaxes((int) Product::getIdTaxRulesGroupByIdProduct((int) $product['id_product']), $id_country, $id_state, $id_county);
                    // If its a freeOrder, there will be no calculation
                    if ($order->total_products > 0) {
                        // remove order discount quotepart on product price in order to obtain the real tax
                        $ratio = $price / $order->total_products;
                        $order_reduction_amount = (double) abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS)) * $ratio;
                        $tmp_price = $price - $order_reduction_amount;
                        foreach ($allTaxes as $res) {
                            if (!isset($store_all_taxes[$res->id])) {
                                $store_all_taxes[$res->id] = array();
                                $store_all_taxes[$res->id]['amount'] = 0;
                            }
                            $store_all_taxes[$res->id]['name'] = $res->name[(int) $order->id_lang];
                            $store_all_taxes[$res->id]['rate'] = $res->rate;
                            $unit_tax_amount = $tmp_price * ($res->rate * 0.01);
                            $tmp_price = $tmp_price + $unit_tax_amount;
                            $store_all_taxes[$res->id]['amount'] += $unit_tax_amount * $product['cart_quantity'];
                        }
                    }
                    /* End */
                    // Add some informations for virtual products
                    $deadline = '0000-00-00 00:00:00';
                    $download_hash = null;
                    if ($id_product_download = ProductDownload::getIdFromIdProduct((int) $product['id_product'])) {
                        $productDownload = new ProductDownload((int) $id_product_download);
                        $deadline = $productDownload->getDeadLine();
                        $download_hash = $productDownload->getHash();
                    }
                    // Exclude VAT
                    if (!_PS_TAX_) {
                        $product['tax'] = 0;
                        $product['rate'] = 0;
                        $tax_rate = 0;
                    } else {
                        $tax_rate = Tax::getProductTaxRate((int) $product['id_product'], $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $ecotaxTaxRate = 0;
                    if (!empty($product['ecotax'])) {
                        $ecotaxTaxRate = Tax::getProductEcotaxRate($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $product_price = (double) Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? 2 : 6, NULL, false, false, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}, $specificPrice, false, false);
                    $group_reduction = (double) GroupReduction::getValueForProduct((int) $product['id_product'], $customer->id_default_group) * 100;
                    if (!$group_reduction) {
                        $group_reduction = (double) Group::getReduction((int) $order->id_customer);
                    }
                    $quantityDiscount = SpecificPrice::getQuantityDiscount((int) $product['id_product'], Shop::getCurrentShop(), (int) $cart->id_currency, (int) $vat_address->id_country, (int) $customer->id_default_group, (int) $product['cart_quantity']);
                    $unitPrice = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? intval($product['id_product_attribute']) : NULL, 2, NULL, false, true, 1, false, (int) $order->id_customer, NULL, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    $quantityDiscountValue = $quantityDiscount ? (Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? Tools::ps_round($unitPrice, 2) : $unitPrice) - $quantityDiscount['price'] * (1 + $tax_rate / 100) : 0.0;
                    $query .= '(' . (int) $order->id . ',
						' . (int) $product['id_product'] . ',
						' . (isset($product['id_product_attribute']) ? (int) $product['id_product_attribute'] : 'NULL') . ',
						\'' . pSQL($product['name'] . ((isset($product['attributes']) and $product['attributes'] != NULL) ? ' - ' . $product['attributes'] : '')) . '\',
						' . (int) $product['cart_quantity'] . ',
						' . $quantityInStock . ',
						' . $product_price . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'percentage') ? $specificPrice['reduction'] * 100 : 0.0) . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'amount') ? !$specificPrice['id_currency'] ? Tools::convertPrice($specificPrice['reduction'], $order->id_currency) : $specificPrice['reduction'] : 0.0) . ',
						' . $group_reduction . ',
						' . $quantityDiscountValue . ',
						' . (empty($product['ean13']) ? 'NULL' : '\'' . pSQL($product['ean13']) . '\'') . ',
						' . (empty($product['upc']) ? 'NULL' : '\'' . pSQL($product['upc']) . '\'') . ',
						' . (empty($product['reference']) ? 'NULL' : '\'' . pSQL($product['reference']) . '\'') . ',
						' . (empty($product['supplier_reference']) ? 'NULL' : '\'' . pSQL($product['supplier_reference']) . '\'') . ',
						' . (double) ($product['id_product_attribute'] ? $product['weight_attribute'] : $product['weight']) . ',
						\'' . (empty($tax_rate) ? '' : pSQL($product['tax'])) . '\',
						' . (double) $tax_rate . ',
						' . (double) Tools::convertPrice(floatval($product['ecotax']), intval($order->id_currency)) . ',
						' . (double) $ecotaxTaxRate . ',
						' . (($specificPrice and $specificPrice['from_quantity'] > 1) ? 1 : 0) . ',
						\'' . pSQL($deadline) . '\',
						\'' . pSQL($download_hash) . '\'),';
                    $customizationQuantity = 0;
                    if (isset($customizedDatas[$product['id_product']][$product['id_product_attribute']])) {
                        $customizationText = '';
                        foreach ($customizedDatas[$product['id_product']][$product['id_product_attribute']] as $customization) {
                            if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_])) {
                                foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] as $text) {
                                    $customizationText .= $text['name'] . ':' . ' ' . $text['value'] . '<br />';
                                }
                            }
                            if (isset($customization['datas'][_CUSTOMIZE_FILE_])) {
                                $customizationText .= count($customization['datas'][_CUSTOMIZE_FILE_]) . ' ' . Tools::displayError('image(s)') . '<br />';
                            }
                            $customizationText .= '---<br />';
                        }
                        $customizationText = rtrim($customizationText, '---<br />');
                        $customizationQuantity = (int) $product['customizationQuantityTotal'];
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . (isset($product['reference']) && !empty($product['reference']) ? $product['reference'] : '&nbsp;') . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . ' - ' . $this->l('Customized') . (!empty($customizationText) ? ' - ' . $customizationText : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . $customizationQuantity . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice($customizationQuantity * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                    if (!$customizationQuantity or (int) $product['cart_quantity'] > $customizationQuantity) {
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . (isset($product['reference']) && !empty($product['reference']) ? $product['reference'] : '&nbsp;') . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . ((int) $product['cart_quantity'] - $customizationQuantity) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(((int) $product['cart_quantity'] - $customizationQuantity) * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                }
                // end foreach ($products)
                $query = rtrim($query, ',');
                $result = $db->Execute($query);
                /* Add carrier tax */
                $shippingCostTaxExcl = $cart->getOrderShippingCost((int) $order->id_carrier, false);
                $allTaxes = TaxRulesGroup::getTaxes((int) Carrier::getIdTaxRulesGroupByIdCarrier((int) $order->id_carrier), $id_country, $id_state, $id_county);
                $nTax = 0;
                foreach ($allTaxes as $tax) {
                    if (!isset($tax->id)) {
                        continue;
                    }
                    if (!isset($store_all_taxes[$tax->id])) {
                        $store_all_taxes[$tax->id] = array();
                    }
                    if (!isset($store_all_taxes[$tax->id]['amount'])) {
                        $store_all_taxes[$tax->id]['amount'] = 0;
                    }
                    $store_all_taxes[$tax->id]['name'] = $tax->name[(int) $order->id_lang];
                    $store_all_taxes[$tax->id]['rate'] = $tax->rate;
                    if (!$nTax++) {
                        $store_all_taxes[$tax->id]['amount'] += $shippingCostTaxExcl * (1 + $tax->rate * 0.01) - $shippingCostTaxExcl;
                    } else {
                        $store_all_taxes[$tax->id]['amount'] += $order->total_shipping - $order->total_shipping / (1 + $tax->rate * 0.01);
                    }
                }
                /* Store taxes */
                foreach ($store_all_taxes as $tax) {
                    Db::getInstance()->Execute('
					INSERT INTO `' . _DB_PREFIX_ . 'order_tax` (`id_order`, `tax_name`, `tax_rate`, `amount`)
					VALUES (' . (int) $order->id . ', \'' . pSQL($tax['name']) . '\', ' . (double) $tax['rate'] . ', ' . (double) $tax['amount'] . ')');
                }
                // Insert discounts from cart into order_discount table
                $discounts = $cart->getDiscounts();
                $discountsList = '';
                $total_discount_value = 0;
                $shrunk = false;
                foreach ($discounts as $discount) {
                    $objDiscount = new Discount((int) $discount['id_discount']);
                    $value = $objDiscount->getValue(count($discounts), $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS), $order->total_shipping, $cart->id);
                    if ($objDiscount->id_discount_type == 2 and in_array($objDiscount->behavior_not_exhausted, array(1, 2))) {
                        $shrunk = true;
                    }
                    if ($shrunk and $total_discount_value + $value > $order->total_products_wt + $order->total_shipping + $order->total_wrapping) {
                        $amount_to_add = $order->total_products_wt + $order->total_shipping + $order->total_wrapping - $total_discount_value;
                        if ($objDiscount->id_discount_type == 2 and $objDiscount->behavior_not_exhausted == 2) {
                            $voucher = new Discount();
                            foreach ($objDiscount as $key => $discountValue) {
                                $voucher->{$key} = $discountValue;
                            }
                            $voucher->name = 'VSRK' . (int) $order->id_customer . 'O' . (int) $order->id;
                            $voucher->value = (double) $value - $amount_to_add;
                            $voucher->add();
                            $params['{voucher_amount}'] = Tools::displayPrice($voucher->value, $currency, false);
                            $params['{voucher_num}'] = $voucher->name;
                            $params['{firstname}'] = $customer->firstname;
                            $params['{lastname}'] = $customer->lastname;
                            $params['{id_order}'] = $order->id;
                            $params['{order_name}'] = sprintf("#%06d", (int) $order->id);
                            @Mail::Send((int) $order->id_lang, 'voucher', Mail::l('New voucher regarding your order #', (int) $order->id_lang) . sprintf("%06d", (int) $order->id), $params, $customer->email, $customer->firstname . ' ' . $customer->lastname);
                        }
                    } else {
                        $amount_to_add = $value;
                    }
                    $order->addDiscount($objDiscount->id, $objDiscount->name, $amount_to_add);
                    $total_discount_value += $amount_to_add;
                    if ($id_order_state != Configuration::get('PS_OS_ERROR') and $id_order_state != Configuration::get('PS_OS_CANCELED')) {
                        $objDiscount->quantity = $objDiscount->quantity - 1;
                    }
                    $objDiscount->update();
                    $discountsList .= '<tr style="background-color:#EBECEE;">
							<td colspan="4" style="padding: 0.6em 0.4em; text-align: right;">' . $this->l('Voucher code:') . ' ' . $objDiscount->name . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . ($value != 0.0 ? '-' : '') . Tools::displayPrice($value, $currency, false) . '</td>
					</tr>';
                }
                // Specify order id for message
                $oldMessage = Message::getMessageByCartId((int) $cart->id);
                if ($oldMessage) {
                    $message = new Message((int) $oldMessage['id_message']);
                    $message->id_order = (int) $order->id;
                    $message->update();
                }
                // Hook new order
                $orderStatus = new OrderState((int) $id_order_state, (int) $order->id_lang);
                if (Validate::isLoadedObject($orderStatus)) {
                    Hook::newOrder($cart, $order, $customer, $currency, $orderStatus);
                    foreach ($cart->getProducts() as $product) {
                        if ($orderStatus->logable) {
                            ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']);
                        }
                    }
                }
                if (isset($outOfStock) && $outOfStock && Configuration::get('PS_STOCK_MANAGEMENT')) {
                    $history = new OrderHistory();
                    $history->id_order = (int) $order->id;
                    $history->changeIdOrderState(Configuration::get('PS_OS_OUTOFSTOCK'), (int) $order->id);
                    $history->addWithemail();
                }
                // Set order state in order history ONLY even if the "out of stock" status has not been yet reached
                // So you migth have two order states
                $new_history = new OrderHistory();
                $new_history->id_order = (int) $order->id;
                $new_history->changeIdOrderState((int) $id_order_state, (int) $order->id);
                $new_history->addWithemail(true, $extraVars);
                // Order is reloaded because the status just changed
                $order = new Order($order->id);
                // Send an e-mail to customer
                if ($id_order_state != Configuration::get('PS_OS_ERROR') and $id_order_state != Configuration::get('PS_OS_CANCELED') and $customer->id) {
                    $invoice = new Address((int) $order->id_address_invoice);
                    $delivery = new Address((int) $order->id_address_delivery);
                    $carrier = new Carrier((int) $order->id_carrier, $order->id_lang);
                    $delivery_state = $delivery->id_state ? new State((int) $delivery->id_state) : false;
                    $invoice_state = $invoice->id_state ? new State((int) $invoice->id_state) : false;
                    $data = array('{firstname}' => $customer->firstname, '{lastname}' => $customer->lastname, '{email}' => $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="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')), '{invoice_block_html}' => $this->_getFormatedAddress($invoice, "<br />", array('firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; 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}' => sprintf("#%06d", (int) $order->id), '{date}' => Tools::displayDate(date('Y-m-d H:i:s'), (int) $order->id_lang, 1), '{carrier}' => $carrier->name, '{payment}' => Tools::substr($order->payment, 0, 32), '{products}' => $productsList, '{discounts}' => $discountsList, '{total_paid}' => Tools::displayPrice($order->total_paid, $currency, false), '{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_wrapping + $order->total_discounts, $currency, false), '{total_discounts}' => Tools::displayPrice($order->total_discounts, $currency, false), '{total_shipping}' => Tools::displayPrice($order->total_shipping, $currency, false), '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $currency, false));
                    if (is_array($extraVars)) {
                        $data = array_merge($data, $extraVars);
                    }
                    // Join PDF invoice
                    if ((int) Configuration::get('PS_INVOICE') and Validate::isLoadedObject($orderStatus) and $orderStatus->invoice and $order->invoice_number) {
                        $fileAttachment['content'] = PDF::invoice($order, 'S');
                        $fileAttachment['name'] = Configuration::get('PS_INVOICE_PREFIX', (int) $order->id_lang) . sprintf('%06d', $order->invoice_number) . '.pdf';
                        $fileAttachment['mime'] = 'application/pdf';
                    } else {
                        $fileAttachment = null;
                    }
                    if (Validate::isEmail($customer->email)) {
                        Mail::Send((int) $order->id_lang, 'order_conf', Mail::l('Order confirmation', (int) $order->id_lang), $data, $customer->email, $customer->firstname . ' ' . $customer->lastname, NULL, NULL, $fileAttachment);
                    }
                }
                $this->currentOrder = (int) $order->id;
                return true;
            } else {
                $errorMessage = Tools::displayError('Order creation failed');
                Logger::addLog($errorMessage, 4, '0000002', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
        } else {
            $errorMessage = Tools::displayError('Cart cannot be loaded or an order has already been placed using this cart');
            Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($cart->id));
            die($errorMessage);
        }
    }
Esempio n. 14
0
 public static function getProductProperties($id_lang, $row, Context $context = null)
 {
     Hook::exec('actionGetProductPropertiesBefore', ['id_lang' => $id_lang, 'product' => $row, 'context' => $context]);
     if (!$row['id_product']) {
         return false;
     }
     if ($context == null) {
         $context = Context::getContext();
     }
     $id_product_attribute = $row['id_product_attribute'] = !empty($row['id_product_attribute']) ? (int) $row['id_product_attribute'] : null;
     // Product::getDefaultAttribute is only called if id_product_attribute is missing from the SQL query at the origin of it:
     // consider adding it in order to avoid unnecessary queries
     $row['allow_oosp'] = Product::isAvailableWhenOutOfStock($row['out_of_stock']);
     if (Combination::isFeatureActive() && $id_product_attribute === null && (isset($row['cache_default_attribute']) && ($ipa_default = $row['cache_default_attribute']) !== null || ($ipa_default = Product::getDefaultAttribute($row['id_product'], !$row['allow_oosp'])))) {
         $id_product_attribute = $row['id_product_attribute'] = $ipa_default;
     }
     if (!Combination::isFeatureActive() || !isset($row['id_product_attribute'])) {
         $id_product_attribute = $row['id_product_attribute'] = 0;
     }
     // Tax
     $usetax = !Tax::excludeTaxeOption();
     $cache_key = $row['id_product'] . '-' . $id_product_attribute . '-' . $id_lang . '-' . (int) $usetax;
     if (isset($row['id_product_pack'])) {
         $cache_key .= '-pack' . $row['id_product_pack'];
     }
     if (isset(self::$producPropertiesCache[$cache_key])) {
         return array_merge($row, self::$producPropertiesCache[$cache_key]);
     }
     // Datas
     $row['category'] = Category::getLinkRewrite((int) $row['id_category_default'], (int) $id_lang);
     $row['category_name'] = Db::getInstance()->getValue('SELECT name FROM ' . _DB_PREFIX_ . 'category_lang WHERE id_shop = ' . (int) $context->shop->id . ' AND id_lang = ' . (int) $id_lang . ' AND id_category = ' . (int) $row['id_category_default']);
     $row['link'] = $context->link->getProductLink((int) $row['id_product'], $row['link_rewrite'], $row['category'], $row['ean13']);
     $row['attribute_price'] = 0;
     if ($id_product_attribute) {
         $row['attribute_price'] = (double) Combination::getPrice($id_product_attribute);
     }
     if (isset($row['quantity_wanted'])) {
         // 'quantity_wanted' may very well be zero even if set
         $quantity = max((int) $row['minimal_quantity'], (int) $row['quantity_wanted']);
     } else {
         $quantity = (int) $row['minimal_quantity'];
     }
     $row['price_tax_exc'] = Product::getPriceStatic((int) $row['id_product'], false, $id_product_attribute, self::$_taxCalculationMethod == PS_TAX_EXC ? 2 : 6, null, false, true, $quantity);
     if (self::$_taxCalculationMethod == PS_TAX_EXC) {
         $row['price_tax_exc'] = Tools::ps_round($row['price_tax_exc'], 2);
         $row['price'] = Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, true, $quantity);
         $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], false, $id_product_attribute, 2, null, false, false, $quantity);
     } else {
         $row['price'] = Tools::ps_round(Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, true, $quantity), (int) Configuration::get('PS_PRICE_DISPLAY_PRECISION'));
         $row['price_without_reduction'] = Product::getPriceStatic((int) $row['id_product'], true, $id_product_attribute, 6, null, false, false, $quantity);
     }
     $row['reduction'] = Product::getPriceStatic((int) $row['id_product'], (bool) $usetax, $id_product_attribute, 6, null, true, true, $quantity, true, null, null, null, $specific_prices);
     $row['specific_prices'] = $specific_prices;
     $row['quantity'] = Product::getQuantity((int) $row['id_product'], 0, isset($row['cache_is_pack']) ? $row['cache_is_pack'] : null);
     $row['quantity_all_versions'] = $row['quantity'];
     if ($row['id_product_attribute']) {
         $row['quantity'] = Product::getQuantity((int) $row['id_product'], $id_product_attribute, isset($row['cache_is_pack']) ? $row['cache_is_pack'] : null);
         $row['available_date'] = Product::getAvailableDate((int) $row['id_product'], $id_product_attribute);
     }
     $row['id_image'] = Product::defineProductImage($row, $id_lang);
     $row['features'] = Product::getFrontFeaturesStatic((int) $id_lang, $row['id_product']);
     $row['attachments'] = array();
     if (!isset($row['cache_has_attachments']) || $row['cache_has_attachments']) {
         $row['attachments'] = Product::getAttachmentsStatic((int) $id_lang, $row['id_product']);
     }
     $row['virtual'] = !isset($row['is_virtual']) || $row['is_virtual'] ? 1 : 0;
     // Pack management
     $row['pack'] = !isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int) $row['cache_is_pack'];
     $row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array();
     $row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0;
     if ($row['pack'] && !Pack::isInStock($row['id_product'])) {
         $row['quantity'] = 0;
     }
     $row['customization_required'] = false;
     if (isset($row['customizable']) && $row['customizable'] && Customization::isFeatureActive()) {
         if (count(Product::getRequiredCustomizableFieldsStatic((int) $row['id_product']))) {
             $row['customization_required'] = true;
         }
     }
     $attributes = Product::getAttributesParams($row['id_product'], $row['id_product_attribute']);
     foreach ($attributes as $attribute) {
         $row['attributes'][$attribute['id_attribute_group']] = $attribute;
     }
     $row = Product::getTaxesInformations($row, $context);
     $row['ecotax_rate'] = (double) Tax::getProductEcotaxRate($context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
     Hook::exec('actionGetProductPropertiesAfter', ['id_lang' => $id_lang, 'product' => $row, 'context' => $context]);
     $combination = new Combination($id_product_attribute);
     if (0 != $combination->unit_price_impact && 0 != $row['unit_price_ratio']) {
         $unitPrice = $row['price_tax_exc'] / $row['unit_price_ratio'] + $combination->unit_price_impact;
         $row['unit_price_ratio'] = $row['price_tax_exc'] / $unitPrice;
     }
     $row['unit_price'] = $row['unit_price_ratio'] != 0 ? $row['price'] / $row['unit_price_ratio'] : 0;
     self::$producPropertiesCache[$cache_key] = $row;
     return self::$producPropertiesCache[$cache_key];
 }
Esempio n. 15
0
 public function initContent()
 {
     if (!$this->ajax) {
         parent::initContent();
     }
     //  parent::initContent();
     $this->setTemplate(_PS_THEME_DIR_ . 'category.tpl');
     if (!$this->customer_access) {
         return;
     }
     if (isset($this->context->cookie->id_compare)) {
         $this->context->smarty->assign('compareProducts', CompareProduct::getCompareProducts((int) $this->context->cookie->id_compare));
     }
     $this->productSort();
     // Product sort must be called before assignProductList()
     $this->assignScenes();
     $this->assignSubcategories();
     $this->assignProductList();
     $products = isset($this->cat_products) && $this->cat_products ? $this->cat_products : null;
     $combinations = array();
     if ($products !== NULL) {
         foreach ($products as &$pro) {
             $product_obj = new Product($pro['id_product'], $this->context->language->id);
             $pro['groups'] = $product_obj->getProductCombinationsGroups($pro['id_product']);
             $combinations[$pro['id_product']] = $product_obj->getProductAttributeCombinations($pro['id_product']);
             $id_group = (int) Group::getCurrent()->id;
             $group_reduction = GroupReduction::getValueForProduct($pro['id_product'], $id_group);
             if ($group_reduction === false) {
                 $group_reduction = Group::getReduction((int) $this->context->cookie->id_customer) / 100;
             }
             $pro['group_reduction'] = $group_reduction;
             $address = new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $pro['no_tax'] = Tax::excludeTaxeOption() || !$product_obj->getTaxesRate($address);
             $pro['customer_group_without_tax'] = Group::getPriceDisplayMethod($this->context->customer->id_default_group);
             $tax = (double) $product_obj->getTaxesRate(new Address((int) $this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
             $pro['tax_rate'] = $tax;
             $pro['unit_price_ratio'] = $product_obj->unit_price_ratio;
             $ecotax_rate = (double) Tax::getProductEcotaxRate($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
             $pro['ecotaxTax_rate'] = $ecotax_rate;
         }
     }
     $this->context->smarty->assign(array('category' => $this->category, 'description_short' => Tools::truncateString($this->category->description, 350), 'products' => $products, 'id_category' => (int) $this->category->id, 'id_category_parent' => (int) $this->category->id_parent, 'return_category_name' => Tools::safeOutput($this->category->name), 'path' => Tools::getPath($this->category->id), 'add_prod_display' => Configuration::get('PS_ATTRIBUTE_CATEGORY_DISPLAY'), 'categorySize' => Image::getSize(ImageType::getFormatedName('category')), 'mediumSize' => Image::getSize(ImageType::getFormatedName('medium')), 'thumbSceneSize' => Image::getSize(ImageType::getFormatedName('m_scene')), 'homeSize' => Image::getSize(ImageType::getFormatedName('home')), 'allow_oosp' => (int) Configuration::get('PS_ORDER_OUT_OF_STOCK'), 'comparator_max_item' => (int) Configuration::get('PS_COMPARATOR_MAX_ITEM'), 'suppliers' => Supplier::getSuppliers(), 'body_classes' => array($this->php_self . '-' . $this->category->id, $this->php_self . '-' . $this->category->link_rewrite), 'combinations' => $combinations));
 }
Esempio n. 16
0
    /**
     * Validate an order in database
     * Function called from a payment module
     *
     * @param integer $id_cart Value
     * @param integer $id_order_state Value
     * @param float $amountPaid Amount really paid by customer (in the default currency)
     * @param string $paymentMethod Payment method (eg. 'Credit card')
     * @param string $message Message to attach to order
     */
    public function validateOrder($id_cart, $id_order_state, $amountPaid, $paymentMethod = 'Unknown', $message = NULL, $extraVars = array(), $currency_special = NULL, $dont_touch_amount = false, $secure_key = false)
    {
        global $cart, $link, $cookie;
        $id_payment_state = _PS_PS_NOT_PAID_;
        $cart = new Cart((int) $id_cart);
        // Does order already exists ?
        if (Validate::isLoadedObject($cart) and $cart->OrderExists() == false) {
            if ($secure_key !== false and $secure_key != $cart->secure_key) {
                die(Tools::displayError());
            }
            // Copying data from cart
            $order = new Order();
            $order->id_carrier = (int) $cart->id_carrier;
            $order->id_customer = (int) $cart->id_customer;
            $order->id_address_invoice = (int) $cart->id_address_invoice;
            $order->id_address_delivery = (int) $cart->id_address_delivery;
            $vat_address = new Address((int) $order->id_address_delivery);
            $order->id_currency = $currency_special ? (int) $currency_special : (int) $cart->id_currency;
            $order->id_lang = (int) $cart->id_lang;
            $order->id_cart = (int) $cart->id;
            $customer = new Customer((int) $order->id_customer);
            $order->secure_key = $secure_key ? pSQL($secure_key) : pSQL($customer->secure_key);
            $order->payment = $paymentMethod;
            if (isset($this->name)) {
                $order->module = $this->name;
            }
            $order->recyclable = $cart->recyclable;
            $order->gift = (int) $cart->gift;
            $order->gift_message = $cart->gift_message;
            $currency = new Currency($order->id_currency);
            $order->conversion_rate = $currency->conversion_rate;
            $amountPaid = !$dont_touch_amount ? Tools::ps_round((double) $amountPaid, 2) : $amountPaid;
            $order->total_paid_real = $amountPaid;
            $order->total_products = (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
            $order->total_products_wt = (double) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
            $order->total_customization = $cart->getCartCustomizationCost();
            $order->total_donation = round($cookie->donation_amount);
            unset($cookie->donation_amount);
            if (strpos($order->payment, 'COD') === false) {
                $order->total_discounts = (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, true));
                $order->total_paid = (double) Tools::ps_round((double) $cart->getOrderTotal(true, Cart::BOTH, true));
            } else {
                $order->total_discounts = (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, false));
                $order->total_paid = (double) Tools::ps_round((double) $cart->getOrderTotal(true, Cart::BOTH, false));
                $order->total_cod = COD_CHARGE;
            }
            $order->total_shipping = (double) $cart->getOrderShippingCost();
            $order->carrier_tax_rate = (double) Tax::getCarrierTaxRate($cart->id_carrier, (int) $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $order->total_wrapping = (double) abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING));
            $order->invoice_date = '0000-00-00 00:00:00';
            $order->delivery_date = '0000-00-00 00:00:00';
            $shippingdate = $cart->getExpectedShippingDate();
            $order->expected_shipping_date = pSQL($shippingdate->format('Y-m-d H:i:s'));
            $order->actual_expected_shipping_date = pSQL($shippingdate->format('Y-m-d H:i:s'));
            // 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 (number_format(round($order->total_paid)) != number_format(round($order->total_paid_real))) {
                $id_order_state = _PS_OS_ERROR_;
                $id_payment_state = _PS_PS_NOT_PAID_;
            } else {
                if (strpos($order->payment, 'COD') === false) {
                    $id_payment_state = _PS_PS_PAID_;
                }
            }
            //update payment status
            // Creating order
            if ($cart->OrderExists() == false) {
                $cart_value = $cart->getOrderTotal();
                if ($cart_value >= 1000) {
                    //if(!$cart->containsProduct(FREE_GIFT_ID, NULL, NULL))
                    //$cart->updateQty(1, FREE_GIFT_ID, NULL, false, 'up', TRUE);
                }
                $result = $order->add();
            } else {
                $errorMessage = Tools::displayError('An order has already been placed using this cart.');
                Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
            // Next !
            if ($result and isset($order->id)) {
                if (!$secure_key) {
                    $message .= $this->l('Warning : the secure key is empty, check your payment account before validation');
                }
                // Optional message to attach to this order
                if (isset($message) and !empty($message)) {
                    $msg = new Message();
                    $message = strip_tags($message, '<br>');
                    if (Validate::isCleanHtml($message)) {
                        $msg->message = $message;
                        $msg->id_order = intval($order->id);
                        $msg->private = 1;
                        $msg->add();
                    }
                }
                // Insert products from cart into order_detail table
                $products = $cart->getProducts();
                $productsList = '';
                $db = Db::getInstance();
                $query = 'INSERT INTO `' . _DB_PREFIX_ . 'order_detail`
					(`id_order`, `product_id`, `product_attribute_id`, `product_name`, `product_quantity`, `product_quantity_in_stock`, `product_price`, `reduction_percent`, `reduction_amount`, `group_reduction`, `product_quantity_discount`, `product_ean13`, `product_upc`, `product_reference`, `product_supplier_reference`, `product_weight`, `tax_name`, `tax_rate`, `ecotax`, `ecotax_tax_rate`, `discount_quantity_applied`, `download_deadline`, `download_hash`, `customization`)
				VALUES ';
                $customizedDatas = Product::getAllCustomizedDatas((int) $order->id_cart);
                Product::addCustomizationPrice($products, $customizedDatas);
                $outOfStock = false;
                foreach ($products as $key => $product) {
                    $productQuantity = (int) Product::getQuantity((int) $product['id_product'], $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL);
                    $quantityInStock = $productQuantity - (int) $product['cart_quantity'] < 0 ? $productQuantity : (int) $product['cart_quantity'];
                    if ($id_order_state != _PS_OS_CANCELED_ and $id_order_state != _PS_OS_ERROR_) {
                        if (Product::updateQuantity($product, (int) $order->id)) {
                            $product['stock_quantity'] -= $product['cart_quantity'];
                        }
                        if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
                            $outOfStock = true;
                        }
                        if ($product['stock_quantity'] < 1) {
                            SolrSearch::updateProduct((int) $product['id_product']);
                        }
                        Product::updateDefaultAttribute($product['id_product']);
                    }
                    $price = Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, 6, NULL, false, true, $product['cart_quantity'], 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, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    // Add some informations for virtual products
                    $deadline = '0000-00-00 00:00:00';
                    $download_hash = NULL;
                    if ($id_product_download = ProductDownload::getIdFromIdProduct((int) $product['id_product'])) {
                        $productDownload = new ProductDownload((int) $id_product_download);
                        $deadline = $productDownload->getDeadLine();
                        $download_hash = $productDownload->getHash();
                    }
                    // Exclude VAT
                    if (Tax::excludeTaxeOption()) {
                        $product['tax'] = 0;
                        $product['rate'] = 0;
                        $tax_rate = 0;
                    } else {
                        $tax_rate = Tax::getProductTaxRate((int) $product['id_product'], $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $ecotaxTaxRate = 0;
                    if (!empty($product['ecotax'])) {
                        $ecotaxTaxRate = Tax::getProductEcotaxRate($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $quantityDiscount = SpecificPrice::getQuantityDiscount((int) $product['id_product'], Shop::getCurrentShop(), (int) $cart->id_currency, (int) $vat_address->id_country, (int) $customer->id_default_group, (int) $product['cart_quantity']);
                    $unitPrice = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? intval($product['id_product_attribute']) : NULL, 2, NULL, false, true, 1, false, (int) $order->id_customer, NULL, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    $quantityDiscountValue = $quantityDiscount ? (Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? Tools::ps_round($unitPrice, 2) : $unitPrice) - $quantityDiscount['price'] * (1 + $tax_rate / 100) : 0.0;
                    $specificPrice = 0;
                    $query .= '(' . (int) $order->id . ',
						' . (int) $product['id_product'] . ',
						' . (isset($product['id_product_attribute']) ? (int) $product['id_product_attribute'] : 'NULL') . ',
						\'' . pSQL($product['name'] . ((isset($product['attributes']) and $product['attributes'] != NULL) ? ' - ' . $product['attributes'] : '')) . '\',
						' . (int) $product['cart_quantity'] . ',
						' . $quantityInStock . ',
						' . (double) Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? 2 : 6, NULL, false, false, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}, $specificPrice, FALSE) . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'percentage') ? $specificPrice['reduction'] * 100 : 0.0) . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'amount') ? !$specificPrice['id_currency'] ? Tools::convertPrice($specificPrice['reduction'], $order->id_currency) : $specificPrice['reduction'] : 0.0) . ',
						' . (double) Group::getReduction((int) $order->id_customer) . ',
						' . $quantityDiscountValue . ',
						' . (empty($product['ean13']) ? 'NULL' : '\'' . pSQL($product['ean13']) . '\'') . ',
						' . (empty($product['upc']) ? 'NULL' : '\'' . pSQL($product['upc']) . '\'') . ',
						' . (empty($product['reference']) ? 'NULL' : '\'' . pSQL($product['reference']) . '\'') . ',
						' . (empty($product['supplier_reference']) ? 'NULL' : '\'' . pSQL($product['supplier_reference']) . '\'') . ',
						' . (double) ($product['id_product_attribute'] ? $product['weight_attribute'] : $product['weight']) . ',
						\'' . (empty($tax_rate) ? '' : pSQL($product['tax'])) . '\',
						' . (double) $tax_rate . ',
						' . (double) Tools::convertPrice(floatval($product['ecotax']), intval($order->id_currency)) . ',
						' . (double) $ecotaxTaxRate . ',
						' . (($specificPrice and $specificPrice['from_quantity'] > 1) ? 1 : 0) . ',
						\'' . pSQL($deadline) . '\',
						\'' . pSQL($download_hash) . '\', ' . $cart->getProductCustomizationCost($product['id_product']) . '),';
                    $customizationQuantity = 0;
                    if (isset($customizedDatas[$product['id_product']][$product['id_product_attribute']])) {
                        $customizationText = '';
                        foreach ($customizedDatas[$product['id_product']][$product['id_product_attribute']] as $customization) {
                            if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_])) {
                                foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] as $text) {
                                    if ($text['index'] == 8) {
                                        $customizationText .= 'Saree with unstitched blouse and fall/pico work.' . '<br />';
                                    } else {
                                        if ($text['index'] == 1) {
                                            $customizationText .= 'Pre-stitched saree with unstitched blouse and fall/pico work.' . '<br />';
                                        } else {
                                            if ($text['index'] == 2) {
                                                $customizationText .= 'Stitched to measure blouse.' . '<br />';
                                            } else {
                                                if ($text['index'] == 3) {
                                                    $customizationText .= 'Stitched to measure in-skirt.' . '<br />';
                                                } else {
                                                    if ($text['index'] == 4) {
                                                        $customizationText .= 'Stitched to measure kurta.' . '<br />';
                                                    } else {
                                                        if ($text['index'] == 5) {
                                                            $customizationText .= 'Stitched to measure salwar.' . '<br />';
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            if (isset($customization['datas'][_CUSTOMIZE_FILE_])) {
                                $customizationText .= sizeof($customization['datas'][_CUSTOMIZE_FILE_]) . ' ' . Tools::displayError('image(s)') . '<br />';
                            }
                            $customizationText .= '---<br />';
                        }
                        $customizationText = rtrim($customizationText, '---<br />');
                        $customizationQuantity = (int) $product['customizationQuantityTotal'];
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . $product['reference'] . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes_small']) ? ' ' . $product['attributes_small'] : '') . ' - ' . $this->l('Customized') . (!empty($customizationText) ? ' - ' . $customizationText : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(round(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $price : $price_wt), $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . $customizationQuantity . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice($customizationQuantity * round(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $price : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                    if (!$customizationQuantity or (int) $product['cart_quantity'] > $customizationQuantity) {
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . $product['reference'] . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes_small']) ? ' ' . $product['attributes_small'] : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(round(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $price : $price_wt), $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . ((int) $product['cart_quantity'] - $customizationQuantity) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(((int) $product['cart_quantity'] - $customizationQuantity) * round(Product::getTaxCalculationMethod() == PS_TAX_EXC ? $price : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                    //if giftcard, create voucher and send the mails now.
                    $categories = Product::getProductCategories($product['id_product']);
                    if (in_array(CAT_GIFTCARD, $categories)) {
                        $friendsName = '';
                        $friendsEmail = '';
                        $giftMessage = '';
                        foreach ($customizedDatas[$product['id_product']][$product['id_product_attribute']] as $customization) {
                            if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_])) {
                                foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] as $text) {
                                    if ($text['index'] == 21) {
                                        $friendsName = $text['value'];
                                    } else {
                                        if ($text['index'] == 22) {
                                            $friendsEmail = $text['value'];
                                        } else {
                                            if ($text['index'] == 23) {
                                                $giftMessage = $text['value'];
                                            } else {
                                                if ($text['index'] == 25) {
                                                    $couponCode = $text['value'];
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //$couponCode = "GC" . Tools::rand_string(8);
                        // create discount
                        $languages = Language::getLanguages($order);
                        $voucher = new Discount();
                        $voucher->id_discount_type = 2;
                        foreach ($languages as $language) {
                            $voucher->description[$language['id_lang']] = $product['name'];
                        }
                        $voucher->value = (double) $unitPrice;
                        $voucher->name = $couponCode;
                        $voucher->id_currency = 2;
                        //USD
                        $voucher->quantity = 1;
                        $voucher->quantity_per_user = 1;
                        $voucher->cumulable = 1;
                        $voucher->cumulable_reduction = 1;
                        $voucher->minimal = 0;
                        $voucher->active = 1;
                        $voucher->cart_display = 0;
                        $now = time();
                        $voucher->date_from = date('Y-m-d H:i:s', $now);
                        $voucher->date_to = date('Y-m-d H:i:s', $now + 3600 * 24 * 365);
                        /* 365 days */
                        $voucher->add();
                        $productObj = new Product($product['id_product'], true, 1);
                        $idImage = $productObj->getCoverWs();
                        if ($idImage) {
                            $idImage = $productObj->id . '-' . $idImage;
                        } else {
                            $idImage = Language::getIsoById(1) . '-default';
                        }
                        $params = array();
                        $params['{voucher_code}'] = $voucher->name;
                        $params['{freinds_name}'] = $friendsName;
                        $params['{gift_message}'] = $giftMessage;
                        $params['{product_name}'] = $product['name'];
                        $params['{voucher_value}'] = $voucher->value;
                        $params['{image_url}'] = _PS_BASE_URL_ . _PS_IMG_ . 'banners/' . $productObj->location;
                        $params['{sender_name}'] = $customer->firstname . ' ' . $customer->lastname;
                        $subject = $friendsName . ', You Have Received A $' . $voucher->value . ' IndusDiva Gift Card';
                        @Mail::Send(1, 'gift_card', $subject, $params, $friendsEmail, $friendsName, '*****@*****.**', 'Indusdiva.com', NULL, NULL, _PS_MAIL_DIR_, true);
                        @Mail::Send(1, 'gift_card', $subject, $params, $customer->email, $customer->firstname . ' ' . $customer->lastname, '*****@*****.**', 'Indusdiva.com', NULL, NULL, _PS_MAIL_DIR_, true);
                    }
                }
                // end foreach ($products)
                $query = rtrim($query, ',');
                $result = $db->Execute($query);
                // Insert discounts from cart into order_discount table
                $discounts = $cart->getDiscounts();
                $discountsList = '';
                $total_discount_value = 0;
                $shrunk = false;
                foreach ($discounts as $discount) {
                    $objDiscount = new Discount((int) $discount['id_discount'], $order->id_lang);
                    $value = $objDiscount->getValue(sizeof($discounts), $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS), $order->total_shipping, $cart->id);
                    if ($objDiscount->id_discount_type == 2 || $objDiscount->id_discount_type == 4 and in_array($objDiscount->behavior_not_exhausted, array(1, 2))) {
                        $shrunk = true;
                    }
                    if ($shrunk and $total_discount_value + $value > $order->total_products + $order->total_shipping + $order->total_wrapping) {
                        $amount_to_add = $order->total_products + $order->total_shipping + $order->total_wrapping - $total_discount_value;
                        if ($objDiscount->id_discount_type == 2 || $objDiscount->id_discount_type == 4 and $objDiscount->behavior_not_exhausted == 2) {
                            $voucher = new Discount();
                            foreach ($objDiscount as $key => $discountValue) {
                                $voucher->{$key} = $discountValue;
                            }
                            $voucher->name = 'VSRK' . (int) $order->id_customer . 'O' . (int) $order->id;
                            $voucher->value = (double) $value - $amount_to_add;
                            $voucher->add();
                            $params['{voucher_amount}'] = Tools::displayPrice($voucher->value, $currency, false);
                            $params['{voucher_num}'] = $voucher->name;
                            @Mail::Send((int) $order->id_lang, 'voucher', Mail::l('New voucher regarding your order #') . $order->id, $params, $customer->email, $customer->firstname . ' ' . $customer->lastname);
                        }
                    } else {
                        $amount_to_add = $value;
                    }
                    $order->addDiscount($objDiscount->id, $objDiscount->name, $amount_to_add);
                    $total_discount_value += $amount_to_add;
                    if ($id_order_state != _PS_OS_ERROR_ and $id_order_state != _PS_OS_CANCELED_) {
                        $objDiscount->quantity = $objDiscount->quantity - 1;
                    }
                    $objDiscount->update();
                    $discountsList .= '<tr style="background-color:#EBECEE;">
							<td colspan="4" style="padding: 0.6em 0.4em; text-align: right;">' . $this->l('Voucher code:') . ' ' . $objDiscount->name . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . ($value != 0.0 ? '-' : '') . Tools::displayPrice($value, $currency, false) . '</td>
					</tr>';
                }
                // Specify order id for message
                $oldMessage = Message::getMessageByCartId((int) $cart->id);
                if ($oldMessage) {
                    $message = new Message((int) $oldMessage['id_message']);
                    $message->id_order = (int) $order->id;
                    $message->update();
                }
                // Hook new order
                $orderStatus = new OrderState((int) $id_order_state, (int) $order->id_lang);
                if (Validate::isLoadedObject($orderStatus)) {
                    Hook::newOrder($cart, $order, $customer, $currency, $orderStatus);
                    foreach ($cart->getProducts() as $product) {
                        if ($orderStatus->logable) {
                            ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']);
                        }
                    }
                }
                if (isset($outOfStock) and $outOfStock) {
                    $history = new OrderHistory();
                    $history->id_order = (int) $order->id;
                    $history->changeIdOrderState(_PS_OS_OUTOFSTOCK_, (int) $order->id);
                    $history->addWithemail();
                }
                // Set order state in order history ONLY even if the "out of stock" status has not been yet reached
                // So you migth have two order states
                $new_history = new OrderHistory();
                $new_history->id_order = (int) $order->id;
                $new_history->changeIdOrderState((int) $id_order_state, (int) $order->id);
                $new_history->addWithemail(true, $extraVars);
                //Payment status
                $paymentHistory = new OrderPaymentHistory();
                $paymentHistory->id_order = (int) $order->id;
                $paymentHistory->changeIdOrderPaymentState($id_payment_state, (int) $order->id);
                $paymentHistory->addState();
                // Order is reloaded because the status just changed
                $order = new Order($order->id);
                //Update tracking code for quantium
                if ($order->id_carrier == QUANTIUM) {
                    if (strpos($order->payment, 'COD') === false) {
                        $order->shipping_number = 'VBN' . $order->id;
                    } else {
                        $order->shipping_number = 'VBC' . $order->id;
                    }
                    $order->update();
                } else {
                    if ($order->id_carrier == SABEXPRESS) {
                        $db = Db::getInstance();
                        $db->Execute('LOCK TABLES vb_awb_pool WRITE');
                        $res = $db->getRow("select min(id) as 'id', awb from vb_awb_pool where id_carrier = " . SABEXPRESS . " and assigned = 0");
                        $awb = $res['awb'];
                        $id = $res['id'];
                        $db->Execute("update vb_awb_pool set assigned = 1 where id = " . $id);
                        $db->Execute('UNLOCK TABLES');
                        $order->shipping_number = $awb;
                        $order->update();
                    } else {
                        if ($order->id_carrier == AFL) {
                            $db = Db::getInstance();
                            $db->Execute('LOCK TABLES vb_awb_pool WRITE');
                            $res = $db->getRow("select min(id) as 'id' , awb from vb_awb_pool where id_carrier = " . AFL . " and assigned = 0");
                            $awb = $res['awb'];
                            $id = $res['id'];
                            $db->Execute("update vb_awb_pool set assigned = 1 where id = " . $id);
                            $db->Execute('UNLOCK TABLES');
                            $order->shipping_number = $awb;
                            $order->update();
                        }
                    }
                }
                // Send an e-mail to customer
                if ($id_order_state != _PS_OS_ERROR_ and $id_order_state != _PS_OS_CANCELED_ and $customer->id and $id_order_state != _PS_OS_OP_PAYEMENT_FAILED) {
                    //deduct reward points
                    $points_redeemed = $cart->getPoints();
                    if ($points_redeemed) {
                        VBRewards::removeRewardPoints($order->id_customer, EVENT_POINTS_REDEEMED, 0, $cart->getPoints(), 'Coins redeemed - Order no ' . $order->id, $order->id, $order->date_add);
                    }
                    /*
                    if(strpos($order->payment, 'COD') === false && $order->total_paid_real > 0)
                    {
                        VBRewards::addRewardPoints($order->id_customer, ONLINE_ORDER, 0, 100, 'Online payment bonus - Order no ' . $order->id, $order->id, $order->date_add);
                    }
                    */
                    $invoice = new Address((int) $order->id_address_invoice);
                    $delivery = new Address((int) $order->id_address_delivery);
                    $carrier = new Carrier((int) $order->id_carrier, $order->id_lang);
                    $delivery_state = $delivery->id_state ? new State((int) $delivery->id_state) : false;
                    $invoice_state = $invoice->id_state ? new State((int) $invoice->id_state) : false;
                    $shippingdate = new DateTime($order->expected_shipping_date);
                    $data = array('{firstname}' => $customer->firstname, '{shipping_date}' => $shippingdate->format("F j, Y"), '{lastname}' => $customer->lastname, '{email}' => $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="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')), '{invoice_block_html}' => $this->_getFormatedAddress($invoice, "<br />", array('firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; 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}' => sprintf("#%06d", (int) $order->id), '{date}' => date("F j, Y, g:i a"), '{carrier}' => $carrier->name, '{payment}' => Tools::substr($order->payment, 0, 32), '{products}' => $productsList, '{discounts}' => $discountsList, '{total_paid}' => Tools::displayPrice($order->total_paid, $currency, false), '{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_cod - $order->total_wrapping + $order->total_discounts, $currency, false), '{total_discounts}' => Tools::displayPrice($order->total_discounts, $currency, false), '{total_shipping}' => Tools::displayPrice($order->total_shipping, $currency, false), '{total_cod}' => Tools::displayPrice($order->total_cod, $currency, false), '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $currency, false));
                    if (is_array($extraVars)) {
                        $data = array_merge($data, $extraVars);
                    }
                    // Join PDF invoice
                    if ((int) Configuration::get('PS_INVOICE') and Validate::isLoadedObject($orderStatus) and $orderStatus->invoice and $order->invoice_number) {
                        $fileAttachment['content'] = PDF::invoice($order, 'S');
                        $fileAttachment['name'] = $fileAttachment['name'] = 'IndusDiva Order #' . sprintf('%06d', (int) $order->id) . '.pdf';
                        $fileAttachment['mime'] = 'application/pdf';
                    } else {
                        $fileAttachment = NULL;
                    }
                    if (Validate::isEmail($customer->email)) {
                        if ($id_order_state == _PS_OS_BANKWIRE_) {
                            Mail::Send((int) $order->id_lang, 'order_conf_bankwire', Mail::l('Your order #' . $order->id . ' with IndusDiva.com is confirmed'), $data, $customer->email, $customer->firstname . ' ' . $customer->lastname, NULL, NULL, $fileAttachment);
                        } else {
                            $data['payment'] = 'Online Payment';
                            Mail::Send((int) $order->id_lang, 'order_conf', Mail::l('Your order #' . $order->id . ' with IndusDiva.com is confirmed'), $data, $customer->email, $customer->firstname . ' ' . $customer->lastname, NULL, NULL, $fileAttachment);
                        }
                    }
                    //Send SMS
                    //$smsText = 'Dear customer, your order #'.$order->id.' at IndusDiva.com is confirmed and will be delivered to you within 3-5 business days. www.indusdiva.com';
                    //Tools::sendSMS($delivery->phone_mobile, $smsText);
                }
                $this->currentOrder = (int) $order->id;
                return true;
            } else {
                $errorMessage = Tools::displayError('Order creation failed');
                Logger::addLog($errorMessage, 4, '0000002', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
        } else {
            $errorMessage = Tools::displayError('Cart can\'t be loaded or an order has already been placed using this cart');
            Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($cart->id));
            die($errorMessage);
        }
    }