bebeboutik/override/classes/Cart.php
Marion Muszynski 13576c64d8 fix conflicts
2017-08-21 11:04:16 +02:00

1095 lines
52 KiB
PHP
Executable File

<?php
include_once dirname(__FILE__).'/../../modules/privatesales/Sale.php';
class Cart extends CartCore {
public static $carrier_special = array(51, 52, 58);
protected static $_cache_getSimpleQuantities = NULL;
/**
* Return cart products
*
* @result array Products
*/
public function getProducts($refresh = false, $id_product = false)
{
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 AND !$refresh)
return $this->_products;
$sql = '
SELECT cp.`id_product_attribute`, cp.`id_product`, cu.`id_customization`, cp.`quantity` AS cart_quantity, cu.`quantity` AS customization_quantity, pl.`name`,
pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, p.`on_sale`, p.`ecotax`, p.`additional_shipping_cost`, p.`available_for_order`,
p.`quantity`, p.`price`, p.`weight`, p.`width`, p.`height`, p.`depth`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`, IFNULL(pa.`minimal_quantity`, p.`minimal_quantity`) as minimal_quantity,
t.`id_tax`, tl.`name` AS tax, t.`rate`, pa.`price` AS price_attribute, pa.`quantity` AS quantity_attribute,
pa.`ecotax` AS ecotax_attr, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id,
IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference,
IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_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,
pai.`id_image` pai_id_image, il.`legend` pai_legend
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product`
LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.(int)$this->id_lang.')
LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`)
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
AND tr.`id_country` = '.(int)Country::getDefaultCountryId().'
AND tr.`id_state` = 0)
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)$this->id_lang.')
LEFT JOIN `'._DB_PREFIX_.'customization` cu ON (cp.`id_product` = cu.`id_product` AND cp.`id_product_attribute` = cu.`id_product_attribute` AND cu.`id_cart` = cp.`id_cart`)
LEFT JOIN `'._DB_PREFIX_.'product_attribute_image` pai ON (pai.`id_product_attribute` = pa.`id_product_attribute`)
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (il.`id_image` = pai.`id_image` AND il.`id_lang` = '.(int)$this->id_lang.')
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.(int)$this->id_lang.')
WHERE cp.`id_cart` = '.(int)$this->id.'
'.($id_product ? ' AND cp.`id_product` = '.(int)$id_product : '').'
AND p.`id_product` IS NOT NULL
GROUP BY unique_id
ORDER BY cp.date_add ASC';
$result = Db::getInstance()->ExecuteS($sql);
// Reset the cache before the following return, or else an empty cart will add dozens of queries
$productsIds = array();
$paIds = array();
foreach ($result as $row)
{
$productsIds[] = $row['id_product'];
$paIds[] = $row['id_product_attribute'];
}
// Thus you can avoid one query per product, because there will be only one query for all the products of the cart
Product::cacheProductsFeatures($productsIds);
self::cacheSomeAttributesLists($paIds, $this->id_lang);
$this->_products = array();
if (empty($result))
return array();
foreach ($result AS $row)
{
if (isset($row['ecotax_attr']) AND $row['ecotax_attr'] > 0)
$row['ecotax'] = (float)($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']) AND (int)$row['id_product_attribute'])
{
$row['weight'] = $row['weight_attribute'];
$row['stock_quantity'] = $row['quantity_attribute'];
}
if ($this->_taxCalculationMethod == PS_TAX_EXC)
{
$row['price'] = Product::getPriceStatic((int)$row['id_product'], false, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, true, (int)($row['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), $specificPriceOutput); // Here taxes are computed only once the quantity has been applied to the product price
$row['price_wt'] = Product::getPriceStatic((int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, true, (int)($row['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));
$row['price_without_reduc'] = Product::getPriceStatic((int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, false, (int)($row['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));
$tax_rate = Tax::getProductTaxRate((int)$row['id_product'], (int)($this->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
$row['total_wt'] = Tools::ps_round($row['price'] * (float)$row['cart_quantity'] * (1 + (float)($tax_rate) / 100), 2);
$row['total'] = $row['price'] * (int)($row['cart_quantity']);
}
else
{
$row['price'] = Product::getPriceStatic((int)$row['id_product'], false, (int)$row['id_product_attribute'], 6, NULL, false, true, $row['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), $specificPriceOutput);
$row['price_wt'] = Product::getPriceStatic((int)$row['id_product'], true, (int)$row['id_product_attribute'], 2, NULL, false, true, $row['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));
$row['price_without_reduc'] = Product::getPriceStatic((int)$row['id_product'], true, isset($row['id_product_attribute']) ? (int)($row['id_product_attribute']) : NULL, 2, NULL, false, false, (int)($row['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));
/* In case when you use QuantityDiscount, getPriceStatic() can be return more of 2 decimals */
$row['price_wt'] = Tools::ps_round($row['price_wt'], 2);
$row['total_wt'] = $row['price_wt'] * (int)($row['cart_quantity']);
$row['total'] = Tools::ps_round($row['price'] * (int)($row['cart_quantity']), 2);
}
if (!isset($row['pai_id_image']) OR $row['pai_id_image'] == 0)
{
$row2 = Db::getInstance()->getRow('
SELECT i.`id_image`, il.`legend`
FROM `'._DB_PREFIX_.'image` i
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$this->id_lang.')
WHERE i.`id_product` = '.(int)$row['id_product'].' AND i.`cover` = 1');
if (!$row2)
$row2 = array('id_image' => false, 'legend' => false);
else
$row = array_merge($row, $row2);
}
else
{
$row['id_image'] = $row['pai_id_image'];
$row['legend'] = $row['pai_legend'];
}
$row['reduction_applies'] = ($specificPriceOutput AND (float)$specificPriceOutput['reduction']);
$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]);
$category_name = Db::getInstance()->getRow('
SELECT cl.`name`
FROM `'._DB_PREFIX_.'product_ps_cache` ps
LEFT JOIN `'._DB_PREFIX_.'privatesale` s ON (s.`id_sale` = ps.`id_sale`)
LEFT JOIN `'._DB_PREFIX_.'category` c ON (c.`id_category` = s.`id_category`)
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (cl.`id_category` = c.`id_category`)
WHERE ps.`id_product` = '.(int)$row['id_product'].'
AND cl.`id_lang` = '.(int)$this->id_lang
);
$row['category_name'] = $category_name['name'];
$this->_products[] = $row;
}
return $this->_products;
}
function getOrderShippingCost($id_carrier=NULL, $useTax=TRUE, $add_carrier_cost = true) {
global $defaultCountry;
if ($this->isVirtualCart())
return 0;
// Checking discounts in cart
$products = $this->getProducts();
$discounts = $this->getDiscounts(TRUE);
if($discounts) {
foreach($discounts as $id_discount) {
if($id_discount['id_discount_type'] == 3) {
if ($id_discount['minimal'] > 0) {
$total_cart = 0;
foreach($products as $product) {
$total_cart += $product['total_wt'];
}
if($total_cart >= $id_discount['minimal']) {
return 0;
}
} else {
return 0;
}
}
}
}
// Order total in default currency without fees
$order_total = $this->getOrderTotal(TRUE, Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING);
// Start with shipping cost at 0
$shipping_cost = 0;
// If no product added, return 0
if ($order_total <= 0 && !(int)(self::getNbProducts($this->id))) {
return $shipping_cost;
}
// Get id zone
if(isset($this->id_address_delivery)
&& $this->id_address_delivery
&& Customer::customerHasAddress($this->id_customer, $this->id_address_delivery)) {
$id_zone = Address::getZoneById((int)($this->id_address_delivery));
} else {
// This method can be called from the backend, and $defaultCountry won't be defined
if(!Validate::isLoadedObject($defaultCountry)) {
$defaultCountry = new Country(Configuration::get('PS_COUNTRY_DEFAULT'), Configuration::get('PS_LANG_DEFAULT'));
}
$id_zone = (int)$defaultCountry->id_zone;
}
// If no carrier, select default one
if(!$id_carrier) {
$id_carrier = $this->id_carrier;
}
if($id_carrier && !$this->isCarrierInRange($id_carrier, $id_zone)) {
$id_carrier = '';
}
if(empty($id_carrier) && $this->isCarrierInRange(Configuration::get('PS_CARRIER_DEFAULT'), $id_zone)) {
$id_carrier = (int)(Configuration::get('PS_CARRIER_DEFAULT'));
}
if(empty($id_carrier)) {
if((int)($this->id_customer)) {
$customer = new Customer((int)($this->id_customer));
$result = Carrier::getCarriers((int)(Configuration::get('PS_LANG_DEFAULT')), TRUE, FALSE, (int)($id_zone), $customer->getGroups());
unset($customer);
} else {
$result = Carrier::getCarriers((int)(Configuration::get('PS_LANG_DEFAULT')), TRUE, FALSE, (int)($id_zone));
}
foreach ($result as $k => $row) {
if ($row['id_carrier'] == Configuration::get('PS_CARRIER_DEFAULT')) {
continue;
}
if (!isset(self::$_carriers[$row['id_carrier']])) {
self::$_carriers[$row['id_carrier']] = new Carrier((int)($row['id_carrier']));
}
$carrier = self::$_carriers[$row['id_carrier']];
// Get only carriers that are compliant with shipping method
if(($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT && $carrier->getMaxDeliveryPriceByWeight($id_zone) === FALSE)
|| ($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_PRICE && $carrier->getMaxDeliveryPriceByPrice($id_zone) === FALSE)) {
unset($result[$k]);
continue ;
}
// If out-of-range behavior carrier is set on "Desactivate carrier"
if($row['range_behavior']) {
// Get only carriers that have a range compatible with cart
if(($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT && (!Carrier::checkDeliveryPriceByWeight($row['id_carrier'], $this->getTotalWeight(), $id_zone)))
|| ($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_PRICE && (!Carrier::checkDeliveryPriceByPrice($row['id_carrier'], $this->getOrderTotal(TRUE, Cart::BOTH_WITHOUT_SHIPPING), $id_zone, (int)($this->id_currency))))) {
unset($result[$k]);
continue ;
}
}
if($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT) {
$shipping = $carrier->getDeliveryPriceByWeight($this->getTotalWeight(), $id_zone);
} else {
$shipping = $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)($this->id_currency));
}
if(!isset($minShippingPrice)) {
$minShippingPrice = $shipping;
}
if($shipping <= $minShippingPrice) {
$id_carrier = (int)($row['id_carrier']);
$minShippingPrice = $shipping;
}
}
}
if(empty($id_carrier)) {
$id_carrier = Configuration::get('PS_CARRIER_DEFAULT');
}
if(!isset(self::$_carriers[$id_carrier])) {
self::$_carriers[$id_carrier] = new Carrier((int)($id_carrier), Configuration::get('PS_LANG_DEFAULT'));
}
$carrier = self::$_carriers[$id_carrier];
if(!Validate::isLoadedObject($carrier)) {
die(Tools::displayError('Fatal error: "no default carrier"'));
}
if(!$carrier->active) {
return $shipping_cost;
}
// Free fees if free carrier
if($carrier->is_free == 1) {
return 0;
}
// Select carrier tax
if($useTax && !Tax::excludeTaxeOption()) {
$carrierTax = Tax::getCarrierTaxRate((int)$carrier->id, (int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
}
$configuration = Configuration::getMultiple(array('PS_SHIPPING_FREE_PRICE', 'PS_SHIPPING_HANDLING', 'PS_SHIPPING_METHOD', 'PS_SHIPPING_FREE_WEIGHT'));
include_once(dirname(__FILE__).'/../../modules/giftvoucher/giftvoucher.php');
$dgv = new GiftVoucher();
if ($dgv->checkFreeShippingPriceCart($this)) return 0;
// Free fees
$free_fees_price = 0;
if(isset($configuration['PS_SHIPPING_FREE_PRICE'])) {
$free_fees_price = Tools::convertPrice((float)($configuration['PS_SHIPPING_FREE_PRICE']), Currency::getCurrencyInstance((int)($this->id_currency)));
}
$orderTotalwithDiscounts = $this->getOrderTotal(TRUE, Cart::BOTH_WITHOUT_SHIPPING);
if($orderTotalwithDiscounts >= (float)($free_fees_price) && (float)($free_fees_price) > 0) {
return $shipping_cost;
}
if(isset($configuration['PS_SHIPPING_FREE_WEIGHT']) && $this->getTotalWeight() >= (float)($configuration['PS_SHIPPING_FREE_WEIGHT']) && (float)($configuration['PS_SHIPPING_FREE_WEIGHT']) > 0) {
return $shipping_cost;
}
// Get shipping cost using correct method
if($carrier->range_behavior) {
// Get id zone
if(
isset($this->id_address_delivery)
&& $this->id_address_delivery
&& Customer::customerHasAddress($this->id_customer, $this->id_address_delivery)
) {
$id_zone = Address::getZoneById((int)($this->id_address_delivery));
} else {
$id_zone = (int)$defaultCountry->id_zone;
}
if(($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT && (!Carrier::checkDeliveryPriceByWeight($carrier->id, $this->getTotalWeight(), $id_zone)))
|| ($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_PRICE && (!Carrier::checkDeliveryPriceByPrice($carrier->id, $this->getOrderTotal(TRUE, Cart::BOTH_WITHOUT_SHIPPING), $id_zone, (int)($this->id_currency))))) {
$shipping_cost += 0;
} else {
if ($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT) {
$shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight(), $id_zone);
} else { // by price
$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)($this->id_currency));
}
}
} else {
if($carrier->getShippingMethod() == Carrier::SHIPPING_METHOD_WEIGHT) {
$shipping_cost += $carrier->getDeliveryPriceByWeight($this->getTotalWeight(), $id_zone);
} else {
$shipping_cost += $carrier->getDeliveryPriceByPrice($order_total, $id_zone, (int)($this->id_currency));
}
}
// Adding handling charges
if(isset($configuration['PS_SHIPPING_HANDLING']) && $carrier->shipping_handling) {
$shipping_cost += (float)($configuration['PS_SHIPPING_HANDLING']);
}
// Additional Shipping Cost per product
foreach($products as $product) {
$shipping_cost += $product['additional_shipping_cost'] * $product['cart_quantity'];
}
$shipping_cost = Tools::convertPrice($shipping_cost, Currency::getCurrencyInstance((int)($this->id_currency)));
//get external shipping cost from module
if($carrier->shipping_external) {
$moduleName = $carrier->external_module_name;
$module = Module::getInstanceByName($moduleName);
if(Validate::isLoadedObject($module)) {
if(array_key_exists('id_carrier', $module)) {
$module->id_carrier = $carrier->id;
}
if($carrier->need_range) {
$shipping_cost = $module->getOrderShippingCost($this, $shipping_cost);
} else {
$shipping_cost = $module->getOrderShippingCostExternal($this);
}
// Check if carrier is available
if($shipping_cost === FALSE) {
return FALSE;
}
} else {
return FALSE;
}
}
if(Module::isInstalled('privatesales')) {
$product_cats = array();
foreach($products as $product) {
$product_cats[] = $product['id_category_default'];
}
$sales = Db::getInstance()->ExecuteS('
SELECT DISTINCT `id_sale`
FROM `'._DB_PREFIX_.'privatesale_category`
WHERE `id_category` IN ('.implode(', ', $product_cats).')
');
$cpt_sales = count($sales);
// si consommables forcer à 5euros
/*if ($cpt_sales==1) {
foreach ($sales as $key => $sale) {
if ((int) $sale['id_sale'] == (int) _SHOP_PRIVATESALES_CONSUMABLE) {
$sale = new Sale((int)$sale['id_sale']);
$sale_carriers = $sale->getCarriers();
foreach ($sale_carriers as $id_c) {
if ((int) $carrier->id == (int) $id_c) {
$shipping_cost = 5;
$shipping_cost = Tools::convertPrice($shipping_cost, Currency::getCurrencyInstance((int)($this->id_currency)));
return $shipping_cost;
}
}
unset($sale_carriers);
}
}
}*/
// Surcout transporteur classique
// if ($carrier->id == 33
// || $carrier->id == 24
// || $carrier->id == 37
// || $carrier->id == 45) {
// if ($carrier->id == 28
// || $carrier->id == 24
// || $carrier->id == 27)
// if ($carrier->id == 45
// || $carrier->id == 46
// || $carrier->id == 47
// || $carrier->id == 48) {
if($cpt_sales == 2) {
$shipping_cost += (float) Configuration::get('PS_SHIPPING_HANDLING_PS_1');
} elseif($cpt_sales == 3) {
$shipping_cost += (float) Configuration::get('PS_SHIPPING_HANDLING_PS_2');
} elseif($cpt_sales == 4) {
$shipping_cost += (float) Configuration::get('PS_SHIPPING_HANDLING_PS_3');
} elseif($cpt_sales == 5) {
$shipping_cost += (float) Configuration::get('PS_SHIPPING_HANDLING_PS_4');
} elseif($cpt_sales >= 6) {
$shipping_cost += (float) Configuration::get('PS_SHIPPING_HANDLING_PS_4');
}
// }
}
// Apply tax
if(isset($carrierTax)) {
$shipping_cost *= 1 + ($carrierTax / 100);
}
if(Module::isInstalled('privatesales') && $add_carrier_cost) {
if (class_exists('Sale')) {
if (in_array($carrier->id, self::$carrier_special)) {
if(Configuration::get('PRIVATESALES_CARRIERFENCE') ) {
$cart_products = $this->getProducts();
if(count($cart_products) > 0) {
$_carriers = array();
foreach ($cart_products as $key => $cart_product) {
$sale = Sale::getSaleFromCategory($cart_product['id_category_default']);
if($sale) {
$sale_carriers = $sale->getCarriers();
foreach ($sale_carriers as $carrier_test) {
if (!in_array($carrier_test, $_carriers)) {
$_carriers[] = $carrier_test;
}
}
unset($sale_carriers);
}
}
// not add self surcout
$delete_self = array_search($carrier->id, $_carriers);
unset($_carriers[$delete_self]);
// ajout du surcout
// $socolissimo_carriers = array(45, 33, 37, 22);
// $socolissimo_carriers = array(24, 27, 28, 22);
$socolissimo_carriers = array(87, 88, 89, 22);
$socolissimo_found = false;
foreach ($_carriers as $key => $carrier_to_add) {
if (in_array($carrier_to_add, $socolissimo_carriers) ) {
if (!$socolissimo_found ) {
$cart = new Cart($this->id);
// $total = $cart->getOrderShippingCost((int)$carrier_to_add, true, false);
// $total = $cart->getOrderShippingCost(45, true, false);
// $shipping_cost += $total;
$shipping_cost += 8;
$socolissimo_found = true;
} else {
continue;
}
} else {
$cart = new Cart($this->id);
$total = $cart->getOrderShippingCost((int)$carrier_to_add, true, false);
$shipping_cost += $total;
}
}
}
}
}
}
}
return (float)(Tools::ps_round((float)($shipping_cost), 2));
}
/**
* @Override
* Get cart products quantitites
* @return Array Cart quantities
*/
public function checkQuantitiesDetails() {
if(Configuration::get('PS_CATALOG_MODE')) {
return FALSE;
}
$cart_qties = $this->getDetailedProductsQuantities();
$product_ids = array();
foreach ($cart_qties as $cart_product) {
$product_ids[] = (int) $cart_product['id_product'];
}
$available_qties = array();
foreach(Db::getInstance()->executeS('
SELECT
p.`id_product`,
pl.`name`,
IFNULL(pa.`id_product_attribute`, 0) as `id_product_attribute`,
IFNULL(pa.`quantity`, p.`quantity`) as `quantity`,
p.`active`,
p.`out_of_stock`
FROM `' . _DB_PREFIX_ . 'product` p
LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
ON p.`id_product` = pa.`id_product`
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl
ON pl.`id_product` = p.`id_product`
AND pl.`id_lang` = '.(int) $this->id_lang .'
WHERE p.`id_product` IN (' . implode(', ', $product_ids) . ')
') as $row){
$available_qties[$row['id_product'] . '_' . $row['id_product_attribute']] = array(
'id_product_attribute' => (int) $row['id_product_attribute'],
'id_product' => (int) $row['id_product'],
'name' => $row['name'],
'quantity' => (int) $row['quantity'],
'active' => (int) $row['id_product'],
'out_of_stock' => (int) $row['out_of_stock']);
}
$not_found = false;
foreach ($cart_qties as $pkey => $cart_poduct) {
if (isset($available_qties[$pkey]) && (
!$available_qties[$pkey]['active'] ||
($available_qties[$pkey]['quantity'] < $cart_poduct['quantity'] && $available_qties[$pkey]['out_of_stock'] != 1)
)
){
return $available_qties[$pkey];
}
else{
$not_found = true;
}
}
if ($not_found){
foreach($this->getProducts() as $product) {
if(!$product['active'] || (!$product['allow_oosp'] && $product['stock_quantity'] < $product['cart_quantity']) || !$product['available_for_order']) {
return $product;
}
}
}
return TRUE;
}
/**
* @Override
* Update product quantity
*
* @param integer $quantity Quantity to add (or substract)
* @param integer $id_product Product ID
* @param integer $id_product_attribute Attribute ID if needed
* @param string $operator Indicate if quantity must be increased or decreased
*/
public function updateQty($quantity, $id_product, $id_product_attribute = NULL, $id_customization = false, $operator = 'up')
{
$lang = Configuration::get('PS_LANG_DEFAULT');
$product = new Product((int)$id_product, false, (int) $lang);
/* If we have a product combination, the minimal quantity is set with the one of this combination */
if (!empty($id_product_attribute))
$minimalQuantity = (int)Attribute::getAttributeMinimalQty((int)$id_product_attribute);
else
$minimalQuantity = (int)$product->minimal_quantity;
if (!Validate::isLoadedObject($product))
die(Tools::displayError());
if (isset(self::$_nbProducts[$this->id]))
unset(self::$_nbProducts[$this->id]);
if (isset(self::$_totalWeight[$this->id]))
unset(self::$_totalWeight[$this->id]);
if ((int)$quantity <= 0)
return $this->deleteProduct((int)$id_product, (int)$id_product_attribute, (int)$id_customization);
else if (!$product->available_for_order OR Configuration::get('PS_CATALOG_MODE'))
return false;
else
{
/* Check if the product is already in the cart */
$result = $this->containsProduct((int)$id_product, (int)$id_product_attribute, (int)$id_customization);
/* Update quantity if product already exist */
if ($result)
{
if ($operator == 'up')
{
/**
* @Override check packs quantity
*/
$cart_qties = $this->getDetailedProductsQuantities();
$cart_add_qties = array();
$cart_add_ids = array();
if (Pack::isPack((int) $id_product, (int) $lang)){
// If is pack and not availbale return false
if (!Pack::isInStock((int) $id_product, (int) $lang))
return false;
$pack_items = Pack::getSimplePack((int) $id_product);
foreach ($pack_items as $pack_item) {
$p_key = $pack_item['id_product_item'] . '_0';
if (!isset($cart_add_qties[$p_key])){
$cart_add_qties[$p_key] = 0;
}
$cart_add_qties[$p_key] += $quantity * $pack_item['quantity'];
$cart_add_ids[] = $pack_item['id_product_item'];
}
$cart_add_qties[$id_product . '_0'] += $quantity;
$cart_add_ids[] = (int) $id_product;
}
else{
$p_key = (int) $id_product . '_' . ($id_product_attribute ? (int) $id_product_attribute : 0);
$cart_add_qties[$p_key] = $quantity;
$cart_add_ids[] = (int) $id_product;
}
$available_qties = array();
foreach(Db::getInstance()->executeS('
SELECT
p.`id_product`,
IFNULL(pa.`id_product_attribute`, 0) as `id_product_attribute`,
IFNULL(pa.`quantity`, p.`quantity`) as `quantity`,
p.`out_of_stock`
FROM `' . _DB_PREFIX_ . 'product` p
LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
ON p.`id_product` = pa.`id_product`
WHERE p.`id_product` IN (' . implode(', ', $cart_add_ids) . ')
') as $row){
$available_qties[$row['id_product'] . '_' . $row['id_product_attribute']] = array(
'quantity' => $row['quantity'],
'out_of_stock' => $row['out_of_stock']);
}
$qty = '+ ' . (int) $quantity;
$newQty = (int) $result['quantity'] + (int) $quantity;
foreach ($cart_add_qties as $p_key => $new_qty) {
if (isset($cart_qties[$p_key])) {
$new_qty += $cart_qties[$p_key]['quantity'];
}
if (isset($available_qties[$p_key]) &&
!Product::isAvailableWhenOutOfStock((int) $available_qties[$p_key]['out_of_stock']) &&
$new_qty > $available_qties[$p_key]['quantity']
){
return false;
}
}
}
elseif ($operator == 'down')
{
$qty = '- '.(int)$quantity;
$newQty = (int)$result['quantity'] - (int)$quantity;
if ($newQty < $minimalQuantity AND $minimalQuantity > 1)
return -1;
}
else
return false;
/* Delete product from cart */
if ($newQty <= 0)
return $this->deleteProduct((int)$id_product, (int)$id_product_attribute, (int)$id_customization);
else if ($newQty < $minimalQuantity)
return -1;
else
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'cart_product`
SET `quantity` = `quantity` '.$qty.', `date_add` = NOW()
WHERE `id_product` = '.(int)$id_product.
(!empty($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
AND `id_cart` = '.(int)$this->id.'
LIMIT 1');
}
/* Add product to the cart */
else
{
/**
* @Override check packs quantity
*/
$cart_qties = $this->getDetailedProductsQuantities();
$cart_add_qties = array();
$cart_add_ids = array();
if (Pack::isPack((int) $id_product, (int) $lang)){
// If is pack and not availbale return false
if (!Pack::isInStock((int) $id_product, (int) $lang))
return false;
$pack_items = Pack::getSimplePack((int) $id_product);
foreach ($pack_items as $pack_item) {
$p_key = $pack_item['id_product_item'] . '_0';
if (!isset($cart_add_qties[$p_key])){
$cart_add_qties[$p_key] = 0;
}
$cart_add_qties[$p_key] += $quantity * $pack_item['quantity'];
$cart_add_ids[] = $pack_item['id_product_item'];
}
$cart_add_qties[$id_product . '_0'] += $quantity;
$cart_add_ids[] = (int) $id_product;
}
else{
$p_key = (int) $id_product . '_' . ($id_product_attribute ? (int) $id_product_attribute : 0);
$cart_add_qties[$p_key] = $quantity;
$cart_add_ids[] = (int) $id_product;
}
$available_qties = array();
foreach(Db::getInstance()->executeS('
SELECT
p.`id_product`,
IFNULL(pa.`id_product_attribute`, 0) as `id_product_attribute`,
IFNULL(pa.`quantity`, p.`quantity`) as `quantity`,
p.`out_of_stock`
FROM `' . _DB_PREFIX_ . 'product` p
LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
ON p.`id_product` = pa.`id_product`
WHERE p.`id_product` IN (' . implode(', ', $cart_add_ids) . ')
') as $row){
$available_qties[$row['id_product'] . '_' . $row['id_product_attribute']] = array(
'quantity' => $row['quantity'],
'out_of_stock' => $row['out_of_stock']);
}
foreach ($cart_add_qties as $p_key => $new_qty) {
if (isset($cart_qties[$p_key]))
$new_qty += $cart_qties[$p_key]['quantity'];
if (isset($available_qties[$p_key]) &&
!Product::isAvailableWhenOutOfStock((int) $available_qties[$p_key]['out_of_stock']) &&
$new_qty > $available_qties[$p_key]['quantity']
){
return false;
}
}
if ((int)$quantity < $minimalQuantity)
return -1;
if (!Db::getInstance()->AutoExecute(_DB_PREFIX_.'cart_product', array('id_product' => (int)$id_product,
'id_product_attribute' => (int)$id_product_attribute, 'id_cart' => (int)$this->id,
'quantity' => (int)$quantity, 'date_add' => date('Y-m-d H:i:s')), 'INSERT'))
return false;
}
}
// refresh cache of self::_products
$this->_products = $this->getProducts(true);
$this->update(true);
if ($product->customizable)
return $this->_updateCustomizationQuantity((int)$quantity, (int)$id_customization, (int)$id_product, (int)$id_product_attribute, $operator);
else
return true;
}
/**
* @Adding
* Get cart products quantitites
* @return Array Cart quantities
*/
public function getSimpleQuantities(){
if (isset(self::$_cache_getSimpleQuantities[(int) $this->id])) {
return self::$_cache_getSimpleQuantities[(int) $this->id];
}
self::$_cache_getSimpleQuantities[(int) $this->id] = Db::getInstance()->executeS('
SELECT `id_product`, `id_product_attribute`, `quantity`
FROM `' . _DB_PREFIX_ . 'cart_product`
WHERE `id_cart` = ' . (int) $this->id . '
');
return self::$_cache_getSimpleQuantities[(int) $this->id];
}
/**
* @Adding
* Get cart products quantitites
* @return Array Cart quantities
*/
public function getDetailedProductsQuantities(){
$cart_qties = $this->getSimpleQuantities();
$products_qties = array();
foreach ($cart_qties as $product) {
if (Pack::isPack($product['id_product'])){
$items = Pack::getSimplePack((int) $product['id_product']);
foreach ($items as $pack_item) {
$p_key = $pack_item['id_product_item'] . '_0';
if (!isset($products_qties[$p_key])){
$products_qties[$p_key] = array(
'id_product' => $pack_item['id_product_item'],
'id_product_attribute' => 0,
'quantity' => 0
);
}
$products_qties[$p_key]['quantity'] += $product['quantity'] * $pack_item['quantity'];
}
if (!isset($products_qties[$pack_item['id_product_pack'] . '_0'])){
$products_qties[$pack_item['id_product_pack'] . '_0'] = array(
'id_product' => $pack_item['id_product_pack'],
'id_product_attribute' => 0,
'quantity' => 0
);
}
$products_qties[$pack_item['id_product_pack'] . '_0']['quantity'] += $product['quantity'];
}
else{
$p_key = $product['id_product'] . '_' . $product['id_product_attribute'];
if (!isset($products_qties[$p_key])){
$products_qties[$p_key] = array(
'id_product' => $product['id_product'],
'id_product_attribute' => $product['id_product_attribute'],
'quantity' => 0
);
}
$products_qties[$p_key]['quantity'] += $product['quantity'];
}
}
return $products_qties;
}
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false)
{
global $cookie;
if (!$order_total)
return Tools::displayError('Cannot add voucher if order is free.');
if (!$discountObj->active)
return Tools::displayError('This voucher has already been used or is disabled.');
if (!$discountObj->quantity)
return Tools::displayError('This voucher has expired (usage limit attained).');
if ($discountObj->id_discount_type == 2 AND $this->id_currency != $discountObj->id_currency)
return Tools::displayError('This voucher can only be used in the following currency:').'
'.Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT `name` FROM `'._DB_PREFIX_.'currency` WHERE id_currency = '.(int)$discountObj->id_currency);
if ($checkCartDiscount
AND (
$this->getDiscountsCustomer($discountObj->id) >= $discountObj->quantity_per_user
OR (Order::getDiscountsCustomer((int)($cookie->id_customer), $discountObj->id) + $this->getDiscountsCustomer($discountObj->id) >= $discountObj->quantity_per_user) >= $discountObj->quantity_per_user
)
)
return Tools::displayError('You cannot use this voucher anymore (usage limit attained).');
if (strtotime($discountObj->date_from) > time())
return Tools::displayError('This voucher is not yet valid');
if (strtotime($discountObj->date_to) < time())
return Tools::displayError('This voucher has expired.');
if (sizeof($discounts) >= 1 AND $checkCartDiscount)
{
if (!$discountObj->cumulable) {
return Tools::displayError('This voucher is not valid with other current discounts.');
}
foreach ($discounts as $discount) {
if (!$discount['cumulable']) {
return Tools::displayError('Voucher is not valid with other discounts.');
}
}
foreach($discounts as $discount) {
if ($discount['id_discount'] == $discountObj->id) {
return Tools::displayError('This voucher is already in your cart');
}
}
}
$groups = Customer::getGroupsStatic($this->id_customer);
if (($discountObj->id_customer OR $discountObj->id_group) AND ((($this->id_customer != $discountObj->id_customer) OR ($this->id_customer == 0)) AND !in_array($discountObj->id_group, $groups)))
{
if (!$cookie->isLogged()){
return Tools::displayError('You cannot use this voucher.').' - '.Tools::displayError('Please log in.');
}
return Tools::displayError('You cannot use this voucher.');
}
// @Override Antadis - check in custom group
if (!class_exists('CustomGroup')) {
require_once(_PS_MODULE_DIR_.'ant_customgroup/models/CustomGroup.php');
}
if (!CustomGroup::isValidDiscount($discountObj->id, $this->id_customer)) {
return Tools::displayError('This voucher has already been used or is disabled.');
}
// @End override
$onlyProductWithDiscount = false;
if (!$discountObj->cumulable_reduction)
{
foreach ($products as $product) {
if ($product['reduction_applies'] OR $product['on_sale']) {
$onlyProductWithDiscount = true;
}
}
}
if (!$discountObj->cumulable_reduction AND $onlyProductWithDiscount) {
return Tools::displayError('This voucher is not valid for marked or reduced products.');
}
$total_cart = 0;
foreach($products AS $product) {
if ((!$discountObj->cumulable_reduction AND !$product['reduction_applies'] AND !$product['on_sale']) OR $discountObj->cumulable_reduction)
$total_cart += $discountObj->include_tax ? $product['total_wt'] : $product['total'];
}
// @Override Antadis - check discount category
$categories = Discount::getCategories($discountObj->id);
$returnErrorNoProductCategory = true;
foreach($products AS $product)
{
if (count($categories)) {
if (Product::idIsOnCategoryId($product['id_product'], $categories))
{
if ((!$discountObj->cumulable_reduction AND !$product['reduction_applies'] AND !$product['on_sale']) OR $discountObj->cumulable_reduction)
$total_cart += $discountObj->include_tax ? $product['total_wt'] : $product['total'];
$returnErrorNoProductCategory = false;
} else {
$returnErrorNoProductCategory = true;
break;
}
} else {
$returnErrorNoProductCategory = false;
}
}
// @End Override Antadis - check discount category
if ($returnErrorNoProductCategory) {
return Tools::displayError('This discount does not apply to that product category.');
}
if ($total_cart < $discountObj->minimal)
return Tools::displayError('The order total is not high enough or this voucher cannot be used with those products.');
return false;
}
public function getDiscounts($lite = false, $refresh = false)
{
if (!$this->id)
return array();
if (!$refresh)
{
if (!$lite AND isset(self::$_discounts[$this->id]))
return self::$_discounts[$this->id];
if ($lite AND isset(self::$_discountsLite[$this->id]))
return self::$_discountsLite[$this->id];
}
$result = Db::getInstance()->ExecuteS('
SELECT d.*, `id_cart`
FROM `'._DB_PREFIX_.'cart_discount` c
LEFT JOIN `'._DB_PREFIX_.'discount` d ON c.`id_discount` = d.`id_discount`
WHERE `id_cart` = '.(int)($this->id));
// @Override Antadis - check discount category
$products = $this->getProducts();
foreach ($result AS $k => $discount)
{
$categories = Discount::getCategories((int)($discount['id_discount']));
if(count($categories)) {
$in_category = false;
foreach ($products AS $product) {
if (Product::idIsOnCategoryId((int)($product['id_product']), $categories))
{
$in_category = true;
} else{
$in_category = false;
break;
}
}
if (!$in_category)
unset($result[$k]);
}
}
// @End Override Antadis - check discount category
if ($lite)
{
self::$_discountsLite[$this->id] = $result;
return $result;
}
$total_products_wt = $this->getOrderTotal(true, Cart::ONLY_PRODUCTS);
$total_products = $this->getOrderTotal(false, Cart::ONLY_PRODUCTS);
$shipping_wt = $this->getOrderShippingCost();
$shipping = $this->getOrderShippingCost(NULL, false);
self::$_discounts[$this->id] = array();
foreach ($result as $row)
{
$discount = new Discount($row['id_discount'], (int)($this->id_lang));
$row['description'] = $discount->description ? $discount->description : $discount->name;
$row['value_real'] = $discount->getValue(sizeof($result), $total_products_wt, $shipping_wt, $this->id);
$row['value_tax_exc'] = $discount->getValue(sizeof($result), $total_products, $shipping, $this->id, false);
if ($row['value_real'] !== 0)
self::$_discounts[$this->id][] = $row;
else
$this->deleteDiscount($row['id_discount']);
}
return isset(self::$_discounts[$this->id]) ? self::$_discounts[$this->id] : NULL;
}
/**
* Return useful informations for cart
*
* @return array Cart details
*/
function getSummaryDetails()
{
global $cookie;
$delivery = new Address((int)($this->id_address_delivery));
$invoice = new Address((int)($this->id_address_invoice));
// New layout system with personalization fields
$formattedAddresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice);
$formattedAddresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery);
$total_tax = $this->getOrderTotal() - $this->getOrderTotal(false);
if ($total_tax < 0)
$total_tax = 0;
$total_free_ship = 0;
if ($free_ship = Tools::convertPrice((float)(Configuration::get('PS_SHIPPING_FREE_PRICE')), new Currency((int)($this->id_currency))))
{
$discounts = $this->getDiscounts();
$total_free_ship = $free_ship - ($this->getOrderTotal(true, Cart::ONLY_PRODUCTS) + $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
foreach ($discounts as $discount)
if ($discount['id_discount_type'] == 3)
{
$total_free_ship = 0;
break;
}
}
$products = $this->getProducts(false);
// assign delay to Products
if (Module::isInstalled('privatesales_delay')) {
require _PS_ROOT_DIR_.'/modules/privatesales_delay/saledelay.php';
$products = SaleDelay::associateDelay($products);
}
return array(
'delivery' => $delivery,
'delivery_state' => State::getNameById($delivery->id_state),
'invoice' => $invoice,
'invoice_state' => State::getNameById($invoice->id_state),
'formattedAddresses' => $formattedAddresses,
'carrier' => new Carrier((int)($this->id_carrier), $cookie->id_lang),
'products' => $products,
'discounts' => $this->getDiscounts(false, true),
'is_virtual_cart' => (int)$this->isVirtualCart(),
'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')),
'total_discounts' => $this->getOrderTotal(true, Cart::ONLY_DISCOUNTS),
'total_discounts_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_DISCOUNTS),
'total_wrapping' => $this->getOrderTotal(true, Cart::ONLY_WRAPPING),
'total_wrapping_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_WRAPPING),
'total_shipping' => $this->getOrderShippingCost(),
'total_shipping_tax_exc' => $this->getOrderShippingCost(NULL, false),
'total_products_wt' => $this->getOrderTotal(true, Cart::ONLY_PRODUCTS),
'total_products' => $this->getOrderTotal(false, Cart::ONLY_PRODUCTS),
'total_price' => $this->getOrderTotal(),
'total_tax' => $total_tax,
'total_price_without_tax' => $this->getOrderTotal(false),
'free_ship' => $total_free_ship);
}
public function printVersion($value, $params)
{
$versions = array(
'en' => 1,
'fr' => 2,
'es' => 3,
'it' => 5,
);
return '<img src="/img/l/'.(int) $versions[$value].'.jpg" alt="" />';
}
}