[*] Project : US + CA TaxSystem

This commit is contained in:
fBrignoli
2011-08-18 10:10:50 +00:00
parent 50e9f03719
commit 8f8ac0670d
33 changed files with 1665 additions and 1168 deletions
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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">&nbsp;</span></li>
<li><span class="placeholder">&nbsp;</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, ' ');
}
}
-52
View File
@@ -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;
}
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
*/
+2 -1
View File
@@ -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`
+140 -132
View File
@@ -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];
}
}
+144
View File
@@ -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;
}
}
+103
View File
@@ -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;
}
}
+51
View File
@@ -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();
}
+57
View File
@@ -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;
}
}
+86 -18
View File
@@ -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();
}
}
+101
View File
@@ -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;
}
}