00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 class Mage_Tax_Model_Mysql4_Calculation extends Mage_Core_Model_Mysql4_Abstract
00033 {
00034 protected function _construct()
00035 {
00036 $this->_setMainTable('tax/tax_calculation');
00037 }
00038
00039 public function deleteByRuleId($ruleId)
00040 {
00041 $conn = $this->_getWriteAdapter();
00042 $where = $conn->quoteInto('tax_calculation_rule_id = ?', $ruleId);
00043 $conn->delete($this->getMainTable(), $where);
00044 }
00045
00046 public function getDistinct($field, $ruleId)
00047 {
00048 $select = $this->_getReadAdapter()->select();
00049 $select->from($this->getMainTable(), $field)->where('tax_calculation_rule_id = ?', $ruleId);
00050 return $this->_getReadAdapter()->fetchCol($select);
00051 }
00052
00053 public function getRate($request)
00054 {
00055 return $this->_calculateRate($this->_getRates($request));
00056 }
00057
00058 public function getCalculationProcess($request, $rates = null)
00059 {
00060 if (is_null($rates)) {
00061 $rates = $this->_getRates($request);
00062 }
00063
00064 $result = array();
00065 $row = array();
00066 $ids = array();
00067 $currentRate = 0;
00068 $totalPercent = 0;
00069 for ($i=0; $i<count($rates); $i++) {
00070 $rate = $rates[$i];
00071 $value = (isset($rate['value']) ? $rate['value'] : $rate['percent'])*1;
00072
00073 $oneRate = array(
00074 'code'=>$rate['code'],
00075 'title'=>$rate['title'],
00076 'percent'=>$value,
00077 'position'=>$rate['position'],
00078 'priority'=>$rate['priority'],
00079 );
00080
00081
00082 if (isset($rate['hidden'])) {
00083 $row['hidden'] = $rate['hidden'];
00084 }
00085
00086 if (isset($rate['amount'])) {
00087 $row['amount'] = $rate['amount'];
00088 }
00089
00090 if (isset($rate['base_amount'])) {
00091 $row['base_amount'] = $rate['base_amount'];
00092 }
00093 if (isset($rate['base_real_amount'])) {
00094 $row['base_real_amount'] = $rate['base_real_amount'];
00095 }
00096 $row['rates'][] = $oneRate;
00097
00098 if (isset($rates[$i+1]['tax_calculation_rule_id'])) {
00099 $rule = $rate['tax_calculation_rule_id'];
00100 }
00101 $priority = $rate['priority'];
00102 $ids[] = $rate['code'];
00103
00104 if (isset($rates[$i+1]['tax_calculation_rule_id'])) {
00105 while(isset($rates[$i+1]) && $rates[$i+1]['tax_calculation_rule_id'] == $rule) {
00106 $i++;
00107 }
00108 }
00109
00110 $currentRate += $value;
00111
00112 if (!isset($rates[$i+1]) || $rates[$i+1]['priority'] != $priority || (isset($rates[$i+1]['process']) && $rates[$i+1]['process'] != $rate['process'])) {
00113 $row['percent'] = (100+$totalPercent)*($currentRate/100);
00114 $row['id'] = implode($ids);
00115 $result[] = $row;
00116 $row = array();
00117 $ids = array();
00118
00119 $totalPercent += (100+$totalPercent)*($currentRate/100);
00120 $currentRate = 0;
00121 }
00122 }
00123
00124 return $result;
00125 }
00126
00127 protected function _getRates($request)
00128 {
00129 $storeId = Mage::app()->getStore($request->getStore())->getId();
00130
00131 $select = $this->_getReadAdapter()->select();
00132 $select
00133 ->from(array('main_table'=>$this->getMainTable()))
00134 ->where('customer_tax_class_id = ?', $request->getCustomerClassId())
00135 ->where('product_tax_class_id = ?', $request->getProductClassId());
00136
00137 $select->join(array('rule'=>$this->getTable('tax/tax_calculation_rule')), 'rule.tax_calculation_rule_id = main_table.tax_calculation_rule_id', array('rule.priority', 'rule.position'));
00138 $select->join(array('rate'=>$this->getTable('tax/tax_calculation_rate')), 'rate.tax_calculation_rate_id = main_table.tax_calculation_rate_id', array('value'=>'rate.rate', 'rate.tax_country_id', 'rate.tax_region_id', 'rate.tax_postcode', 'rate.tax_calculation_rate_id', 'rate.code'));
00139
00140 $select
00141 ->where("rate.tax_country_id = ?", $request->getCountryId())
00142 ->where("rate.tax_region_id in ('*', '', ?)", $request->getRegionId())
00143 ->where("rate.tax_postcode in ('*', '', ?)", $request->getPostcode());
00144
00145 $select->joinLeft(array('title_table'=>$this->getTable('tax/tax_calculation_rate_title')), "rate.tax_calculation_rate_id = title_table.tax_calculation_rate_id AND title_table.store_id = '{$storeId}'", array('title'=>'IFNULL(title_table.value, rate.code)'));
00146
00147 $order = array('rule.priority ASC', 'rule.tax_calculation_rule_id ASC', 'rate.tax_country_id DESC', 'rate.tax_region_id DESC', 'rate.tax_postcode DESC', 'rate.rate DESC');
00148 $select->order($order);
00149
00150 return $this->_getReadAdapter()->fetchAll($select);
00151 }
00152
00153 protected function _calculateRate($rates)
00154 {
00155 $result = 0;
00156 $currentRate = 0;
00157 for ($i=0; $i<count($rates); $i++) {
00158 $rate = $rates[$i];
00159 $rule = $rate['tax_calculation_rule_id'];
00160 $value = $rate['value'];
00161 $priority = $rate['priority'];
00162
00163 while(isset($rates[$i+1]) && $rates[$i+1]['tax_calculation_rule_id'] == $rule) {
00164 $i++;
00165 }
00166
00167 $currentRate += $value;
00168
00169 if (!isset($rates[$i+1]) || $rates[$i+1]['priority'] != $priority) {
00170 $result += (100+$result)*($currentRate/100);
00171 $currentRate = 0;
00172 }
00173 }
00174
00175 return $result;
00176 }
00177
00178 public function getRateIds($request)
00179 {
00180 $result = array();
00181 $rates = $this->_getRates($request);
00182 for ($i=0; $i<count($rates); $i++) {
00183 $rate = $rates[$i];
00184 $rule = $rate['tax_calculation_rule_id'];
00185 $result[] = $rate['tax_calculation_rate_id'];
00186 while(isset($rates[$i+1]) && $rates[$i+1]['tax_calculation_rule_id'] == $rule) {
00187 $i++;
00188 }
00189 }
00190 return $result;
00191 }
00192
00193 public function getRatesByCustomerTaxClass($customerTaxClass, $productTaxClass = null)
00194 {
00195 $calcJoinConditions = "calc_table.tax_calculation_rate_id = main_table.tax_calculation_rate_id";
00196 $calcJoinConditions .= " AND calc_table.customer_tax_class_id = '{$customerTaxClass}'";
00197 if ($productTaxClass) {
00198 $calcJoinConditions .= " AND calc_table.product_tax_class_id = '{$productTaxClass}'";
00199 }
00200
00201 $selectCSP = $this->_getReadAdapter()->select();
00202 $selectCSP->from(array('main_table'=>$this->getTable('tax/tax_calculation_rate')), array('country'=>'tax_country_id', 'region_id'=>'tax_region_id', 'postcode'=>'tax_postcode'))
00203 ->joinInner(
00204 array('calc_table'=>$this->getTable('tax/tax_calculation')),
00205 $calcJoinConditions,
00206 array('product_class'=>'calc_table.product_tax_class_id'))
00207
00208 ->joinLeft(
00209 array('state_table'=>$this->getTable('directory/country_region')),
00210 'state_table.region_id = main_table.tax_region_id',
00211 array('region_code'=>'state_table.code'))
00212
00213 ->distinct(true);
00214
00215 $CSP = $this->_getReadAdapter()->fetchAll($selectCSP);
00216
00217 $result = array();
00218 foreach ($CSP as $one) {
00219 $request = new Varien_Object();
00220 $request->setCountryId($one['country'])
00221 ->setRegionId($one['region_id'])
00222 ->setPostcode($one['postcode'])
00223 ->setCustomerClassId($customerTaxClass)
00224 ->setProductClassId($one['product_class']);
00225
00226 $rate = $this->getRate($request);
00227 if ($rate) {
00228 $row = array(
00229 'value' => $rate/100,
00230 'country' => $one['country'],
00231 'state' => $one['region_code'],
00232 'postcode' => $one['postcode'],
00233 'product_class' => $one['product_class'],
00234 );
00235
00236 $result[] = $row;
00237 }
00238 }
00239
00240 return $result;
00241 }
00242
00243 }