1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: class Mage_Weee_Model_Total_Quote_Weee extends Mage_Tax_Model_Sales_Total_Quote_Tax
29: {
30: 31: 32: 33: 34:
35: protected $_helper;
36: protected $_store;
37:
38: 39: 40: 41: 42:
43: protected $_config;
44:
45: 46: 47: 48: 49:
50: protected $_isTaxAffected;
51:
52: 53: 54:
55: public function __construct()
56: {
57: $this->setCode('weee');
58: $this->_helper = Mage::helper('weee');
59: $this->_config = Mage::getSingleton('tax/config');
60: }
61:
62: 63: 64: 65: 66: 67:
68: public function collect(Mage_Sales_Model_Quote_Address $address)
69: {
70: Mage_Sales_Model_Quote_Address_Total_Abstract::collect($address);
71: $this->_isTaxAffected = false;
72: $items = $this->_getAddressItems($address);
73: if (!count($items)) {
74: return $this;
75: }
76:
77: $address->setAppliedTaxesReset(true);
78: $address->setAppliedTaxes(array());
79:
80: $this->_store = $address->getQuote()->getStore();
81: foreach ($items as $item) {
82: if ($item->getParentItemId()) {
83: continue;
84: }
85: $this->_resetItemData($item);
86: if ($item->getHasChildren() && $item->isChildrenCalculated()) {
87: foreach ($item->getChildren() as $child) {
88: $this->_resetItemData($child);
89: $this->_process($address, $child);
90: }
91: $this->_recalculateParent($item);
92: } else {
93: $this->_process($address, $item);
94: }
95: }
96:
97: if ($this->_isTaxAffected) {
98: $address->unsSubtotalInclTax();
99: $address->unsBaseSubtotalInclTax();
100: }
101:
102: return $this;
103: }
104:
105: 106: 107: 108: 109: 110: 111:
112: protected function _process(Mage_Sales_Model_Quote_Address $address, $item)
113: {
114: if (!$this->_helper->isEnabled($this->_store)) {
115: return $this;
116: }
117:
118: $attributes = $this->_helper->getProductWeeeAttributes(
119: $item->getProduct(),
120: $address,
121: $address->getQuote()->getBillingAddress(),
122: $this->_store->getWebsiteId()
123: );
124:
125: $applied = array();
126: $productTaxes = array();
127:
128: $totalValue = 0;
129: $baseTotalValue = 0;
130: $totalRowValue = 0;
131: $baseTotalRowValue = 0;
132:
133: foreach ($attributes as $k=>$attribute) {
134: $baseValue = $attribute->getAmount();
135: $value = $this->_store->convertPrice($baseValue);
136: $rowValue = $value*$item->getTotalQty();
137: $baseRowValue = $baseValue*$item->getTotalQty();
138: $title = $attribute->getName();
139:
140: $totalValue += $value;
141: $baseTotalValue += $baseValue;
142: $totalRowValue += $rowValue;
143: $baseTotalRowValue += $baseRowValue;
144:
145: $productTaxes[] = array(
146: 'title' => $title,
147: 'base_amount' => $baseValue,
148: 'amount' => $value,
149: 'row_amount' => $rowValue,
150: 'base_row_amount'=> $baseRowValue,
151: 152: 153:
154: 'base_amount_incl_tax' => $baseValue,
155: 'amount_incl_tax' => $value,
156: 'row_amount_incl_tax' => $rowValue,
157: 'base_row_amount_incl_tax' => $baseRowValue,
158: );
159:
160: $applied[] = array(
161: 'id' => $attribute->getCode(),
162: 'percent' => null,
163: 'hidden' => $this->_helper->includeInSubtotal($this->_store),
164: 'rates' => array(array(
165: 'base_real_amount'=> $baseRowValue,
166: 'base_amount' => $baseRowValue,
167: 'amount' => $rowValue,
168: 'code' => $attribute->getCode(),
169: 'title' => $title,
170: 'percent' => null,
171: 'position' => 1,
172: 'priority' => -1000+$k,
173: ))
174: );
175: }
176:
177: $item->setWeeeTaxAppliedAmount($totalValue)
178: ->setBaseWeeeTaxAppliedAmount($baseTotalValue)
179: ->setWeeeTaxAppliedRowAmount($totalRowValue)
180: ->setBaseWeeeTaxAppliedRowAmount($baseTotalRowValue);
181:
182: $this->_processTaxSettings($item, $totalValue, $baseTotalValue, $totalRowValue, $baseTotalRowValue)
183: ->_processTotalAmount($address, $totalRowValue, $baseTotalRowValue)
184: ->_processDiscountSettings($item, $totalValue, $baseTotalValue);
185:
186: $this->_helper->setApplied($item, array_merge($this->_helper->getApplied($item), $productTaxes));
187: if ($applied) {
188: $this->_saveAppliedTaxes($address, $applied,
189: $item->getWeeeTaxAppliedAmount(),
190: $item->getBaseWeeeTaxAppliedAmount(),
191: null
192: );
193: }
194:
195: }
196:
197: 198: 199: 200: 201: 202: 203: 204:
205: protected function _processDiscountSettings($item, $value, $baseValue)
206: {
207: if ($this->_helper->isDiscounted($this->_store)) {
208: Mage::helper('salesrule')->addItemDiscountPrices($item, $baseValue, $value);
209: }
210: return $this;
211: }
212:
213: 214: 215: 216: 217: 218: 219: 220: 221: 222:
223: protected function _processTaxSettings($item, $value, $baseValue, $rowValue, $baseRowValue)
224: {
225: if ($this->_helper->isTaxable($this->_store) && $rowValue) {
226: if (!$this->_config->priceIncludesTax($this->_store)) {
227: $item->setExtraTaxableAmount($value)
228: ->setBaseExtraTaxableAmount($baseValue)
229: ->setExtraRowTaxableAmount($rowValue)
230: ->setBaseExtraRowTaxableAmount($baseRowValue);
231: }
232: $item->unsRowTotalInclTax()
233: ->unsBaseRowTotalInclTax()
234: ->unsPriceInclTax()
235: ->unsBasePriceInclTax();
236: $this->_isTaxAffected = true;
237: }
238: return $this;
239: }
240:
241: 242: 243: 244: 245: 246: 247: 248:
249: protected function _processTotalAmount($address, $rowValue, $baseRowValue)
250: {
251: if ($this->_helper->includeInSubtotal($this->_store)) {
252: $address->addTotalAmount('subtotal', $rowValue);
253: $address->addBaseTotalAmount('subtotal', $baseRowValue);
254: $this->_isTaxAffected = true;
255: } else {
256: $address->setExtraTaxAmount($address->getExtraTaxAmount() + $rowValue);
257: $address->setBaseExtraTaxAmount($address->getBaseExtraTaxAmount() + $baseRowValue);
258: }
259: return $this;
260: }
261:
262: 263: 264: 265: 266: 267:
268: protected function _recalculateParent(Mage_Sales_Model_Quote_Item_Abstract $item)
269: {
270:
271: }
272:
273: 274: 275: 276: 277: 278:
279: protected function _resetItemData($item)
280: {
281: $this->_helper->setApplied($item, array());
282:
283: $item->setBaseWeeeTaxDisposition(0);
284: $item->setWeeeTaxDisposition(0);
285:
286: $item->setBaseWeeeTaxRowDisposition(0);
287: $item->setWeeeTaxRowDisposition(0);
288:
289: $item->setBaseWeeeTaxAppliedAmount(0);
290: $item->setBaseWeeeTaxAppliedRowAmount(0);
291:
292: $item->setWeeeTaxAppliedAmount(0);
293: $item->setWeeeTaxAppliedRowAmount(0);
294: }
295:
296: 297: 298: 299: 300: 301:
302: public function fetch(Mage_Sales_Model_Quote_Address $address)
303: {
304: return $this;
305: }
306:
307: 308: 309: 310: 311: 312: 313: 314:
315: public function processConfigArray($config, $store)
316: {
317: return $config;
318: }
319:
320: 321: 322: 323: 324: 325: 326: 327: 328:
329: protected function _processItem(Mage_Sales_Model_Quote_Address $address, $item, $updateParent = false)
330: {
331: $store = $address->getQuote()->getStore();
332: if (!$this->_helper->isEnabled($store)) {
333: return $this;
334: }
335: $custTaxClassId = $address->getQuote()->getCustomerTaxClassId();
336:
337: $taxCalculationModel = Mage::getSingleton('tax/calculation');
338:
339: $request = $taxCalculationModel->getRateRequest(
340: $address,
341: $address->getQuote()->getBillingAddress(),
342: $custTaxClassId,
343: $store
344: );
345: $defaultRateRequest = $taxCalculationModel->getRateRequest(false, false, false, $store);
346:
347: $attributes = $this->_helper->getProductWeeeAttributes(
348: $item->getProduct(),
349: $address,
350: $address->getQuote()->getBillingAddress(),
351: $store->getWebsiteId()
352: );
353:
354: $applied = array();
355: $productTaxes = array();
356:
357: foreach ($attributes as $k=>$attribute) {
358: $baseValue = $attribute->getAmount();
359: $value = $store->convertPrice($baseValue);
360:
361: $rowValue = $value*$item->getQty();
362: $baseRowValue = $baseValue*$item->getQty();
363:
364: $title = $attribute->getName();
365:
366: 367: 368:
369: if ($item->getDiscountPercent() && $this->_helper->isDiscounted($store)) {
370: $valueDiscount = $value/100*$item->getDiscountPercent();
371: $baseValueDiscount = $baseValue/100*$item->getDiscountPercent();
372:
373: $rowValueDiscount = $rowValue/100*$item->getDiscountPercent();
374: $baseRowValueDiscount = $baseRowValue/100*$item->getDiscountPercent();
375:
376: $address->setDiscountAmount($address->getDiscountAmount()+$rowValueDiscount);
377: $address->setBaseDiscountAmount($address->getBaseDiscountAmount()+$baseRowValueDiscount);
378:
379: $address->setGrandTotal($address->getGrandTotal() - $rowValueDiscount);
380: $address->setBaseGrandTotal($address->getBaseGrandTotal() - $baseRowValueDiscount);
381: }
382:
383: $oneDisposition = $baseOneDisposition = $disposition = $baseDisposition = 0;
384:
385: 386: 387:
388: if ($this->_helper->isTaxable($store)) {
389: $currentPercent = $item->getTaxPercent();
390: $defaultPercent = $taxCalculationModel->getRate(
391: $defaultRateRequest->setProductClassId($item->getProduct()->getTaxClassId())
392: );
393:
394: $valueBeforeVAT = $rowValue;
395: $baseValueBeforeVAT = $baseRowValue;
396:
397: $oneDisposition = $store->roundPrice($value/(100+$defaultPercent)*$currentPercent);
398: $baseOneDisposition = $store->roundPrice($baseValue/(100+$defaultPercent)*$currentPercent);
399:
400: $disposition = $store->roundPrice($rowValue/(100+$defaultPercent)*$currentPercent);
401: $baseDisposition = $store->roundPrice($baseRowValue/(100+$defaultPercent)*$currentPercent);
402:
403: $item->setBaseTaxAmount($item->getBaseTaxAmount()+$baseDisposition);
404: $item->setTaxAmount($item->getTaxAmount()+$disposition);
405:
406: $value -= $oneDisposition;
407: $baseValue -= $baseOneDisposition;
408:
409: $rowValue -= $baseDisposition;
410: $baseRowValue -= $disposition;
411:
412: $item->setWeeeTaxDisposition($item->getWeeeTaxDisposition() + $oneDisposition);
413: $item->setBaseWeeeTaxDisposition($item->getBaseWeeeTaxDisposition() + $baseOneDisposition);
414: $item->setWeeeTaxRowDisposition($item->getWeeeTaxRowDisposition() + $disposition);
415: $item->setBaseWeeeTaxRowDisposition($item->getBaseWeeeTaxRowDisposition() + $baseDisposition);
416:
417:
418:
419:
420: $address->setTaxAmount($address->getTaxAmount() + $disposition);
421: $address->setBaseTaxAmount($address->getBaseTaxAmount() + $baseDisposition);
422:
423: $rate = $taxCalculationModel->getRate(
424: $request->setProductClassId($item->getProduct()->getTaxClassId())
425: );
426:
427: $this->_saveAppliedTaxes(
428: $address,
429: $taxCalculationModel->getAppliedRates($request),
430: $store->roundPrice($valueBeforeVAT-$rowValue),
431: $store->roundPrice($baseValueBeforeVAT-$baseRowValue),
432: $rate
433: );
434:
435: $address->setGrandTotal(
436: $address->getGrandTotal() + $store->roundPrice($valueBeforeVAT - $rowValue)
437: );
438: $address->setBaseGrandTotal(
439: $address->getBaseGrandTotal() + $store->roundPrice($baseValueBeforeVAT - $baseRowValue)
440: );
441: }
442:
443: 444: 445:
446: if ($this->_helper->includeInSubtotal($store)) {
447: $address->setSubtotal($address->getSubtotal() + $rowValue);
448: $address->setBaseSubtotal($address->getBaseSubtotal() + $baseRowValue);
449:
450:
451:
452: } else {
453: $address->setTaxAmount($address->getTaxAmount() + $rowValue);
454: $address->setBaseTaxAmount($address->getBaseTaxAmount() + $baseRowValue);
455: }
456:
457:
458: $productTaxes[] = array(
459: 'title'=>$title,
460: 'base_amount'=>$baseValue,
461: 'amount'=>$value,
462:
463: 'row_amount'=>$rowValue,
464: 'base_row_amount'=>$baseRowValue,
465:
466: 'base_amount_incl_tax'=>$baseValue+$baseOneDisposition,
467: 'amount_incl_tax'=>$value+$oneDisposition,
468:
469: 'row_amount_incl_tax'=>$rowValue+$disposition,
470: 'base_row_amount_incl_tax'=>$baseRowValue+$baseDisposition,
471: );
472:
473: $applied[] = array(
474: 'id'=>$attribute->getCode(),
475: 'percent'=>null,
476: 'hidden'=>$this->_helper->includeInSubtotal($store),
477: 'rates' => array(array(
478: 'amount'=>$rowValue,
479: 'base_amount'=>$baseRowValue,
480: 'base_real_amount'=>$baseRowValue,
481: 'code'=>$attribute->getCode(),
482: 'title'=>$title,
483: 'percent'=>null,
484: 'position'=>1,
485: 'priority'=>-1000+$k,
486: ))
487: );
488:
489: $item->setBaseWeeeTaxAppliedAmount($item->getBaseWeeeTaxAppliedAmount() + $baseValue);
490: $item->setBaseWeeeTaxAppliedRowAmount($item->getBaseWeeeTaxAppliedRowAmount() + $baseRowValue);
491:
492: $item->setWeeeTaxAppliedAmount($item->getWeeeTaxAppliedAmount() + $value);
493: $item->setWeeeTaxAppliedRowAmount($item->getWeeeTaxAppliedRowAmount() + $rowValue);
494: }
495:
496: $this->_helper->setApplied($item, array_merge($this->_helper->getApplied($item), $productTaxes));
497:
498: if ($updateParent) {
499: $parent = $item->getParentItem();
500:
501: $parent->setBaseWeeeTaxDisposition(
502: $parent->getBaseWeeeTaxDisposition() + $item->getBaseWeeeTaxDisposition()
503: );
504: $parent->setWeeeTaxDisposition(
505: $parent->getWeeeTaxDisposition() + $item->getWeeeTaxDisposition()
506: );
507:
508: $parent->setBaseWeeeTaxRowDisposition(
509: $parent->getBaseWeeeTaxRowDisposition() + $item->getBaseWeeeTaxRowDisposition()
510: );
511: $parent->setWeeeTaxRowDisposition(
512: $parent->getWeeeTaxRowDisposition() + $item->getWeeeTaxRowDisposition()
513: );
514:
515: $parent->setBaseWeeeTaxAppliedAmount(
516: $parent->getBaseWeeeTaxAppliedAmount() + $item->getBaseWeeeTaxAppliedAmount()
517: );
518: $parent->setBaseWeeeTaxAppliedRowAmount(
519: $parent->getBaseWeeeTaxAppliedRowAmount() + $item->getBaseWeeeTaxAppliedRowAmount()
520: );
521:
522: $parent->setWeeeTaxAppliedAmount(
523: $parent->getWeeeTaxAppliedAmount() + $item->getWeeeTaxAppliedAmount()
524: );
525: $parent->setWeeeTaxAppliedRowAmount(
526: $parent->getWeeeTaxAppliedRowAmount() + $item->getWeeeTaxAppliedRowAmount()
527: );
528: }
529:
530: if ($applied) {
531: $this->_saveAppliedTaxes(
532: $address,
533: $applied,
534: $item->getWeeeTaxAppliedAmount(),
535: $item->getBaseWeeeTaxAppliedAmount(),
536: null
537: );
538: }
539: }
540:
541: 542: 543: 544: 545:
546: public function getLabel()
547: {
548: return '';
549: }
550: }
551: