[*] Project : US + CA TaxSystem
This commit is contained in:
@@ -77,6 +77,8 @@ class Autoload
|
||||
*/
|
||||
public function load($classname)
|
||||
{
|
||||
// echo("Please load $classname.<br />");
|
||||
|
||||
// regenerate the class index if the requested class is not found in the index or if the requested file doesn't exists
|
||||
if (!isset($this->index[$classname]) || ($this->index[$classname] && !file_exists($this->root_dir.$this->index[$classname])))
|
||||
$this->generateIndex();
|
||||
@@ -87,6 +89,7 @@ class Autoload
|
||||
// If requested class does not exist, load associated core class
|
||||
if (isset($this->index[$classname]) && !$this->index[$classname])
|
||||
{
|
||||
|
||||
require_once($this->root_dir.$this->index[$classname.'Core']);
|
||||
if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core']))
|
||||
{
|
||||
@@ -104,10 +107,14 @@ class Autoload
|
||||
{
|
||||
// request a non Core Class load the associated Core class if exists
|
||||
if (isset($this->index[$classname.'Core']))
|
||||
{
|
||||
require_once($this->root_dir.$this->index[$classname.'Core']);
|
||||
}
|
||||
|
||||
if (isset($this->index[$classname]))
|
||||
{
|
||||
require_once($this->root_dir.$this->index[$classname]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Call directly ProductCore, ShopCore class
|
||||
|
||||
+25
-11
@@ -70,7 +70,7 @@ class CarrierCore extends ObjectModel
|
||||
|
||||
/** @var boolean Free carrier */
|
||||
public $is_free = false;
|
||||
|
||||
|
||||
/** @var int shipping behavior: by weight or by price */
|
||||
public $shipping_method = 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ class CarrierCore extends ObjectModel
|
||||
|
||||
/** @var boolean Need Range */
|
||||
public $need_range = 0;
|
||||
|
||||
|
||||
protected $langMultiShop = true;
|
||||
|
||||
protected $fieldsRequired = array('name', 'active');
|
||||
@@ -488,7 +488,7 @@ class CarrierCore extends ObjectModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$row['name'] = (strval($row['name']) != '0' ? $row['name'] : Configuration::get('PS_SHOP_NAME'));
|
||||
$row['price'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier']));
|
||||
$row['price_tax_exc'] = ($shippingMethod == Carrier::SHIPPING_METHOD_FREE ? 0 : $cart->getOrderShippingCost((int)$row['id_carrier'], false));
|
||||
@@ -590,7 +590,7 @@ class CarrierCore extends ObjectModel
|
||||
$where .= 'AND id_shop IS NULL AND id_group_shop = '.$shopGroupID;
|
||||
else
|
||||
$where .= 'AND id_shop = '.$shopID;
|
||||
|
||||
|
||||
return Db::getInstance()->delete(_DB_PREFIX_.'delivery', $where);
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ class CarrierCore extends ObjectModel
|
||||
$keys[] = 'id_shop';
|
||||
if (!in_array('id_group_shop', $keys))
|
||||
$keys[] = 'id_group_shop';
|
||||
|
||||
|
||||
if (!$shop)
|
||||
$shop = Context::getContext()->shop;
|
||||
$shopID = $shop->getID();
|
||||
@@ -623,7 +623,7 @@ class CarrierCore extends ObjectModel
|
||||
$values['id_shop'] = ($shopID) ? $shopID : null;
|
||||
if (!isset($values['id_group_shop']))
|
||||
$values['id_group_shop'] = ($shopGroupID) ? $shopGroupID : null;
|
||||
|
||||
|
||||
$sql .= '(';
|
||||
foreach ($values as $v)
|
||||
{
|
||||
@@ -650,7 +650,7 @@ class CarrierCore extends ObjectModel
|
||||
{
|
||||
if (!Validate::isUnsignedId($oldId))
|
||||
die(Tools::displayError());
|
||||
|
||||
|
||||
if (!$this->id)
|
||||
return false;
|
||||
|
||||
@@ -670,7 +670,7 @@ class CarrierCore extends ObjectModel
|
||||
VALUES ('.$this->id.','.(float)$val['delimiter1'].','.(float)$val['delimiter2'].')';
|
||||
Db::getInstance()->Execute($sql);
|
||||
$rangeID = (int)Db::getInstance()->Insert_ID();
|
||||
|
||||
|
||||
$rangePriceID = ($range == 'range_price') ? $rangeID : 'NULL';
|
||||
$rangeWeightID = ($range == 'range_weight') ? $rangeID : 'NULL';
|
||||
$sql = 'INSERT INTO '._DB_PREFIX_.$range.' (id_carrier, id_shop, id_group_shop, id_range_price, id_range_weight, id_zone, price)
|
||||
@@ -769,10 +769,24 @@ class CarrierCore extends ObjectModel
|
||||
|
||||
return self::$_cache_tax_rule[$id_carrier];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the taxes rate associated to the carrier
|
||||
*
|
||||
* @since 1.5
|
||||
* @param Address $address
|
||||
*/
|
||||
public function getTaxesRate(Address $address)
|
||||
{
|
||||
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
|
||||
$tax_calculator = $tax_manager->getTaxCalculator();
|
||||
return $tax_calculator->getTaxesRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* This tricky method generate a sql clause to check if ranged data are overloaded by multishop
|
||||
*
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @param string $rangeTable
|
||||
* @param Shop $shop
|
||||
@@ -791,7 +805,7 @@ class CarrierCore extends ObjectModel
|
||||
$where = 'AND ((d2.id_group_shop IS NULL OR d2.id_group_shop = '.$shopGroupID.') AND d2.id_shop IS NULL)';
|
||||
else
|
||||
$where = 'AND (d2.id_shop = '.$shopID.' OR (d2.id_group_shop = '.$shopGroupID.' AND d2.id_shop IS NULL) OR (d2.id_group_shop IS NULL AND d2.id_shop IS NULL))';
|
||||
|
||||
|
||||
$sql = 'AND '.$alias.'.id_delivery = (
|
||||
SELECT d2.id_delivery
|
||||
FROM '._DB_PREFIX_.'delivery d2
|
||||
|
||||
+60
-58
@@ -28,11 +28,11 @@
|
||||
class CartCore extends ObjectModel
|
||||
{
|
||||
public $id;
|
||||
|
||||
|
||||
public $id_group_shop;
|
||||
|
||||
|
||||
public $id_shop;
|
||||
|
||||
|
||||
/** @var integer Customer delivery address ID */
|
||||
public $id_address_delivery;
|
||||
|
||||
@@ -75,7 +75,7 @@ class CartCore extends ObjectModel
|
||||
public $checkedTos = false;
|
||||
public $pictures;
|
||||
public $textFields;
|
||||
|
||||
|
||||
protected static $_nbProducts = array();
|
||||
protected static $_isVirtualCart = array();
|
||||
|
||||
@@ -129,7 +129,7 @@ class CartCore extends ObjectModel
|
||||
|
||||
$fields['id_group_shop'] = (int)$this->id_group_shop;
|
||||
$fields['id_shop'] = (int)$this->id_shop;
|
||||
|
||||
|
||||
$fields['id_address_delivery'] = (int)($this->id_address_delivery);
|
||||
$fields['id_address_invoice'] = (int)($this->id_address_invoice);
|
||||
$fields['id_currency'] = (int)($this->id_currency);
|
||||
@@ -187,35 +187,35 @@ class CartCore extends ObjectModel
|
||||
{
|
||||
if ($this->OrderExists()) //NOT delete a cart which is associated with an order
|
||||
return false;
|
||||
|
||||
|
||||
$uploadedFiles = Db::getInstance()->ExecuteS('
|
||||
SELECT cd.`value`
|
||||
SELECT cd.`value`
|
||||
FROM `'._DB_PREFIX_.'customized_data` cd
|
||||
INNER JOIN `'._DB_PREFIX_.'customization` c ON (cd.`id_customization`= c.`id_customization`)
|
||||
WHERE cd.`type`= 0 AND c.`id_cart`='.(int)$this->id);
|
||||
|
||||
|
||||
foreach ($uploadedFiles as $mustUnlink)
|
||||
{
|
||||
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value'].'_small');
|
||||
unlink(_PS_UPLOAD_DIR_.$mustUnlink['value']);
|
||||
}
|
||||
|
||||
|
||||
Db::getInstance()->Execute('
|
||||
DELETE FROM `'._DB_PREFIX_.'customized_data`
|
||||
DELETE FROM `'._DB_PREFIX_.'customized_data`
|
||||
WHERE `id_customization` IN (
|
||||
SELECT `id_customization`
|
||||
FROM `'._DB_PREFIX_.'customization`
|
||||
SELECT `id_customization`
|
||||
FROM `'._DB_PREFIX_.'customization`
|
||||
WHERE `id_cart`='.(int)$this->id.'
|
||||
)');
|
||||
|
||||
|
||||
Db::getInstance()->Execute('
|
||||
DELETE FROM `'._DB_PREFIX_.'customization`
|
||||
DELETE FROM `'._DB_PREFIX_.'customization`
|
||||
WHERE `id_cart` = '.(int)$this->id);
|
||||
|
||||
if (!Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_cart` = '.(int)($this->id))
|
||||
if (!Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_discount` WHERE `id_cart` = '.(int)($this->id))
|
||||
OR !Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'cart_product` WHERE `id_cart` = '.(int)($this->id)))
|
||||
return false;
|
||||
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ class CartCore extends ObjectModel
|
||||
if (is_int($id_product))
|
||||
{
|
||||
foreach ($this->_products as $product)
|
||||
if ($product['id_product'] == $id_product)
|
||||
if ($product['id_product'] == $id_product)
|
||||
return array($product);
|
||||
return array();
|
||||
}
|
||||
@@ -352,7 +352,7 @@ class CartCore extends ObjectModel
|
||||
}
|
||||
if (!$id_country)
|
||||
$id_country = Context::getContext()->country->id;
|
||||
|
||||
|
||||
$sql = 'SELECT cp.`id_product_attribute`, cp.`id_product`, cu.`id_customization`, cp.`quantity` AS cart_quantity, cp.id_shop, 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.`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,
|
||||
@@ -369,7 +369,8 @@ class CartCore extends ObjectModel
|
||||
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)$id_country.'
|
||||
AND tr.`id_state` = 0)
|
||||
AND tr.`id_state` = 0
|
||||
AND tr.`zipcode_from` = 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 (p.`id_product` = cu.`id_product`)
|
||||
@@ -381,6 +382,7 @@ class CartCore extends ObjectModel
|
||||
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
|
||||
|
||||
@@ -414,7 +416,7 @@ class CartCore extends ObjectModel
|
||||
$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));
|
||||
$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']);
|
||||
}
|
||||
@@ -428,7 +430,7 @@ class CartCore extends ObjectModel
|
||||
$row['total_wt'] = $row['price_wt'] * (int)($row['cart_quantity']);
|
||||
$row['total'] = Tools::ps_round($row['price'] * (int)($row['cart_quantity']), 2);
|
||||
}
|
||||
|
||||
|
||||
$row2 = Db::getInstance()->getRow('
|
||||
SELECT i.`id_image`, il.`legend`
|
||||
FROM `'._DB_PREFIX_.'image` i
|
||||
@@ -447,7 +449,7 @@ class CartCore extends ObjectModel
|
||||
if (!$row2)
|
||||
$row2 = array('id_image' => false, 'legend' => false);
|
||||
$row = array_merge($row, $row2);
|
||||
|
||||
|
||||
$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']);
|
||||
@@ -513,8 +515,8 @@ class CartCore extends ObjectModel
|
||||
if (isset(self::$_nbProducts[$id]) && self::$_nbProducts[$id] !== NULL)
|
||||
return self::$_nbProducts[$id];
|
||||
self::$_nbProducts[$id] = (int)(Db::getInstance()->getValue('
|
||||
SELECT SUM(`quantity`)
|
||||
FROM `'._DB_PREFIX_.'cart_product`
|
||||
SELECT SUM(`quantity`)
|
||||
FROM `'._DB_PREFIX_.'cart_product`
|
||||
WHERE `id_cart` = '.(int)($id)));
|
||||
return self::$_nbProducts[$id];
|
||||
}
|
||||
@@ -579,7 +581,7 @@ class CartCore extends ObjectModel
|
||||
$result = $this->containsProduct($id_product, $id_product_attribute, (int)$id_customization);
|
||||
|
||||
/* Update quantity if product already exist */
|
||||
|
||||
|
||||
if ($result)
|
||||
{
|
||||
if ($operator == 'up')
|
||||
@@ -652,7 +654,7 @@ class CartCore extends ObjectModel
|
||||
// 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
|
||||
@@ -673,15 +675,15 @@ class CartCore extends ObjectModel
|
||||
if ($field['quantity'] == 0)
|
||||
{
|
||||
Db::getInstance()->Execute('
|
||||
UPDATE `'._DB_PREFIX_.'customization`
|
||||
SET `quantity` = '.(int)($quantity).',
|
||||
UPDATE `'._DB_PREFIX_.'customization`
|
||||
SET `quantity` = '.(int)($quantity).',
|
||||
`id_product_attribute` = '.(int)$id_product_attribute.',
|
||||
`in_cart` = 1
|
||||
WHERE `id_customization` = '.(int)$field['id_customization']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Deletion */
|
||||
if (!empty($id_customization) AND (int)($quantity) < 1)
|
||||
return $this->_deleteCustomization((int)$id_customization, (int)$id_product, (int)$id_product_attribute);
|
||||
@@ -694,7 +696,7 @@ class CartCore extends ObjectModel
|
||||
if ($operator == 'down' AND (int)($result['quantity']) - (int)($quantity) < 1)
|
||||
return Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'customization` WHERE `id_customization` = '.(int)$id_customization);
|
||||
return Db::getInstance()->Execute('
|
||||
UPDATE `'._DB_PREFIX_.'customization`
|
||||
UPDATE `'._DB_PREFIX_.'customization`
|
||||
SET `quantity` = `quantity` '.($operator == 'up' ? '+ ' : '- ').(int)($quantity).'
|
||||
WHERE `id_customization` = '.(int)($id_customization));
|
||||
}
|
||||
@@ -726,15 +728,15 @@ class CartCore extends ObjectModel
|
||||
AND cu.id_product = '.(int)$id_product.'
|
||||
AND in_cart = 0');
|
||||
|
||||
if ($exising_customization)
|
||||
if ($exising_customization)
|
||||
{
|
||||
// If the customization field is alreay filled, delete it
|
||||
// If the customization field is alreay filled, delete it
|
||||
foreach($exising_customization as $customization)
|
||||
{
|
||||
if ($customization['type'] == $type && $customization['index'] == $index)
|
||||
{
|
||||
Db::getInstance()->Execute('
|
||||
DELETE FROM `'._DB_PREFIX_.'customized_data`
|
||||
DELETE FROM `'._DB_PREFIX_.'customized_data`
|
||||
WHERE id_customization = '.(int)$customization['id_customization'].'
|
||||
AND type = '.(int)$customization['type'].'
|
||||
AND `index` = '.(int)$customization['index']);
|
||||
@@ -750,7 +752,7 @@ class CartCore extends ObjectModel
|
||||
}else
|
||||
{
|
||||
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'customization` (`id_cart`, `id_product`, `id_product_attribute`, `quantity`) VALUES ('.(int)($this->id).', '.(int)($id_product).', '.(int)($id_product_attribute).', '.(int)($quantity).')');
|
||||
$id_customization = Db::getInstance()->Insert_ID();
|
||||
$id_customization = Db::getInstance()->Insert_ID();
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO `'._DB_PREFIX_.'customized_data` (`id_customization`, `type`, `index`, `value`) VALUES ('.(int)$id_customization.', '.(int)$type.', '.(int)$index.', \''.pSql($field).'\')';
|
||||
@@ -922,7 +924,7 @@ class CartCore extends ObjectModel
|
||||
|
||||
// no shipping cost if is a cart with only virtuals products
|
||||
$virtual = $this->isVirtualCart();
|
||||
if ($virtual AND $type == Cart::ONLY_SHIPPING)
|
||||
if ($virtual AND $type == Cart::ONLY_SHIPPING)
|
||||
return 0;
|
||||
if ($virtual AND $type == Cart::BOTH)
|
||||
$type = Cart::BOTH_WITHOUT_SHIPPING;
|
||||
@@ -1042,7 +1044,7 @@ class CartCore extends ObjectModel
|
||||
|
||||
if (!$default_country)
|
||||
$default_country = Context::getContext()->country;
|
||||
|
||||
|
||||
// Checking discounts in cart
|
||||
$products = $this->getProducts();
|
||||
$discounts = $this->getDiscounts(true);
|
||||
@@ -1087,7 +1089,7 @@ class CartCore extends ObjectModel
|
||||
if (!Validate::isLoadedObject($default_country))
|
||||
$default_country = new Country(Configuration::get('PS_COUNTRY_DEFAULT'), Configuration::get('PS_LANG_DEFAULT'));
|
||||
$id_zone = (int)$default_country->id_zone;
|
||||
}
|
||||
}
|
||||
|
||||
// If no carrier, select default one
|
||||
if (!$id_carrier)
|
||||
@@ -1173,14 +1175,14 @@ class CartCore extends ObjectModel
|
||||
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;
|
||||
|
||||
return 0;
|
||||
|
||||
// Select carrier tax
|
||||
if ($useTax AND !Tax::excludeTaxeOption())
|
||||
$carrierTax = Tax::getCarrierTaxRate((int)$carrier->id, (int)$this->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
|
||||
$carrierTax = $carrier->getTaxesRate(new Address((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'));
|
||||
// Free fees
|
||||
@@ -1238,7 +1240,7 @@ class CartCore extends ObjectModel
|
||||
{
|
||||
$moduleName = $carrier->external_module_name;
|
||||
$module = Module::getInstanceByName($moduleName);
|
||||
|
||||
|
||||
if (Validate::isLoadedObject($module))
|
||||
{
|
||||
if (array_key_exists('id_carrier', $module))
|
||||
@@ -1295,13 +1297,13 @@ class CartCore extends ObjectModel
|
||||
*
|
||||
* @return mixed Return a string if an error occurred and false otherwise
|
||||
*/
|
||||
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false,
|
||||
function checkDiscountValidity($discountObj, $discounts, $order_total, $products, $checkCartDiscount = false,
|
||||
Customer $customer = null, Shop $shop = null)
|
||||
{
|
||||
if (!$shop)
|
||||
$shop = Context::getContext()->shop;
|
||||
if (!$customer)
|
||||
$customer = Context::getContext()->customer;
|
||||
$customer = Context::getContext()->customer;
|
||||
if (!$order_total)
|
||||
return Tools::displayError('Cannot add voucher if order is free.');
|
||||
if (!$discountObj->active)
|
||||
@@ -1331,12 +1333,12 @@ class CartCore extends ObjectModel
|
||||
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)))
|
||||
@@ -1391,7 +1393,7 @@ class CartCore extends ObjectModel
|
||||
// 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)
|
||||
@@ -1513,7 +1515,7 @@ class CartCore extends ObjectModel
|
||||
$textValue = str_replace(array("\n", "\r"), '', nl2br($textValue));
|
||||
$textValue = str_replace('\\', '\\\\', $textValue);
|
||||
$textValue = str_replace('\'', '\\\'', $textValue);
|
||||
return $this->_addCustomization($id_product, 0, $index, $type, $textValue, 0);
|
||||
return $this->_addCustomization($id_product, 0, $index, $type, $textValue, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1523,9 +1525,9 @@ class CartCore extends ObjectModel
|
||||
*/
|
||||
public function addPictureToProduct($id_product, $index, $type, $file)
|
||||
{
|
||||
return $this->_addCustomization($id_product, 0, $index, $type, $file, 0);
|
||||
return $this->_addCustomization($id_product, 0, $index, $type, $file, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove a customer's customization
|
||||
*
|
||||
@@ -1534,7 +1536,7 @@ class CartCore extends ObjectModel
|
||||
public function deleteCustomizationToProduct($id_product, $index)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
|
||||
$custData = Db::getInstance()->getRow('
|
||||
SELECT cu.`id_customization`, cd.`index`, cd.`value`, cd.`type` FROM `'._DB_PREFIX_.'customization` cu
|
||||
LEFT JOIN `'._DB_PREFIX_.'customized_data` cd
|
||||
@@ -1544,7 +1546,7 @@ class CartCore extends ObjectModel
|
||||
AND `index` = '.(int)$index.'
|
||||
AND `in_cart` = 0'
|
||||
);
|
||||
|
||||
|
||||
// Delete customization picture if necessary
|
||||
if ($custData['type'] == 0)
|
||||
$result &= (@unlink(_PS_UPLOAD_DIR_.$custData['value']) && @unlink(_PS_UPLOAD_DIR_.$custData['value'].'_small'));
|
||||
@@ -1556,7 +1558,7 @@ class CartCore extends ObjectModel
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return custom pictures in this cart for a specified product
|
||||
*
|
||||
@@ -1603,7 +1605,7 @@ class CartCore extends ObjectModel
|
||||
$cart->id = NULL;
|
||||
$cart->id_shop = $this->id_shop;
|
||||
$cart->id_group_shop = $this->id_group_shop;
|
||||
|
||||
|
||||
$cart->add();
|
||||
|
||||
if (!Validate::isLoadedObject($cart))
|
||||
@@ -1620,7 +1622,7 @@ class CartCore extends ObjectModel
|
||||
FROM '._DB_PREFIX_.'customization c
|
||||
LEFT JOIN '._DB_PREFIX_.'customized_data cd ON cd.id_customization = c.id_customization
|
||||
WHERE c.id_cart = '.(int)$this->id);
|
||||
|
||||
|
||||
// Group line by id_customization
|
||||
$customsById = array();
|
||||
foreach ($customs AS $custom)
|
||||
@@ -1629,7 +1631,7 @@ class CartCore extends ObjectModel
|
||||
$customsById[$custom['id_customization']] = array();
|
||||
$customsById[$custom['id_customization']][] = $custom;
|
||||
}
|
||||
|
||||
|
||||
// Insert new customizations
|
||||
$custom_ids = array();
|
||||
foreach($customsById as $customizationId => $val)
|
||||
@@ -1639,7 +1641,7 @@ class CartCore extends ObjectModel
|
||||
VALUES(\'\', '.(int)$cart->id.', '.(int)$custom['id_product_attribute'].', '.(int)$custom['id_product'].', '.(int)$custom['quantity'].')');
|
||||
$custom_ids[$custom['id_customization']] = Db::getInstance(_PS_USE_SQL_SLAVE_)->Insert_ID();
|
||||
}
|
||||
|
||||
|
||||
// Insert customized_data
|
||||
if (sizeof($customs))
|
||||
{
|
||||
@@ -1655,7 +1657,7 @@ class CartCore extends ObjectModel
|
||||
}
|
||||
Db::getInstance(_PS_USE_SQL_SLAVE_)->Execute($sql_custom_data);
|
||||
}
|
||||
|
||||
|
||||
return array('cart' => $cart, 'success' => $success);
|
||||
}
|
||||
|
||||
|
||||
@@ -548,7 +548,8 @@ class CategoryCore extends ObjectModel
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
|
||||
AND tr.`id_country` = '.(int)$context->country->id.'
|
||||
AND tr.`id_state` = 0)
|
||||
AND tr.`id_state` = 0
|
||||
AND tr.`zipcode_from` = 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)$id_lang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
|
||||
|
||||
+55
-135
@@ -25,6 +25,10 @@
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
class CountyCore extends ObjectModel
|
||||
{
|
||||
public $id;
|
||||
@@ -63,181 +67,97 @@ class CountyCore extends ObjectModel
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$id = $this->id;
|
||||
parent::delete();
|
||||
|
||||
// remove associated zip codes & tax rule
|
||||
return (County::deleteZipCodeByIdCounty($id) AND TaxRule::deleteTaxRuleByIdCounty($id));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getCounties($id_state)
|
||||
{
|
||||
if (!isset(self::$_cache_get_counties[$id_state]))
|
||||
{
|
||||
self::$_cache_get_counties[$id_state] = Db::getInstance()->ExecuteS('
|
||||
SELECT * FROM `'._DB_PREFIX_.'county`
|
||||
WHERE `id_state` = '.(int)$id_state
|
||||
);
|
||||
}
|
||||
|
||||
return self::$_cache_get_counties[$id_state];
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
// return the list of associated zipcode
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function getZipCodes()
|
||||
{
|
||||
return Db::getInstance()->ExecuteS('
|
||||
SELECT * FROM `'._DB_PREFIX_.'county_zip_code`
|
||||
WHERE `id_county` = '.(int)$this->id.'
|
||||
ORDER BY `from_zip_code` ASC'
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function addZipCodes($zip_codes)
|
||||
{
|
||||
list($from, $to) = $this->breakDownZipCode($zip_codes);
|
||||
|
||||
if ($from == 0)
|
||||
return false;
|
||||
|
||||
return Db::getInstance()->Execute(
|
||||
'INSERT INTO `'._DB_PREFIX_.'county_zip_code` (`id_county`, `from_zip_code`, `to_zip_code`)
|
||||
VALUES ('.(int)$this->id.','.(int)$from.','.(int)$to.')'
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function removeZipCodes($zip_codes)
|
||||
{
|
||||
list($from, $to) = $this->breakDownZipCode($zip_codes);
|
||||
|
||||
if ($from == 0)
|
||||
return false;
|
||||
|
||||
return Db::getInstance()->Execute('
|
||||
DELETE FROM `'._DB_PREFIX_.'county_zip_code`
|
||||
WHERE `id_county` = '.(int)$this->id.'
|
||||
AND `from_zip_code` = '.(int)$from.'
|
||||
AND `to_zip_code` = '.(int)$to
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function breakDownZipCode($zip_codes)
|
||||
{
|
||||
$zip_codes = preg_split('/-/', $zip_codes);
|
||||
|
||||
if (sizeof($zip_codes) == 2)
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = $zip_codes[1];
|
||||
if ($zip_codes[0] > $zip_codes[1])
|
||||
{
|
||||
$from = $zip_codes[1];
|
||||
$to = $zip_codes[0];
|
||||
}
|
||||
else if ($zip_codes[0] == $zip_codes[1])
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = 0;
|
||||
}
|
||||
}
|
||||
else if (sizeof($zip_codes) == 1)
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = 0;
|
||||
}
|
||||
|
||||
if (!Validate::isInt($from) OR !Validate::isInt($to))
|
||||
{
|
||||
$from = 0;
|
||||
$to = 0;
|
||||
}
|
||||
|
||||
return array($from, $to);
|
||||
Tools::displayAsDeprecated();
|
||||
return array(0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getIdCountyByZipCode($id_state, $zip_code)
|
||||
{
|
||||
if (!isset(self::$_cache_county_zipcode[$id_state.'-'.$zip_code]))
|
||||
{
|
||||
self::$_cache_county_zipcode[$id_state.'-'.$zip_code] = Db::getInstance()->getValue('
|
||||
SELECT DISTINCT c.`id_county` FROM `'._DB_PREFIX_.'county` c
|
||||
LEFT JOIN `'._DB_PREFIX_.'county_zip_code` cz ON (c.`id_county` = cz.`id_county`)
|
||||
WHERE `id_state` = '.(int)$id_state.'
|
||||
AND cz.`from_zip_code` >= '.(int)$zip_code.'
|
||||
AND cz.`to_zip_code` <= '.(int)$zip_code
|
||||
);
|
||||
}
|
||||
|
||||
return self::$_cache_county_zipcode[$id_state.'-'.$zip_code];
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function isZipCodeRangePresent($zip_codes)
|
||||
{
|
||||
$res = false;
|
||||
list($from, $to) = $this->breakDownZipCode($zip_codes);
|
||||
|
||||
if ($from == 0)
|
||||
return false;
|
||||
|
||||
if ($to != 0)
|
||||
{
|
||||
$res = Db::getInstance()->getValue('
|
||||
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
|
||||
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
|
||||
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
|
||||
WHERE `from_zip_code` >= '.(int)$from.'
|
||||
AND `to_zip_code` <= '.(int)$to.'
|
||||
AND s.`id_country` = (SELECT `id_country`
|
||||
FROM `'._DB_PREFIX_.'state` s
|
||||
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
|
||||
WHERE `id_county` = '.(int)$this->id.'
|
||||
)'
|
||||
);
|
||||
}
|
||||
|
||||
return ($res OR County::isZipCodePresent($from) OR County::isZipCodePresent($to));
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public function isZipCodePresent($zip_code)
|
||||
{
|
||||
|
||||
if ($zip_code == 0)
|
||||
return false;
|
||||
|
||||
return (bool) Db::getInstance()->getValue('
|
||||
SELECT COUNT(*) FROM `'._DB_PREFIX_.'county_zip_code` cz
|
||||
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_county` = cz.`id_county`)
|
||||
LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = c.`id_state`)
|
||||
WHERE
|
||||
(`from_zip_code` <= '.(int)$zip_code.' AND `to_zip_code` >= '.(int)$zip_code.')
|
||||
OR
|
||||
(`from_zip_code` = '.(int)$zip_code.')
|
||||
AND s.`id_country` = (SELECT `id_country`
|
||||
FROM `'._DB_PREFIX_.'state` s
|
||||
LEFT JOIN `'._DB_PREFIX_.'county` c ON (c.`id_state` = s.`id_state`)
|
||||
WHERE `id_county` = '.(int)$this->id.'
|
||||
)'
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function deleteZipCodeByIdCounty($id_county)
|
||||
{
|
||||
return Db::getInstance()->Execute(
|
||||
'DELETE FROM `'._DB_PREFIX_.'county_zip_code`
|
||||
WHERE `id_county` = '.(int)$id_county
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getIdCountyByNameAndIdState($name, $id_state)
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT `id_county` FROM `'._DB_PREFIX_.'county`
|
||||
WHERE `name` = \''.pSQL($name).'\'
|
||||
AND `id_state` = '.(int)$id_state
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+86
-19
@@ -34,7 +34,7 @@ class HelperCore
|
||||
public static $translationsKeysForAdminCategorieTree = array(
|
||||
'Home', 'selected', 'selecteds', 'Collapse All', 'Expand All', 'Check All', 'Uncheck All'
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $trads values of translations keys
|
||||
@@ -42,22 +42,22 @@ class HelperCore
|
||||
* @param type $selected_cat array of selected categories
|
||||
* Format
|
||||
* Array
|
||||
(
|
||||
[0] => 1
|
||||
[1] => 2
|
||||
)
|
||||
* OR
|
||||
Array
|
||||
(
|
||||
[1] => Array
|
||||
(
|
||||
[id_category] => 1
|
||||
[name] => Home page
|
||||
[link_rewrite] => home
|
||||
)
|
||||
)
|
||||
* (
|
||||
* [0] => 1
|
||||
* [1] => 2
|
||||
* )
|
||||
* OR
|
||||
* Array
|
||||
* (
|
||||
* [1] => Array
|
||||
* (
|
||||
* [id_category] => 1
|
||||
* [name] => Home page
|
||||
* [link_rewrite] => home
|
||||
* )
|
||||
* )
|
||||
* @param type $input_name name of input
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public static function renderAdminCategorieTree($trads, $selected_cat = array(), $input_name = 'categoryBox', $use_radio = false)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ class HelperCore
|
||||
</script>
|
||||
<link type="text/css" rel="stylesheet" href="../css/jquery.treeview.css" />
|
||||
';
|
||||
|
||||
|
||||
$html .= '
|
||||
<div style="background-color:#F4E6C9; width:99%;padding:5px 0 5px 5px;">
|
||||
<a href="#" id="collapse_all" >'.$trads['Collapse All'].'</a>
|
||||
@@ -97,7 +97,7 @@ class HelperCore
|
||||
' : '').'
|
||||
</div>
|
||||
';
|
||||
|
||||
|
||||
$home_is_selected = false;
|
||||
foreach($selected_cat AS $cat)
|
||||
{
|
||||
@@ -121,10 +121,77 @@ class HelperCore
|
||||
<li id="1" class="hasChildren">
|
||||
<span class="folder"> <input type="'.(!$use_radio ? 'checkbox' : 'radio').'" name="'.$input_name.'" value="1" '.($home_is_selected ? 'checked' : '').' onclick="clickOnCategoryBox($(this));" /> '.$trads['Home'].'</span>
|
||||
<ul>
|
||||
<li><span class="placeholder"> </span></li>
|
||||
<li><span class="placeholder"> </span></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a select input field
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $html_options any key => value options
|
||||
* @param array $select_options
|
||||
* - key: the array value that will be used as a key in my select (optional)
|
||||
* - value: the array value that will be used as a label in my select (optional)
|
||||
* - empty: the label displayed as an empty value (optional)
|
||||
* - selected: the key corresponding to the selected value (optional)
|
||||
*
|
||||
* @return string html content
|
||||
*/
|
||||
public static function selectInput(array $values, array $html_options = array(), array $select_options = array())
|
||||
{
|
||||
// options management
|
||||
$options = self::buildHtmlOptions($html_options);
|
||||
$select_html = '<select '.$options.'>';
|
||||
|
||||
if (isset($select_options['key']))
|
||||
$use_key = $select_options['key'];
|
||||
|
||||
if (isset($select_options['value']))
|
||||
$use_value = $select_options['value'];
|
||||
|
||||
if (isset($select_options['empty']))
|
||||
$select_html .= '<option value="">'.$select_options['empty'].'</option>';
|
||||
|
||||
// render options fields
|
||||
foreach ($values as $key => $value)
|
||||
{
|
||||
$current_key = isset($use_key) ? $value[$use_key] : $key;
|
||||
$current_value = isset($use_value) ? $value[$use_value] : $value;
|
||||
|
||||
if (isset($select_options['selected']) && $select_options['selected'] == $current_key)
|
||||
$selected = 'selected="selected"';
|
||||
else
|
||||
$selected = '';
|
||||
|
||||
$select_html .= '<option value="'.Tools::htmlentitiesUTF8($current_key).'" '.$selected.'>'.Tools::htmlentitiesUTF8($current_value).'</option>';
|
||||
}
|
||||
|
||||
$select_html .= '</select>';
|
||||
|
||||
return $select_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create html a string containing html options
|
||||
* eg: buildHtmlOptions(array('name' => 'myInputName', 'id' => 'myInputId'));
|
||||
* return => 'name="myInputName" id="myInputId"'
|
||||
*
|
||||
* @param array $html_options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function buildHtmlOptions(array $html_options)
|
||||
{
|
||||
$html = '';
|
||||
|
||||
foreach ($html_options as $html_option => $value)
|
||||
$html .= Tools::htmlentitiesUTF8($html_option).'="'.Tools::htmlentitiesUTF8($value).'" ';
|
||||
|
||||
return rtrim($html, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,60 +117,8 @@ class LocalizationPackCore
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add counties
|
||||
foreach ($data->county AS $xml_county)
|
||||
{
|
||||
$county_attributes = $xml_county->attributes();
|
||||
if (!$id_county = County::getIdCountyByNameAndIdState($county_attributes['name'], $state->id))
|
||||
{
|
||||
$county = new County();
|
||||
$county->name = $county_attributes['name'];
|
||||
$county->id_state = (int)$state->id;
|
||||
$county->active = 1;
|
||||
|
||||
if (!$county->validateFields())
|
||||
{
|
||||
$this->_errors[] = Tools::displayError('Invalid County properties');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$county->save())
|
||||
{
|
||||
$this->_errors[] = Tools::displayError('An error has occurred while adding the county');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$county = new County((int)$id_county);
|
||||
if (!Validate::isLoadedObject($county))
|
||||
{
|
||||
$this->_errors[] = Tools::displayError('An error occurred while fetching the county.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// add zip codes
|
||||
foreach ($xml_county->zipcode AS $xml_zipcode)
|
||||
{
|
||||
$zipcode_attributes = $xml_zipcode->attributes();
|
||||
|
||||
$zipcodes = $zipcode_attributes['from'];
|
||||
if (isset($zipcode_attributes['to']))
|
||||
$zipcodes .= '-'.$zipcode_attributes['to'];
|
||||
|
||||
if ($county->isZipCodeRangePresent($zipcodes))
|
||||
continue;
|
||||
|
||||
if (!$county->addZipCodes($zipcodes))
|
||||
{
|
||||
$this->_errors[] = Tools::displayError('An error has occurred while adding zipcodes');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,8 +286,9 @@ class ManufacturerCore extends ObjectModel
|
||||
LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = p.`id_product` AND i.`cover` = 1)
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)$id_lang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
|
||||
AND tr.`id_country` = '.(int)$context->country->id.'
|
||||
AND tr.`id_state` = 0)
|
||||
AND tr.`id_country` = '.(int)$context->country->id.'
|
||||
AND tr.`id_state` = 0
|
||||
AND tr.`zipcode_from` = 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)$id_lang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON m.`id_manufacturer` = p.`id_manufacturer`
|
||||
|
||||
+16
-14
@@ -99,9 +99,12 @@ abstract class PaymentModuleCore extends Module
|
||||
if ($secure_key !== false AND $secure_key != $cart->secure_key)
|
||||
die(Tools::displayError());
|
||||
|
||||
|
||||
$carrier = new Carrier((int)$cart->id_carrier, (int)$cart->id_lang);
|
||||
|
||||
// Copying data from cart
|
||||
$order = new Order();
|
||||
$order->id_carrier = (int)($cart->id_carrier);
|
||||
$order->id_carrier = $carrier->id;
|
||||
$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);
|
||||
@@ -109,10 +112,10 @@ abstract class PaymentModuleCore extends Module
|
||||
$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);
|
||||
|
||||
|
||||
$order->id_shop = (int)($shop->getID() ? $shop->getID() : $cart->id_shop);
|
||||
$order->id_group_shop = (int)($shop->getID() ? $shop->getGroupID() : $cart->id_group_shop);
|
||||
|
||||
|
||||
$customer = new Customer((int)($order->id_customer));
|
||||
$order->secure_key = ($secure_key ? pSQL($secure_key) : pSQL($customer->secure_key));
|
||||
$order->payment = $paymentMethod;
|
||||
@@ -128,8 +131,8 @@ abstract class PaymentModuleCore extends Module
|
||||
$order->total_products = (float)($cart->getOrderTotal(false, Cart::ONLY_PRODUCTS));
|
||||
$order->total_products_wt = (float)($cart->getOrderTotal(true, Cart::ONLY_PRODUCTS));
|
||||
$order->total_discounts = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS)));
|
||||
$order->total_shipping = (float)($cart->getOrderShippingCost());
|
||||
$order->carrier_tax_rate = (float)Tax::getCarrierTaxRate($cart->id_carrier, (int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
|
||||
$order->total_shipping = (float)$cart->getOrderShippingCost();
|
||||
$order->carrier_tax_rate = (float)$carrier->getTaxesRate(new Address((int)$cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
|
||||
$order->total_wrapping = (float)(abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING)));
|
||||
$order->total_paid = (float)(Tools::ps_round((float)($cart->getOrderTotal(true, Cart::BOTH)), 2));
|
||||
$order->invoice_date = '0000-00-00 00:00:00';
|
||||
@@ -256,15 +259,15 @@ abstract class PaymentModuleCore extends Module
|
||||
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 .= sizeof($customization['datas'][_CUSTOMIZE_FILE_]) .' '. Tools::displayError('image(s)').'<br />';
|
||||
|
||||
$customizationText .= '---<br />';
|
||||
|
||||
$customizationText .= '---<br />';
|
||||
}
|
||||
|
||||
|
||||
$customizationText = rtrim($customizationText, '---<br />');
|
||||
|
||||
|
||||
$customizationQuantity = (int)($product['customizationQuantityTotal']);
|
||||
$productsList .=
|
||||
'<tr style="background-color: '.($key % 2 ? '#DDE2E6' : '#EBECEE').';">
|
||||
@@ -377,7 +380,6 @@ abstract class PaymentModuleCore extends Module
|
||||
{
|
||||
$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;
|
||||
|
||||
@@ -387,11 +389,11 @@ abstract class PaymentModuleCore extends Module
|
||||
'{email}' => $customer->email,
|
||||
'{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"),
|
||||
'{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"),
|
||||
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />",
|
||||
'{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />",
|
||||
array(
|
||||
'firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>',
|
||||
'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 />",
|
||||
'{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>')),
|
||||
|
||||
+85
-54
@@ -186,7 +186,7 @@ class ProductCore extends ObjectModel
|
||||
public $tags;
|
||||
|
||||
public $isFullyLoaded = false;
|
||||
|
||||
|
||||
protected $langMultiShop = true;
|
||||
|
||||
public $cache_is_pack;
|
||||
@@ -202,10 +202,10 @@ class ProductCore extends ObjectModel
|
||||
protected static $_cacheFeatures = array();
|
||||
protected static $_frontFeaturesCache = array();
|
||||
protected static $producPropertiesCache = array();
|
||||
|
||||
|
||||
/** @var array cache stock data in getStock() method */
|
||||
protected static $cacheStock = array();
|
||||
|
||||
|
||||
/** @var array tables */
|
||||
protected $tables = array ('product', 'product_lang');
|
||||
|
||||
@@ -303,7 +303,7 @@ class ProductCore extends ObjectModel
|
||||
parent::__construct($id_product, $id_lang, $id_shop);
|
||||
if (!$context)
|
||||
$context = Context::getContext();
|
||||
|
||||
|
||||
if ($full AND $this->id)
|
||||
{
|
||||
$this->isFullyLoaded = $full;
|
||||
@@ -311,10 +311,13 @@ class ProductCore extends ObjectModel
|
||||
$this->manufacturer_name = Manufacturer::getNameById((int)$this->id_manufacturer);
|
||||
$this->supplier_name = Supplier::getNameById((int)$this->id_supplier);
|
||||
self::$_tax_rules_group[$this->id] = $this->id_tax_rules_group;
|
||||
|
||||
$address = NULL;
|
||||
if (is_object($context->cart) AND $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')} != NULL)
|
||||
$this->tax_rate = Tax::getProductTaxRate($this->id, $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
|
||||
else
|
||||
$this->tax_rate = Tax::getProductTaxRate($this->id, NULL);
|
||||
$address = $context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
|
||||
|
||||
$this->tax_rate = $this->getTaxesRate(new Address($address));
|
||||
|
||||
$this->new = $this->isNew();
|
||||
$this->price = Product::getPriceStatic((int)($this->id), false, NULL, 6, NULL, false, true, 1, false, NULL, NULL, NULL, $this->specificPrice);
|
||||
$this->unit_price = ($this->unit_price_ratio != 0 ? $this->price / $this->unit_price_ratio : 0);
|
||||
@@ -375,7 +378,7 @@ class ProductCore extends ObjectModel
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
public function add($autodate = true, $nullValues = false)
|
||||
{
|
||||
if (!parent::add($autodate, $nullValues))
|
||||
@@ -405,18 +408,25 @@ class ProductCore extends ObjectModel
|
||||
));
|
||||
}
|
||||
|
||||
public static function initPricesComputation($customer = NULL)
|
||||
public static function initPricesComputation($id_customer = NULL)
|
||||
{
|
||||
if ($customer)
|
||||
if ($id_customer)
|
||||
{
|
||||
$customer = new Customer((int)($id_customer));
|
||||
if (!Validate::isLoadedObject($customer))
|
||||
die(Tools::displayError());
|
||||
self::$_taxCalculationMethod = Group::getPriceDisplayMethod((int)($customer->id_default_group));
|
||||
}
|
||||
else if (Validate::isLoadedObject(Context::getContext()->customer))
|
||||
self::$_taxCalculationMethod = Group::getPriceDisplayMethod(Context::getContext()->customer->id_default_group);
|
||||
else
|
||||
self::$_taxCalculationMethod = Group::getDefaultPriceDisplayMethod();
|
||||
}
|
||||
|
||||
public static function getTaxCalculationMethod($customer = NULL)
|
||||
public static function getTaxCalculationMethod($id_customer = NULL)
|
||||
{
|
||||
if ($customer)
|
||||
self::initPricesComputation((int)($customer));
|
||||
if ($id_customer)
|
||||
self::initPricesComputation((int)($id_customer));
|
||||
return (int)(self::$_taxCalculationMethod);
|
||||
}
|
||||
|
||||
@@ -556,7 +566,7 @@ class ProductCore extends ObjectModel
|
||||
{
|
||||
if (!GroupReduction::deleteProductReduction($this->id))
|
||||
return false;
|
||||
|
||||
|
||||
Hook::deleteProduct($this);
|
||||
if (!parent::delete() OR
|
||||
!$this->deleteCategories(true) OR
|
||||
@@ -669,7 +679,7 @@ class ProductCore extends ObjectModel
|
||||
|
||||
if (!$this->setGroupReduction())
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -740,7 +750,7 @@ class ProductCore extends ObjectModel
|
||||
SELECT `id_image`
|
||||
FROM `'._DB_PREFIX_.'image`
|
||||
WHERE `id_product` = '.(int)($this->id));
|
||||
|
||||
|
||||
$status = true;
|
||||
if ($result)
|
||||
foreach($result as $row)
|
||||
@@ -1369,7 +1379,7 @@ class ProductCore extends ObjectModel
|
||||
AND tr.`id_state` = 0)
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
|
||||
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = p.`id_manufacturer`)
|
||||
WHERE p.`active` = 1
|
||||
WHERE p.`active` = 1
|
||||
AND DATEDIFF(p.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0
|
||||
AND p.`id_product` IN (
|
||||
SELECT cp.`id_product`
|
||||
@@ -1556,7 +1566,7 @@ class ProductCore extends ObjectModel
|
||||
$ret[] = $val['id_category'];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function getProductCategoriesFull($id_product = '', $id_lang)
|
||||
{
|
||||
$ret = array();
|
||||
@@ -1642,7 +1652,7 @@ class ProductCore extends ObjectModel
|
||||
{
|
||||
if (!$context)
|
||||
$context = Context::getContext();
|
||||
|
||||
|
||||
$cur_cart = $context->cart;
|
||||
|
||||
if (isset($divisor))
|
||||
@@ -1680,7 +1690,7 @@ class ProductCore extends ObjectModel
|
||||
// retrieve address informations
|
||||
$id_country = (int)$context->country->id;
|
||||
$id_state = 0;
|
||||
$id_county = 0;
|
||||
$zipcode = 0;
|
||||
|
||||
if (!$id_address)
|
||||
$id_address = $cur_cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
|
||||
@@ -1692,18 +1702,14 @@ class ProductCore extends ObjectModel
|
||||
{
|
||||
$id_country = (int)($address_infos['id_country']);
|
||||
$id_state = (int)($address_infos['id_state']);
|
||||
$postcode = (int)$address_infos['postcode'];
|
||||
|
||||
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
|
||||
$zipcode = $address_infos['postcode'];
|
||||
}
|
||||
}
|
||||
elseif (isset($context->customer->geoloc_id_country))
|
||||
{
|
||||
$id_country = (int)$context->customer->geoloc_id_country;
|
||||
$id_state = (int)$context->customer->id_state;
|
||||
$postcode = (int)$context->customer->postcode;
|
||||
|
||||
$id_county = (int)County::getIdCountyByZipCode($id_state, $postcode);
|
||||
$zipcode = (int)$context->customer->postcode;
|
||||
}
|
||||
|
||||
if (Tax::excludeTaxeOption())
|
||||
@@ -1712,7 +1718,7 @@ class ProductCore extends ObjectModel
|
||||
if ($usetax != false AND !empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
|
||||
$usetax = false;
|
||||
|
||||
return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc,
|
||||
return Product::priceCalculation($context->shop->getID(), $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $usetax, $decimals, $only_reduc,
|
||||
$usereduc, $with_ecotax, $specificPriceOutput, $use_groupReduction);
|
||||
}
|
||||
|
||||
@@ -1733,16 +1739,17 @@ class ProductCore extends ObjectModel
|
||||
* @param boolean $use_reduc Set if the returned amount will include reduction
|
||||
* @param boolean $with_ecotax insert ecotax in price output.
|
||||
* @param variable_reference $specific_price_output If a specific price applies regarding the previous parameters, this variable is filled with the corresponding SpecificPrice object
|
||||
*
|
||||
* @return float Product price
|
||||
**/
|
||||
public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $id_county, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction)
|
||||
public static function priceCalculation($id_shop, $id_product, $id_product_attribute, $id_country, $id_state, $zipcode, $id_currency, $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc, $with_ecotax, &$specific_price, $use_groupReduction)
|
||||
{
|
||||
// Caching
|
||||
if ($id_product_attribute === NULL)
|
||||
$product_attribute_label = 'NULL';
|
||||
else
|
||||
$product_attribute_label = ($id_product_attribute === false ? 'false' : $id_product_attribute);
|
||||
$cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$id_county.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax;
|
||||
$cacheId = $id_product.'-'.$id_shop.'-'.$id_currency.'-'.$id_country.'-'.$id_state.'-'.$zipcode.'-'.$id_group.'-'.$quantity.'-'.$product_attribute_label.'-'.($use_tax?'1':'0').'-'.$decimals.'-'.($only_reduc?'1':'0').'-'.($use_reduc?'1':'0').'-'.$with_ecotax;
|
||||
|
||||
// reference parameter is filled before any returns
|
||||
$specific_price = SpecificPrice::getSpecificPrice((int)($id_product), $id_shop, $id_currency, $id_country, $id_group, $quantity);
|
||||
@@ -1773,14 +1780,18 @@ class ProductCore extends ObjectModel
|
||||
if ($id_product_attribute !== false) // If you want the default combination, please use NULL value instead
|
||||
$price += $attribute_price;
|
||||
|
||||
// TaxRate calculation
|
||||
$tax_rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county);
|
||||
if ($tax_rate === false)
|
||||
$tax_rate = 0;
|
||||
// Tax
|
||||
$address = new Address();
|
||||
$address->id_country = $id_country;
|
||||
$address->id_state = $id_state;
|
||||
$address->postcode = $zipcode;
|
||||
|
||||
$tax_manager = TaxManagerFactory::getManager($address, Product::getIdTaxRulesGroupByIdProduct((int)$id_product));
|
||||
$product_tax_calculator = $tax_manager->getTaxCalculator();
|
||||
|
||||
// Add Tax
|
||||
if ($use_tax)
|
||||
$price = $price * (1 + ($tax_rate / 100));
|
||||
$price = $product_tax_calculator->addTaxes($price);
|
||||
$price = Tools::ps_round($price, $decimals);
|
||||
|
||||
// Reduction
|
||||
@@ -1793,7 +1804,7 @@ class ProductCore extends ObjectModel
|
||||
|
||||
if (!$specific_price['id_currency'])
|
||||
$reduction_amount = Tools::convertPrice($reduction_amount, $id_currency);
|
||||
$reduc = Tools::ps_round(!$use_tax ? $reduction_amount / (1 + $tax_rate / 100) : $reduction_amount, $decimals);
|
||||
$reduc = Tools::ps_round(!$use_tax ? $product_tax_calculator->removeTax($reduction_amount) : $reduction_amount, $decimals);
|
||||
}
|
||||
else
|
||||
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals);
|
||||
@@ -1825,8 +1836,13 @@ class ProductCore extends ObjectModel
|
||||
$ecotax = Tools::convertPrice($ecotax, $id_currency);
|
||||
if ($use_tax)
|
||||
{
|
||||
$taxRate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county);
|
||||
$price += $ecotax * (1 + ($taxRate / 100));
|
||||
// reinit the tax manager for ecotax handling
|
||||
$tax_manager = TaxManagerFactory::getManager(
|
||||
$address,
|
||||
(int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID')
|
||||
);
|
||||
$ecotax_tax_calculator = $tax_manager->getTaxCalculator();
|
||||
$price += $ecotax_tax_calculator->addTaxes($ecotax);
|
||||
}
|
||||
else
|
||||
$price += $ecotax;
|
||||
@@ -1915,7 +1931,7 @@ class ProductCore extends ObjectModel
|
||||
$ret .= Tools::displayPrice($params['p']['price'], $smarty->ps_currency);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display price with right format and currency
|
||||
*
|
||||
@@ -1975,10 +1991,10 @@ class ProductCore extends ObjectModel
|
||||
$product = new Product($id_product);
|
||||
return $product->getStock($id_product_attribute);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create JOIN query with 'stock' table
|
||||
*
|
||||
*
|
||||
* @param string $productAlias Alias of product table
|
||||
* @param string|int $productAttribute If string : alias of PA table ; if int : value of PA ; if null : nothing about PA
|
||||
* @param bool $innerJoin LEFT JOIN or INNER JOIN
|
||||
@@ -2002,10 +2018,10 @@ class ProductCore extends ObjectModel
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the stock quantity of current product
|
||||
*
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @param int $quantity
|
||||
* @param int $id_product_attribute
|
||||
@@ -2060,7 +2076,7 @@ class ProductCore extends ObjectModel
|
||||
'quantity' => $quantity,
|
||||
), 'INSERT');
|
||||
}
|
||||
|
||||
|
||||
// Change stock quantity on product
|
||||
if ($id_stock = Stock::getStockId($this->id, $id_product_attribute, $shop->getID(true)))
|
||||
{
|
||||
@@ -2082,7 +2098,7 @@ class ProductCore extends ObjectModel
|
||||
|
||||
/**
|
||||
* Get the stock quantity of current product
|
||||
*
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @param int $id_product_attribute
|
||||
* @param Context $context
|
||||
@@ -2103,6 +2119,7 @@ class ProductCore extends ObjectModel
|
||||
WHERE id_product = '.$this->id.'
|
||||
AND id_product_attribute = '.(int)$id_product_attribute
|
||||
.$context->shop->sqlRestriction(Shop::SHARE_STOCK);
|
||||
|
||||
self::$cacheStock[$this->id][$id_product_attribute] = (int)Db::getInstance()->getValue($sql);
|
||||
}
|
||||
return self::$cacheStock[$this->id][$id_product_attribute];
|
||||
@@ -2692,7 +2709,7 @@ class ProductCore extends ObjectModel
|
||||
{
|
||||
if (!$this->isFullyLoaded && is_null($this->tags))
|
||||
$this->tags = Tag::getProductTags($this->id);
|
||||
|
||||
|
||||
if (!($this->tags AND key_exists($id_lang, $this->tags)))
|
||||
return '';
|
||||
|
||||
@@ -2714,7 +2731,7 @@ class ProductCore extends ObjectModel
|
||||
if (!$row['id_product'])
|
||||
return false;
|
||||
$context = Context::getContext();
|
||||
|
||||
|
||||
// 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 ((!isset($row['id_product_attribute']) OR !$row['id_product_attribute'])
|
||||
@@ -3030,10 +3047,10 @@ class ProductCore extends ObjectModel
|
||||
$fields_present[] = array('id_customization_field' => $field['index'], 'type' => $field['type']);
|
||||
foreach ($requiredFields AS $required_field)
|
||||
if (!in_array($required_field, $fields_present))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static function idIsOnCategoryId($id_product, $categories)
|
||||
{
|
||||
$sql = 'SELECT id_product FROM `'._DB_PREFIX_.'category_product` WHERE `id_product`='.(int)($id_product).' AND `id_category` IN(';
|
||||
@@ -3063,7 +3080,7 @@ class ProductCore extends ObjectModel
|
||||
FROM `'._DB_PREFIX_.'category_product` cp
|
||||
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
|
||||
WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = 1');
|
||||
else
|
||||
else
|
||||
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
|
||||
SELECT cg.`id_group`
|
||||
FROM `'._DB_PREFIX_.'category_product` cp
|
||||
@@ -3075,7 +3092,7 @@ class ProductCore extends ObjectModel
|
||||
|
||||
/**
|
||||
* Add a stock movement for current product
|
||||
*
|
||||
*
|
||||
* @param int $quantity
|
||||
* @param int $id_reason
|
||||
* @param int $id_product_attribute
|
||||
@@ -3155,6 +3172,20 @@ class ProductCore extends ObjectModel
|
||||
return self::$_tax_rules_group[$id_product];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total taxes rate applied to the product
|
||||
*/
|
||||
public function getTaxesRate(Address $address = NULL)
|
||||
{
|
||||
if (!$address OR !$address->id_country)
|
||||
$address = Tax::initializeAddress();
|
||||
|
||||
$tax_manager = TaxManagerFactory::getManager($address, $this->id_tax_rules_group);
|
||||
$tax_calculator = $tax_manager->getTaxCalculator();
|
||||
|
||||
return $tax_calculator->getTaxesRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice getter : get product features association
|
||||
*
|
||||
@@ -3368,7 +3399,7 @@ class ProductCore extends ObjectModel
|
||||
SET `cover` = 1 WHERE `id_product` = '.(int)($this->id).' AND `id_image` = '.(int)$id_image);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Webservice getter : get image ids of current product for association
|
||||
*
|
||||
@@ -3390,8 +3421,8 @@ class ProductCore extends ObjectModel
|
||||
FROM `'._DB_PREFIX_.'product_tag`
|
||||
WHERE `id_product` = '.(int)($this->id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function getWsManufacturerName()
|
||||
{
|
||||
return Manufacturer::getNameById((int)$this->id_manufacturer);
|
||||
@@ -3404,7 +3435,7 @@ class ProductCore extends ObjectModel
|
||||
SET ecotax = 0
|
||||
');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Group reduction if needed
|
||||
*/
|
||||
|
||||
@@ -223,7 +223,8 @@ class SupplierCore extends ObjectModel
|
||||
LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.(int)($id_lang).')
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (p.`id_tax_rules_group` = tr.`id_tax_rules_group`
|
||||
AND tr.`id_country` = '.(int)Context::getContext()->country->id.'
|
||||
AND tr.`id_state` = 0)
|
||||
AND tr.`id_state` = 0
|
||||
AND tr.`zipcode_from` = 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)($id_lang).')
|
||||
LEFT JOIN `'._DB_PREFIX_.'supplier` s ON s.`id_supplier` = p.`id_supplier`
|
||||
|
||||
@@ -74,138 +74,6 @@ class TaxCore extends ObjectModel
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available taxes
|
||||
*
|
||||
* @return array Taxes
|
||||
*/
|
||||
public static function getTaxes($id_lang = false, $active = 1)
|
||||
{
|
||||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
|
||||
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
|
||||
FROM `'._DB_PREFIX_.'tax` t
|
||||
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
|
||||
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
|
||||
ORDER BY `name` ASC' : ''));
|
||||
}
|
||||
|
||||
public static function excludeTaxeOption()
|
||||
{
|
||||
return !Configuration::get('PS_TAX');
|
||||
}
|
||||
|
||||
public static function getTaxIdByName($tax_name, $active = 1)
|
||||
{
|
||||
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
|
||||
SELECT t.`id_tax`
|
||||
FROM `'._DB_PREFIX_.'tax` t
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
|
||||
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
|
||||
($active == 1 ? ' AND t.`active` = 1' : ''));
|
||||
|
||||
return $tax ? (int)($tax['id_tax']) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the product tax
|
||||
*
|
||||
* @param integer $id_product
|
||||
* @param integer $id_country
|
||||
* @return Tax
|
||||
*/
|
||||
public static function getProductTaxRate($id_product, $id_address = NULL)
|
||||
{
|
||||
$id_country = (int)Context::getContext()->country->id;
|
||||
$id_state = 0;
|
||||
$id_county = 0;
|
||||
$rate = 0;
|
||||
if (!empty($id_address))
|
||||
{
|
||||
$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']);
|
||||
}
|
||||
|
||||
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($rate = Tax::getProductTaxRateViaRules((int)$id_product, (int)$id_country, (int)$id_state, (int)$id_county))
|
||||
return $rate;
|
||||
|
||||
return $rate;
|
||||
}
|
||||
|
||||
public static function getProductEcotaxRate($id_address = NULL)
|
||||
{
|
||||
$id_country = (int)Context::getContext()->country->id;
|
||||
$id_state = 0;
|
||||
$id_county = 0;
|
||||
$rate = 0;
|
||||
if (!empty($id_address))
|
||||
{
|
||||
$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']);
|
||||
}
|
||||
|
||||
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($rate = TaxRulesGroup::getTaxesRate((int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'), (int)$id_country, (int)$id_state, (int)$id_county))
|
||||
return $rate;
|
||||
|
||||
return $rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the product tax rate using the tax rules system
|
||||
*
|
||||
* @param integer $id_product
|
||||
* @param integer $id_country
|
||||
* @return Tax
|
||||
*/
|
||||
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $id_county)
|
||||
{
|
||||
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
|
||||
{
|
||||
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, (int)$id_county);
|
||||
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county] = $tax_rate;
|
||||
}
|
||||
|
||||
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_county];
|
||||
}
|
||||
|
||||
|
||||
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
|
||||
{
|
||||
$id_country = (int)Context::getContext()->country->id;
|
||||
$id_state = 0;
|
||||
$id_county = 0;
|
||||
if (!empty($id_address))
|
||||
{
|
||||
$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']);
|
||||
}
|
||||
|
||||
if (!empty($address_infos['vat_number']) AND $address_infos['id_country'] != Configuration::get('VATNUMBER_COUNTRY') AND Configuration::get('VATNUMBER_MANAGEMENT'))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return TaxRulesGroup::getTaxesRate((int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier), (int)$id_country, (int)$id_state, (int)$id_county);
|
||||
}
|
||||
|
||||
public function toggleStatus()
|
||||
{
|
||||
if (parent::toggleStatus())
|
||||
@@ -229,5 +97,145 @@ class TaxCore extends ObjectModel
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available taxes
|
||||
*
|
||||
* @return array Taxes
|
||||
*/
|
||||
public static function getTaxes($id_lang = false, $active = 1)
|
||||
{
|
||||
return Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
|
||||
SELECT t.id_tax, t.rate'.((int)($id_lang) ? ', tl.name, tl.id_lang ' : '').'
|
||||
FROM `'._DB_PREFIX_.'tax` t
|
||||
'.((int)($id_lang) ? 'LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.(int)($id_lang).')'
|
||||
.($active == 1 ? 'WHERE t.`active` = 1' : '').'
|
||||
ORDER BY `name` ASC' : ''));
|
||||
}
|
||||
|
||||
public static function excludeTaxeOption()
|
||||
{
|
||||
return !Configuration::get('PS_TAX');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tax id associated to the specified name
|
||||
*
|
||||
* @param string $tax_name
|
||||
* @param boolean $active (true by default)
|
||||
*/
|
||||
public static function getTaxIdByName($tax_name, $active = 1)
|
||||
{
|
||||
$tax = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
|
||||
SELECT t.`id_tax`
|
||||
FROM `'._DB_PREFIX_.'tax` t
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (tl.id_tax = t.id_tax)
|
||||
WHERE tl.`name` = \''.pSQL($tax_name).'\' '.
|
||||
($active == 1 ? ' AND t.`active` = 1' : ''));
|
||||
|
||||
return $tax ? (int)($tax['id_tax']) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product tax
|
||||
*
|
||||
* @param integer $id_product
|
||||
* @param integer $id_country
|
||||
* @return Tax
|
||||
*
|
||||
* @deprecated use $product->getTaxesRate() instead
|
||||
*/
|
||||
public static function getProductTaxRate($id_product, $id_address = NULL)
|
||||
{
|
||||
$address = Tax::initializeAddress($id_address);
|
||||
$id_tax_rules = (int)Product::getIdTaxRulesGroupByIdProduct($id_product);
|
||||
|
||||
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
|
||||
$tax_calculator = $tax_manager->getTaxCalculator();
|
||||
|
||||
return $tax_calculator->getTaxesRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ecotax tax rate
|
||||
*
|
||||
* @param id_address
|
||||
* @return float $tax_rate
|
||||
*/
|
||||
public static function getProductEcotaxRate($id_address = NULL)
|
||||
{
|
||||
$address = Tax::initializeAddress($id_address);
|
||||
|
||||
$tax_manager = TaxManagerFactory::getManager($address, (int)Configuration::get('PS_ECOTAX_TAX_RULES_GROUP_ID'));
|
||||
$tax_calculator = $tax_manager->getTaxCalculator();
|
||||
|
||||
return $tax_calculator->getTaxesRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the carrier tax rate
|
||||
*
|
||||
* @param id_address
|
||||
* @return float $tax_rate
|
||||
*/
|
||||
public static function getCarrierTaxRate($id_carrier, $id_address = NULL)
|
||||
{
|
||||
$address = Tax::initializeAddress($id_address);
|
||||
$id_tax_rules = (int)Carrier::getIdTaxRulesGroupByIdCarrier((int)$id_carrier);
|
||||
|
||||
$tax_manager = TaxManagerFactory::getManager($address, $id_tax_rules);
|
||||
$tax_calculator = $tax_manager->getTaxCalculator();
|
||||
|
||||
return $tax_calculator->getTaxesRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiliaze an address corresponding to the id address if any or to the
|
||||
* default shop configuration
|
||||
*
|
||||
* @param int $id_address
|
||||
* @return Address address
|
||||
*/
|
||||
public static function initializeAddress($id_address = NULL)
|
||||
{
|
||||
// set the default address
|
||||
$address = new Address();
|
||||
$address->id_country = (int)Context::getContext()->country->id;
|
||||
$address->id_state = 0;
|
||||
$address->postcode = 0;
|
||||
|
||||
// if an id_address has been specified retrieve the address
|
||||
if ($id_address)
|
||||
{
|
||||
$address = new Address((int)$id_address);
|
||||
|
||||
if (!Validate::isLoadedObject())
|
||||
throw new Exception('Invalid address');
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the product tax rate using the tax rules system
|
||||
*
|
||||
* @param integer $id_product
|
||||
* @param integer $id_country
|
||||
* @return Tax
|
||||
*
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getProductTaxRateViaRules($id_product, $id_country, $id_state, $zipcode)
|
||||
{
|
||||
Tools::displayAsDeprecated();
|
||||
|
||||
if (!isset(self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$id_state.'-'.$zipcode]))
|
||||
{
|
||||
$tax_rate = TaxRulesGroup::getTaxesRate((int)Product::getIdTaxRulesGroupByIdProduct((int)$id_product), (int)$id_country, (int)$id_state, $zipcode);
|
||||
self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode] = $tax_rate;
|
||||
}
|
||||
|
||||
return self::$_product_tax_via_rules[$id_product.'-'.$id_country.'-'.$zipcode];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/*
|
||||
* 2007-2011 PrestaShop
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://opensource.org/licenses/osl-3.0.php
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author PrestaShop SA <contact@prestashop.com>
|
||||
* @copyright 2007-2011 PrestaShop SA
|
||||
* @version Release: $Revision$
|
||||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 1.5.0
|
||||
*
|
||||
* TaxCaculator is responsible of the tax computation
|
||||
*/
|
||||
class TaxCalculatorCore
|
||||
{
|
||||
/**
|
||||
* COMBINE_METHOD sum taxes
|
||||
* eg: 100€ * (10% + 15%)
|
||||
*/
|
||||
const COMBINE_METHOD = 1;
|
||||
|
||||
/**
|
||||
* ONE_AFTER_ANOTHER_METHOD apply taxes one after another
|
||||
* eg: (100€ * 10%) * 15%
|
||||
*/
|
||||
const ONE_AFTER_ANOTHER_METHOD = 2;
|
||||
|
||||
/**
|
||||
* @var array $taxes_rate
|
||||
*/
|
||||
public $taxes_rate;
|
||||
|
||||
/**
|
||||
* @var int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
|
||||
*/
|
||||
public $computation_method;
|
||||
|
||||
|
||||
/**
|
||||
* @param array $taxes_rate
|
||||
* @param int $computation_method (COMBINE_METHOD | ONE_AFTER_ANOTHER_METHOD)
|
||||
*/
|
||||
public function __construct(array $taxes_rate, $computation_method = TaxCalculator::COMBINE_METHOD)
|
||||
{
|
||||
$this->taxes_rate = $taxes_rate;
|
||||
$this->computation_method = (int)$computation_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute and add the taxes to the specified price
|
||||
*
|
||||
* @param price
|
||||
* @return price with taxes
|
||||
*/
|
||||
public function addTaxes($price)
|
||||
{
|
||||
$total_price = $price;
|
||||
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
|
||||
{
|
||||
foreach ($this->taxes_rate as $tax_rate)
|
||||
$total_price = $total_price * (1 + abs($tax_rate) / 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->taxes_rate as $tax_rate)
|
||||
{
|
||||
if ($tax_rate != 0)
|
||||
$total_price = $total_price + ($price * (abs($tax_rate) / 100));
|
||||
}
|
||||
}
|
||||
return $total_price;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute and remove the taxes to the specified price
|
||||
*
|
||||
* @param price
|
||||
* @return price without taxes
|
||||
*/
|
||||
public function removeTaxes($price)
|
||||
{
|
||||
$total_price = $price;
|
||||
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
|
||||
{
|
||||
foreach ($this->taxes_rate as $tax_rate)
|
||||
$total_price = $total_price / (1 + abs($tax_rate) / 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
$taxes_rate = 0;
|
||||
foreach ($this->taxes_rate as $tax_rate)
|
||||
$taxes_rate += abs($tax_rate);
|
||||
|
||||
$total_price = $total_price / (1 + (abs($taxes_rate) / 100));
|
||||
}
|
||||
|
||||
return $total_price;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return total taxes rate
|
||||
*/
|
||||
public function getTaxesRate()
|
||||
{
|
||||
$taxes_rate = 0;
|
||||
if ($this->computation_method == TaxCalculator::ONE_AFTER_ANOTHER_METHOD)
|
||||
{
|
||||
$taxes_rate = 1;
|
||||
foreach ($this->taxes_rate as $rate)
|
||||
$taxes_rate *= (1 + (abs($rate) / 100));
|
||||
|
||||
$taxes_rate = $taxes_rate - 1;
|
||||
$taxes_rate = $taxes_rate * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->taxes_rate as $rate)
|
||||
$taxes_rate += abs($rate);
|
||||
}
|
||||
|
||||
return $taxes_rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/*
|
||||
* 2007-2011 PrestaShop
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://opensource.org/licenses/osl-3.0.php
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author PrestaShop SA <contact@prestashop.com>
|
||||
* @copyright 2007-2011 PrestaShop SA
|
||||
* @version Release: $Revision$
|
||||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @since 1.5
|
||||
*/
|
||||
class TaxManagerFactoryCore
|
||||
{
|
||||
protected static $cache_tax_manager;
|
||||
|
||||
/**
|
||||
* Returns a tax manager able to handle this address
|
||||
*
|
||||
* @param Address $address
|
||||
* @param string $type
|
||||
*
|
||||
* @return TaxManager
|
||||
*/
|
||||
public static function getManager(Address $address, $type)
|
||||
{
|
||||
$cache_id = TaxManagerFactory::getCacheKey($address).'-'.$type;
|
||||
if (!isset(TaxManagerFactory::$cache_tax_manager[$cache_id]))
|
||||
{
|
||||
$tax_manager = TaxManagerFactory::execHookTaxManagerFactory($address, $type);
|
||||
if (!($tax_manager instanceof TaxManagerInterface))
|
||||
$tax_manager = new TaxRulesTaxManager($address, $type);
|
||||
|
||||
TaxManagerFactory::$cache_tax_manager[$cache_id] = $tax_manager;
|
||||
}
|
||||
|
||||
return TaxManagerFactory::$cache_tax_manager[$cache_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a tax manager able to handle this type of address in the module list
|
||||
*
|
||||
* @param Address $address
|
||||
* @param string $type
|
||||
*
|
||||
* @return TaxManager
|
||||
*/
|
||||
public static function execHookTaxManagerFactory(Address $address, $type)
|
||||
{
|
||||
$modules_infos = Hook::getModulesFromHook(Hook::getIdByName('taxManager'));
|
||||
$tax_manager = false;
|
||||
|
||||
foreach ($modules_infos as $module_infos)
|
||||
{
|
||||
$module_instance = Module::getInstanceByName($module_infos['name']);
|
||||
if (is_callable(array($module_instance, 'hookTaxManager')))
|
||||
{
|
||||
$tax_manager = $module_instance->hookTaxManager(array(
|
||||
'address' => $address,
|
||||
'params' => $type
|
||||
));
|
||||
}
|
||||
|
||||
if ($tax_manager)
|
||||
break;
|
||||
}
|
||||
|
||||
return $tax_manager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a unique identifier for the address
|
||||
* @param Address
|
||||
*/
|
||||
protected static function getCacheKey(Address $address)
|
||||
{
|
||||
return $address->id_country.'-'
|
||||
.(int)$address->id_state.'-'
|
||||
.$address->postcode.'-'
|
||||
.$address->vat_number.'-'
|
||||
.$address->dni;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/*
|
||||
* 2007-2011 PrestaShop
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://opensource.org/licenses/osl-3.0.php
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author PrestaShop SA <contact@prestashop.com>
|
||||
* @copyright 2007-2011 PrestaShop SA
|
||||
* @version Release: $Revision$
|
||||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A TaxManager define a way to retrieve tax.
|
||||
*/
|
||||
interface TaxManagerInterface
|
||||
{
|
||||
/**
|
||||
* This method determine if the tax manager is available for the specified address.
|
||||
*
|
||||
* @param Address $address
|
||||
* @param string $type
|
||||
*
|
||||
* @return TaxManager
|
||||
*/
|
||||
public static function isAvailableForThisAddress(Address $address);
|
||||
|
||||
/**
|
||||
* Return the tax calculator associated to this address
|
||||
*
|
||||
* @return TaxCalculator
|
||||
*/
|
||||
public function getTaxCalculator();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/*
|
||||
* 2007-2011 PrestaShop
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://opensource.org/licenses/osl-3.0.php
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author PrestaShop SA <contact@prestashop.com>
|
||||
* @copyright 2007-2011 PrestaShop SA
|
||||
* @version Release: $Revision$
|
||||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
abstract class TaxManagerModuleCore extends Module
|
||||
{
|
||||
public $tax_manager_class;
|
||||
|
||||
public function install()
|
||||
{
|
||||
return (parent::install() && $this->registerHook('taxManager') );
|
||||
}
|
||||
|
||||
public function hookTaxManager($args)
|
||||
{
|
||||
$class_file =_PS_MODULE_DIR_.'/'.$this->name.'/'.$this->tax_manager_class.'.php';
|
||||
|
||||
if (!isset($this->tax_manager_class) || !file_exists($class_file))
|
||||
die(Tools::displayError('Incorrect Tax Manager class ['.$this->tax_manager_class.']'));
|
||||
|
||||
require_once($class_file);
|
||||
|
||||
if (!class_exists($this->tax_manager_class))
|
||||
die(Tools::displayError('Tax Manager class not found ['.$this->tax_manager_class.']'));
|
||||
|
||||
$class = $this->tax_manager_class;
|
||||
|
||||
if ($class::isAvailableForThisAddress($args['address']))
|
||||
return new $class();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,21 @@ class TaxRuleCore extends ObjectModel
|
||||
public $id_tax_rules_group;
|
||||
public $id_country;
|
||||
public $id_state;
|
||||
public $id_county;
|
||||
public $zipcode_from;
|
||||
public $zipcode_to;
|
||||
public $id_tax;
|
||||
public $state_behavior;
|
||||
public $county_behavior;
|
||||
public $behavior;
|
||||
public $description;
|
||||
|
||||
protected $fieldsRequired = array('id_tax_rules_group', 'id_country', 'id_tax');
|
||||
protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId', 'id_country' => 'isUnsignedId', 'id_state' => 'isUnsignedId', 'id_county' => 'isUnsignedId', 'id_tax' => 'isUnsignedId', 'state_behavior' => 'isUnsignedInt', 'county_behavior' => 'isUnsignedInt');
|
||||
protected $fieldsValidate = array('id_tax_rules_group' => 'isUnsignedId',
|
||||
'id_country' => 'isUnsignedId',
|
||||
'id_state' => 'isUnsignedId',
|
||||
'zipcode_from' => 'isUnsignedId', // TODO: char
|
||||
'zipcode_to' => 'isUnsignedId', // TODO: char
|
||||
'id_tax' => 'isUnsignedId',
|
||||
'behavior' => 'isUnsignedInt',
|
||||
'description' => 'isUnsignedInt'); // TODO:char
|
||||
|
||||
protected $table = 'tax_rule';
|
||||
protected $identifier = 'id_tax_rule';
|
||||
@@ -47,10 +55,11 @@ class TaxRuleCore extends ObjectModel
|
||||
$fields['id_tax_rules_group'] = (int)($this->id_tax_rules_group);
|
||||
$fields['id_country'] = (int)$this->id_country;
|
||||
$fields['id_state'] = (int)$this->id_state;
|
||||
$fields['id_county'] = (int)$this->id_county;
|
||||
$fields['state_behavior'] = (int)$this->state_behavior;
|
||||
$fields['county_behavior'] = (int)$this->county_behavior;
|
||||
$fields['id_tax'] = (int)($this->id_tax);
|
||||
$fields['zipcode_from'] = (int)$this->zipcode_from;
|
||||
$fields['zipcode_to'] = (int)$this->zipcode_to;
|
||||
$fields['behavior'] = (int)$this->behavior;
|
||||
$fields['id_tax'] = (int)($this->id_tax);
|
||||
$fields['description'] = $this->description;
|
||||
|
||||
return $fields;
|
||||
}
|
||||
@@ -66,23 +75,44 @@ class TaxRuleCore extends ObjectModel
|
||||
);
|
||||
}
|
||||
|
||||
public static function retrieveById($id_tax_rule)
|
||||
{
|
||||
return Db::getInstance()->getRow('
|
||||
SELECT * FROM `'._DB_PREFIX_.'tax_rule`
|
||||
WHERE `id_tax_rule` = '.(int)$id_tax_rule);
|
||||
}
|
||||
/*
|
||||
public static function getTaxRulesByGroupId($id_group)
|
||||
{
|
||||
if (empty($id_group))
|
||||
die(Tools::displayError());
|
||||
|
||||
$results = Db::getInstance()->ExecuteS('
|
||||
return Db::getInstance()->ExecuteS('
|
||||
SELECT *
|
||||
FROM `'._DB_PREFIX_.'tax_rule`
|
||||
WHERE `id_tax_rules_group` = '.(int)$id_group
|
||||
);
|
||||
}*/
|
||||
|
||||
$res = array();
|
||||
foreach ($results AS $row)
|
||||
$res[$row['id_country']][$row['id_state']][$row['id_county']] = array('id_tax' => $row['id_tax'], 'state_behavior' => $row['state_behavior'], 'county_behavior' => $row['county_behavior']);
|
||||
public static function getTaxRulesByGroupId($id_lang, $id_group)
|
||||
{
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
return Db::getInstance()->ExecuteS('
|
||||
SELECT g.`id_tax_rule`,
|
||||
c.`name` AS country_name,
|
||||
s.`name` AS state_name,
|
||||
t.rate,
|
||||
g.`zipcode_from`, g.`zipcode_to`,
|
||||
g.`description`,
|
||||
g.`behavior`
|
||||
FROM `'._DB_PREFIX_.'tax_rule` g
|
||||
LEFT JOIN `'._DB_PREFIX_.'country_lang` c ON (g.`id_country` = c.`id_country` AND id_lang = '.(int)$id_lang.')
|
||||
LEFT JOIN `'._DB_PREFIX_.'state` s ON (g.`id_state` = s.`id_state`)
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (g.`id_tax` = t.`id_tax`)
|
||||
WHERE `id_tax_rules_group` = '.(int)$id_group
|
||||
);
|
||||
}
|
||||
|
||||
public static function deleteTaxRuleByIdTax($id_tax)
|
||||
{
|
||||
@@ -93,19 +123,57 @@ class TaxRuleCore extends ObjectModel
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function deleteTaxRuleByIdCounty($id_county)
|
||||
{
|
||||
return Db::getInstance()->Execute('
|
||||
DELETE FROM `'._DB_PREFIX_.'tax_rule`
|
||||
WHERE `id_county` = '.(int)$id_county
|
||||
);
|
||||
Tools::displayAsDeprecated();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id_tax
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isTaxInUse($id_tax)
|
||||
{
|
||||
return Db::getInstance()->getValue('
|
||||
SELECT COUNT(*) FROM `'._DB_PREFIX_.'tax_rule` WHERE `id_tax` = '.(int)$id_tax
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $zipcode a range of zipcode (eg: 75000 / 75000-75015)
|
||||
* @return array an array containing two zipcode ordered by zipcode
|
||||
*/
|
||||
public function breakDownZipCode($zip_codes)
|
||||
{
|
||||
$zip_codes = preg_split('/-/', $zip_codes);
|
||||
|
||||
if (sizeof($zip_codes) == 2)
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = $zip_codes[1];
|
||||
if ($zip_codes[0] > $zip_codes[1])
|
||||
{
|
||||
$from = $zip_codes[1];
|
||||
$to = $zip_codes[0];
|
||||
}
|
||||
elseif ($zip_codes[0] == $zip_codes[1])
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = 0;
|
||||
}
|
||||
}
|
||||
elseif (sizeof($zip_codes) == 1)
|
||||
{
|
||||
$from = $zip_codes[0];
|
||||
$to = 0;
|
||||
}
|
||||
|
||||
return array($from, $to);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,74 +59,19 @@ class TaxRulesGroupCore extends ObjectModel
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array an array of tax rules group formatted as $id => $name
|
||||
*/
|
||||
public static function getTaxRulesGroupsForOptions()
|
||||
{
|
||||
$tax_rules[] = array('id_tax_rules_group' => 0, 'name' => Tools::displayError('No tax'));
|
||||
return array_merge($tax_rules, TaxRulesGroup::getTaxRulesGroups());
|
||||
}
|
||||
|
||||
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
|
||||
{
|
||||
if (empty($id_tax_rules_group) OR empty($id_country))
|
||||
return array(new Tax()); // No Tax
|
||||
|
||||
if (isset(self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county]))
|
||||
return self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county];
|
||||
|
||||
$rows = Db::getInstance()->ExecuteS('
|
||||
SELECT *
|
||||
FROM `'._DB_PREFIX_.'tax_rule`
|
||||
WHERE `id_country` = '.(int)$id_country.'
|
||||
AND `id_tax_rules_group` = '.(int)$id_tax_rules_group.'
|
||||
AND `id_state` IN (0, '.(int)$id_state.')
|
||||
AND `id_county` IN (0, '.(int)$id_county.')
|
||||
ORDER BY `id_county` DESC, `id_state` DESC'
|
||||
);
|
||||
|
||||
|
||||
$taxes = array();
|
||||
foreach ($rows AS $row)
|
||||
{
|
||||
if ($row['id_county'] != 0)
|
||||
{
|
||||
switch($row['county_behavior'])
|
||||
{
|
||||
case County::USE_BOTH_TAX:
|
||||
$taxes[] = new Tax($row['id_tax']);
|
||||
break;
|
||||
|
||||
case County::USE_COUNTY_TAX:
|
||||
$taxes = array(new Tax($row['id_tax']));
|
||||
break 2;
|
||||
|
||||
case County::USE_STATE_TAX: // do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ($row['id_state'] != 0)
|
||||
{
|
||||
switch($row['state_behavior'])
|
||||
{
|
||||
case PS_STATE_TAX: // use only product tax
|
||||
$taxes[] = new Tax($row['id_tax']);
|
||||
break 2; // switch + foreach
|
||||
|
||||
case PS_BOTH_TAX:
|
||||
$taxes[] = new Tax($row['id_tax']);
|
||||
break;
|
||||
|
||||
case PS_PRODUCT_TAX: // do nothing use country tax
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
$taxes[] = new Tax((int)$row['id_tax']);
|
||||
}
|
||||
|
||||
self::$_taxes[$id_tax_rules_group.'-'.$id_country.'-'.$id_state.'-'.$id_county] = $taxes;
|
||||
return $taxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getAssociatedTaxRatesByIdCountry($id_country)
|
||||
{
|
||||
$rows = Db::getInstance()->ExecuteS('
|
||||
@@ -136,7 +81,7 @@ class TaxRulesGroupCore extends ObjectModel
|
||||
LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)
|
||||
WHERE tr.`id_country` = '.(int)$id_country.'
|
||||
AND tr.`id_state` = 0
|
||||
AND tr.`id_county` = 0'
|
||||
AND 0 between `zipcode_from` AND `zipcode_to`'
|
||||
);
|
||||
|
||||
$res = array();
|
||||
@@ -146,15 +91,12 @@ class TaxRulesGroupCore extends ObjectModel
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $id_county)
|
||||
{
|
||||
$rate = 0;
|
||||
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county) AS $tax)
|
||||
$rate += (float)$tax->rate;
|
||||
|
||||
return $rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tax rules group id corresponding to the name
|
||||
*
|
||||
* @param string name
|
||||
* @return int id of the tax rules
|
||||
*/
|
||||
public static function getIdByName($name)
|
||||
{
|
||||
return Db::getInstance()->getValue(
|
||||
@@ -163,4 +105,29 @@ class TaxRulesGroupCore extends ObjectModel
|
||||
WHERE `name` = \''.pSQL($name).'\''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getTaxesRate($id_tax_rules_group, $id_country, $id_state, $zipcode)
|
||||
{
|
||||
Tools::displayAsDeprecated();
|
||||
$rate = 0;
|
||||
foreach (TaxRulesGroup::getTaxes($id_tax_rules_group, $id_country, $id_state, $zipcode) AS $tax)
|
||||
$rate += (float)$tax->rate;
|
||||
|
||||
return $rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return taxes associated to this para
|
||||
* @deprecated since 1.5
|
||||
*/
|
||||
public static function getTaxes($id_tax_rules_group, $id_country, $id_state, $id_county)
|
||||
{
|
||||
Tools::displayAsDeprecated();
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* 2007-2011 PrestaShop
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.txt.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* http://opensource.org/licenses/osl-3.0.php
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to http://www.prestashop.com for more information.
|
||||
*
|
||||
* @author PrestaShop SA <contact@prestashop.com>
|
||||
* @copyright 2007-2011 PrestaShop SA
|
||||
* @version Release: $Revision$
|
||||
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
||||
* International Registered Trademark & Property of PrestaShop SA
|
||||
*/
|
||||
|
||||
class TaxRulesTaxManagerCore implements TaxManagerInterface
|
||||
{
|
||||
public $address;
|
||||
public $type;
|
||||
public $tax_calculator;
|
||||
|
||||
|
||||
public function __construct(Address $address, $type)
|
||||
{
|
||||
$this->address = $address;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this tax manager is available for this address
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isAvailableForThisAddress(Address $address)
|
||||
{
|
||||
return true; // default manager, available for all addresses
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tax calculator associated to this address
|
||||
*
|
||||
* @return TaxCalculator
|
||||
*/
|
||||
public function getTaxCalculator()
|
||||
{
|
||||
if (isset($this->tax_calculator))
|
||||
return $this->tax_calculator;
|
||||
|
||||
$postcode = 0;
|
||||
if (!empty($this->address->postcode))
|
||||
$postcode = $this->address->postcode;
|
||||
|
||||
$rows = Db::getInstance()->ExecuteS('
|
||||
SELECT *
|
||||
FROM `'._DB_PREFIX_.'tax_rule`
|
||||
WHERE `id_country` = '.(int)$this->address->id_country.'
|
||||
AND `id_tax_rules_group` = '.(int)$this->type.'
|
||||
AND `id_state` IN (0, '.(int)$this->address->id_state.')
|
||||
AND ('.pSQL($postcode).' BETWEEN `zipcode_from` AND `zipcode_to` OR `zipcode_from` = 0 OR `zipcode_from` = '.pSQL($postcode).')
|
||||
ORDER BY `zipcode_from` DESC, `zipcode_to` DESC, `id_state` DESC, `id_country` DESC');
|
||||
|
||||
$behavior = 0;
|
||||
$first_row = true;
|
||||
$taxes_rates = array();
|
||||
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
$tax = new Tax((int)$row['id_tax']);
|
||||
|
||||
$taxes_rates[] = $tax->rate;
|
||||
|
||||
// the applied behavior correspond to the most specific rules
|
||||
if ($first_row)
|
||||
{
|
||||
$behavior = $row['behavior'];
|
||||
$first_row = false;
|
||||
}
|
||||
|
||||
if ($row['behavior'] == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
$this->tax_calculator = new TaxCalculator($taxes_rates, $behavior);
|
||||
|
||||
return $this->tax_calculator;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user