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: 29:
30: class Mage_Tax_Model_Sales_Total_Quote_Subtotal extends Mage_Sales_Model_Quote_Address_Total_Abstract
31: {
32: 33: 34: 35: 36:
37: protected $_calculator = null;
38:
39: 40: 41: 42: 43:
44: protected $_config = null;
45: protected $_helper = null;
46:
47: protected $_subtotalInclTax = 0;
48: protected $_baseSubtotalInclTax = 0;
49: protected $_subtotal = 0;
50: protected $_baseSubtotal = 0;
51:
52: 53: 54: 55: 56: 57:
58: protected $_areTaxRequestsSimilar = false;
59:
60: 61: 62: 63: 64:
65: protected $_storeTaxRequest = null;
66:
67: 68: 69: 70: 71:
72: protected $_store;
73:
74: 75: 76: 77: 78:
79: protected $_roundingDeltas = array();
80:
81: 82: 83:
84: public function __construct()
85: {
86: $this->setCode('tax_subtotal');
87: $this->_helper = Mage::helper('tax');
88: $this->_calculator = Mage::getSingleton('tax/calculation');
89: $this->_config = Mage::getSingleton('tax/config');
90: }
91:
92: 93: 94: 95: 96: 97: 98: 99:
100: public function collect(Mage_Sales_Model_Quote_Address $address)
101: {
102: $this->_store = $address->getQuote()->getStore();
103: $this->_address = $address;
104:
105: $this->_subtotalInclTax = 0;
106: $this->_baseSubtotalInclTax = 0;
107: $this->_subtotal = 0;
108: $this->_baseSubtotal = 0;
109: $this->_roundingDeltas = array();
110:
111: $address->setSubtotalInclTax(0);
112: $address->setBaseSubtotalInclTax(0);
113: $address->setTotalAmount('subtotal', 0);
114: $address->setBaseTotalAmount('subtotal', 0);
115:
116: $items = $this->_getAddressItems($address);
117: if (!$items) {
118: return $this;
119: }
120:
121: $addressRequest = $this->_getAddressTaxRequest($address);
122: $storeRequest = $this->_getStoreTaxRequest($address);
123: $this->_calculator->setCustomer($address->getQuote()->getCustomer());
124: if ($this->_config->priceIncludesTax($this->_store)) {
125: $classIds = array();
126: foreach ($items as $item) {
127: $classIds[] = $item->getProduct()->getTaxClassId();
128: if ($item->getHasChildren()) {
129: foreach ($item->getChildren() as $child) {
130: $classIds[] = $child->getProduct()->getTaxClassId();
131: }
132: }
133: }
134: $classIds = array_unique($classIds);
135: $storeRequest->setProductClassId($classIds);
136: $addressRequest->setProductClassId($classIds);
137: $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest);
138: }
139:
140: foreach ($items as $item) {
141: if ($item->getParentItem()) {
142: continue;
143: }
144: if ($item->getHasChildren() && $item->isChildrenCalculated()) {
145: foreach ($item->getChildren() as $child) {
146: $this->_processItem($child, $addressRequest);
147: }
148: $this->_recalculateParent($item);
149: } else {
150: $this->_processItem($item, $addressRequest);
151: }
152: $this->_addSubtotalAmount($address, $item);
153: }
154: $address->setRoundingDeltas($this->_roundingDeltas);
155: return $this;
156: }
157:
158: 159: 160: 161: 162: 163: 164:
165: protected function _processItem($item, $taxRequest)
166: {
167: switch ($this->_config->getAlgorithm($this->_store)) {
168: case Mage_Tax_Model_Calculation::CALC_UNIT_BASE:
169: $this->_unitBaseCalculation($item, $taxRequest);
170: break;
171: case Mage_Tax_Model_Calculation::CALC_ROW_BASE:
172: $this->_rowBaseCalculation($item, $taxRequest);
173: break;
174: case Mage_Tax_Model_Calculation::CALC_TOTAL_BASE:
175: $this->_totalBaseCalculation($item, $taxRequest);
176: break;
177: default:
178: break;
179: }
180: return $this;
181: }
182:
183: 184: 185: 186: 187: 188: 189:
190: protected function _unitBaseCalculation($item, $request)
191: {
192: $request->setProductClassId($item->getProduct()->getTaxClassId());
193: $rate = $this->_calculator->getRate($request);
194: $qty = $item->getTotalQty();
195:
196: $price = $taxPrice = $item->getCalculationPriceOriginal();
197: $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
198: $subtotal = $taxSubtotal = $item->getRowTotal();
199: $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
200: $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
201: if ($taxOnOrigPrice) {
202: $origPrice = $item->getOriginalPrice();
203: $baseOrigPrice = $item->getBaseOriginalPrice();
204: }
205:
206:
207: $item->setTaxPercent($rate);
208: if ($this->_config->priceIncludesTax($this->_store)) {
209: if ($this->_sameRateAsStore($request)) {
210: $tax = $this->_calculator->calcTaxAmount($price, $rate, true);
211: $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, true);
212: $taxPrice = $price;
213: $baseTaxPrice = $basePrice;
214: $taxSubtotal = $subtotal;
215: $baseTaxSubtotal= $baseSubtotal;
216: $price = $price - $tax;
217: $basePrice = $basePrice - $baseTax;
218: $subtotal = $price * $qty;
219: $baseSubtotal = $basePrice * $qty;
220: if ($taxOnOrigPrice) {
221: $taxable = $origPrice;
222: $baseTaxable = $baseOrigPrice;
223: } else {
224: $taxable = $taxPrice;
225: $baseTaxable = $baseTaxPrice;
226: }
227: $isPriceInclTax = true;
228: } else {
229: $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
230: $storeTax = $this->_calculator->calcTaxAmount($price, $storeRate, true);
231: $baseStoreTax = $this->_calculator->calcTaxAmount($basePrice, $storeRate, true);
232: $price = $price - $storeTax;
233: $basePrice = $basePrice - $baseStoreTax;
234: $subtotal = $price * $qty;
235: $baseSubtotal = $basePrice * $qty;
236:
237: $tax = $this->_calculator->calcTaxAmount($price, $rate, false);
238: $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false);
239: $taxPrice = $price + $tax;
240: $baseTaxPrice = $basePrice + $baseTax;
241: $taxSubtotal = $taxPrice * $qty;
242: $baseTaxSubtotal= $baseTaxPrice * $qty;
243: if ($taxOnOrigPrice) {
244: $taxable = $origPrice - $storeTax;
245: $baseTaxable = $baseOrigPrice - $baseStoreTax;
246: } else {
247: $taxable = $price;
248: $baseTaxable = $basePrice;
249: }
250: $isPriceInclTax = false;
251: }
252: } else {
253: $tax = $this->_calculator->calcTaxAmount($price, $rate, false);
254: $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false);
255: $taxPrice = $price + $tax;
256: $baseTaxPrice = $basePrice + $baseTax;
257: $taxSubtotal = $taxPrice * $qty;
258: $baseTaxSubtotal= $baseTaxPrice * $qty;
259: if ($taxOnOrigPrice) {
260: $taxable = $origPrice;
261: $baseTaxable = $baseOrigPrice;
262: } else {
263: $taxable = $price;
264: $baseTaxable = $basePrice;
265: }
266: $isPriceInclTax = false;
267: }
268:
269: if ($item->hasCustomPrice()) {
270: 271: 272:
273: $item->getOriginalPrice();
274: $item->setCustomPrice($price);
275: $item->setBaseCustomPrice($basePrice);
276: }
277: $item->setPrice($basePrice);
278: $item->setBasePrice($basePrice);
279: $item->setRowTotal($subtotal);
280: $item->setBaseRowTotal($baseSubtotal);
281: $item->setPriceInclTax($taxPrice);
282: $item->setBasePriceInclTax($baseTaxPrice);
283: $item->setRowTotalInclTax($taxSubtotal);
284: $item->setBaseRowTotalInclTax($baseTaxSubtotal);
285: $item->setTaxableAmount($taxable);
286: $item->setBaseTaxableAmount($baseTaxable);
287: $item->setIsPriceInclTax($isPriceInclTax);
288: if ($this->_config->discountTax($this->_store)) {
289: $item->setDiscountCalculationPrice($taxPrice);
290: $item->setBaseDiscountCalculationPrice($baseTaxPrice);
291: }
292: return $this;
293: }
294:
295: 296: 297: 298: 299: 300: 301:
302: protected function _rowBaseCalculation($item, $request)
303: {
304: $request->setProductClassId($item->getProduct()->getTaxClassId());
305: $rate = $this->_calculator->getRate($request);
306: $qty = $item->getTotalQty();
307:
308: $price = $taxPrice = $item->getCalculationPriceOriginal();
309: $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
310: $subtotal = $taxSubtotal = $item->getRowTotal();
311: $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
312: $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
313: if ($taxOnOrigPrice) {
314: $origSubtotal = $item->getOriginalPrice() * $qty;
315: $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty;
316: }
317:
318: $item->setTaxPercent($rate);
319: if ($this->_config->priceIncludesTax($this->_store)) {
320: if ($this->_sameRateAsStore($request)) {
321: $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, true, false);
322: $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, true, false);
323: $taxPrice = $price;
324: $baseTaxPrice = $basePrice;
325: $taxSubtotal = $subtotal;
326: $baseTaxSubtotal= $baseSubtotal;
327: $subtotal = $this->_calculator->round($subtotal - $rowTax);
328: $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax);
329: $price = $this->_calculator->round($subtotal/$qty);
330: $basePrice = $this->_calculator->round($baseSubtotal/$qty);
331: if ($taxOnOrigPrice) {
332: $taxable = $origSubtotal;
333: $baseTaxable = $baseOrigSubtotal;
334: } else {
335: $taxable = $taxSubtotal;
336: $baseTaxable = $baseTaxSubtotal;
337: }
338: $isPriceInclTax = true;
339: } else {
340: $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
341: $storeTax = $this->_calculator->calcTaxAmount($subtotal, $storeRate, true, false);
342: $baseStoreTax = $this->_calculator->calcTaxAmount($baseSubtotal, $storeRate, true, false);
343: $subtotal = $this->_calculator->round($subtotal - $storeTax);
344: $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseStoreTax);
345: $price = $this->_calculator->round($subtotal/$qty);
346: $basePrice = $this->_calculator->round($baseSubtotal/$qty);
347:
348: $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false);
349: $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false);
350: $taxSubtotal = $subtotal + $rowTax;
351: $baseTaxSubtotal= $baseSubtotal + $baseRowTax;
352: $taxPrice = $this->_calculator->round($taxSubtotal/$qty);
353: $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal/$qty);
354: if ($taxOnOrigPrice) {
355: $taxable = $this->_calculator->round($origSubtotal - $storeTax);
356: $baseTaxable = $this->_calculator->round($baseOrigSubtotal - $baseStoreTax);
357: } else {
358: $taxable = $subtotal;
359: $baseTaxable = $baseSubtotal;
360: }
361: $isPriceInclTax = false;
362: }
363: } else {
364: $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false);
365: $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false);
366: $taxSubtotal = $subtotal + $rowTax;
367: $baseTaxSubtotal= $baseSubtotal + $baseRowTax;
368: $taxPrice = $this->_calculator->round($taxSubtotal/$qty);
369: $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal/$qty);
370: if ($taxOnOrigPrice) {
371: $taxable = $origSubtotal;
372: $baseTaxable = $baseOrigSubtotal;
373: } else {
374: $taxable = $subtotal;
375: $baseTaxable = $baseSubtotal;
376: }
377: $isPriceInclTax = false;
378: }
379:
380: if ($item->hasCustomPrice()) {
381: 382: 383:
384: $item->getOriginalPrice();
385: $item->setCustomPrice($price);
386: $item->setBaseCustomPrice($basePrice);
387: }
388: $item->setPrice($basePrice);
389: $item->setBasePrice($basePrice);
390: $item->setRowTotal($subtotal);
391: $item->setBaseRowTotal($baseSubtotal);
392: $item->setPriceInclTax($taxPrice);
393: $item->setBasePriceInclTax($baseTaxPrice);
394: $item->setRowTotalInclTax($taxSubtotal);
395: $item->setBaseRowTotalInclTax($baseTaxSubtotal);
396: $item->setTaxableAmount($taxable);
397: $item->setBaseTaxableAmount($baseTaxable);
398: $item->setIsPriceInclTax($isPriceInclTax);
399: if ($this->_config->discountTax($this->_store)) {
400: $item->setDiscountCalculationPrice($taxSubtotal/$qty);
401: $item->setBaseDiscountCalculationPrice($baseTaxSubtotal/$qty);
402: } elseif ($isPriceInclTax) {
403: $item->setDiscountCalculationPrice($subtotal/$qty);
404: $item->setBaseDiscountCalculationPrice($baseSubtotal/$qty);
405: }
406:
407: return $this;
408: }
409:
410: 411: 412: 413: 414: 415: 416:
417: protected function _totalBaseCalculation($item, $request)
418: {
419: $calc = $this->_calculator;
420: $request->setProductClassId($item->getProduct()->getTaxClassId());
421: $rate = $calc->getRate($request);
422: $qty = $item->getTotalQty();
423:
424: $price = $taxPrice = $item->getCalculationPriceOriginal();
425: $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
426: $subtotal = $taxSubtotal = $item->getRowTotal();
427: $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
428:
429: $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
430: if ($taxOnOrigPrice) {
431: $origSubtotal = $item->getOriginalPrice() * $qty;
432: $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty;
433: }
434: $item->setTaxPercent($rate);
435: if ($this->_config->priceIncludesTax($this->_store)) {
436: if ($this->_sameRateAsStore($request)) {
437: if ($taxOnOrigPrice) {
438: $rowTax =
439: $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, true, false), $rate, true);
440: $baseRowTax =
441: $this->_deltaRound(
442: $calc->calcTaxAmount($baseOrigSubtotal, $rate, true, false), $rate, true, 'base'
443: );
444:
445: $taxable = $origSubtotal;
446: $baseTaxable = $baseOrigSubtotal;
447: } else {
448: $rowTax =
449: $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, true, false), $rate, true);
450: $baseRowTax =
451: $this->_deltaRound(
452: $calc->calcTaxAmount($baseSubtotal, $rate, true, false), $rate, true, 'base'
453: );
454:
455: $taxable = $subtotal;
456: $baseTaxable = $baseSubtotal;
457: }
458: $taxPrice = $price;
459: $baseTaxPrice = $basePrice;
460:
461: $taxSubtotal = $subtotal;
462: $baseTaxSubtotal= $baseSubtotal;
463:
464: $subtotal = $subtotal - $rowTax;
465: $baseSubtotal = $baseSubtotal - $baseRowTax;
466:
467: $price = $calc->round($subtotal/$qty);
468: $basePrice = $calc->round($baseSubtotal/$qty);
469:
470: $isPriceInclTax = true;
471: } else {
472: $storeRate = $calc->getStoreRate($request, $this->_store);
473: if ($taxOnOrigPrice) {
474: $storeTax = $calc->calcTaxAmount($origSubtotal, $storeRate, true, false);
475: $baseStoreTax = $calc->calcTaxAmount($baseOrigSubtotal, $storeRate, true, false);
476: } else {
477: $storeTax = $calc->calcTaxAmount($subtotal, $storeRate, true, false);
478: $baseStoreTax = $calc->calcTaxAmount($baseSubtotal, $storeRate, true, false);
479: }
480: $subtotal = $calc->round($subtotal - $storeTax);
481: $baseSubtotal = $calc->round($baseSubtotal - $baseStoreTax);
482:
483: $price = $calc->round($subtotal/$qty);
484: $basePrice = $calc->round($baseSubtotal/$qty);
485:
486: $rowTax =
487: $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true);
488: $baseRowTax =
489: $this->_deltaRound(
490: $calc->calcTaxAmount($baseSubtotal, $rate, false, false), $rate, true, 'base'
491: );
492:
493: $taxSubtotal = $subtotal + $rowTax;
494: $baseTaxSubtotal= $baseSubtotal + $baseRowTax;
495:
496: $taxPrice = $calc->round($taxSubtotal/$qty);
497: $baseTaxPrice = $calc->round($baseTaxSubtotal/$qty);
498:
499: $taxable = $subtotal;
500: $baseTaxable = $baseSubtotal;
501:
502: $isPriceInclTax = false;
503: }
504: } else {
505: if ($taxOnOrigPrice) {
506: $rowTax =
507: $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, false, false), $rate, true);
508: $baseRowTax =
509: $this->_deltaRound(
510: $calc->calcTaxAmount($baseOrigSubtotal, $rate, false, false), $rate, true, 'base'
511: );
512:
513: $taxable = $origSubtotal;
514: $baseTaxable = $baseOrigSubtotal;
515: } else {
516: $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true);
517: $baseRowTax =
518: $this->_deltaRound($calc->calcTaxAmount($baseSubtotal, $rate, false, false), $rate, true, 'base');
519:
520: $taxable = $subtotal;
521: $baseTaxable = $baseSubtotal;
522: }
523:
524: $taxSubtotal = $subtotal + $rowTax;
525: $baseTaxSubtotal= $baseSubtotal + $baseRowTax;
526:
527: $taxPrice = $calc->round($taxSubtotal/$qty);
528: $baseTaxPrice = $calc->round($baseTaxSubtotal/$qty);
529:
530: $isPriceInclTax = false;
531: }
532:
533: if ($item->hasCustomPrice()) {
534: 535: 536:
537: $item->getOriginalPrice();
538: $item->setCustomPrice($price);
539: $item->setBaseCustomPrice($basePrice);
540: } else {
541: $item->setConvertedPrice($price);
542: }
543: $item->setPrice($basePrice);
544: $item->setBasePrice($basePrice);
545: $item->setRowTotal($subtotal);
546: $item->setBaseRowTotal($baseSubtotal);
547: $item->setPriceInclTax($taxPrice);
548: $item->setBasePriceInclTax($baseTaxPrice);
549: $item->setRowTotalInclTax($taxSubtotal);
550: $item->setBaseRowTotalInclTax($baseTaxSubtotal);
551: $item->setTaxableAmount($taxable);
552: $item->setBaseTaxableAmount($baseTaxable);
553: $item->setIsPriceInclTax($isPriceInclTax);
554: if ($this->_config->discountTax($this->_store)) {
555: $item->setDiscountCalculationPrice($taxSubtotal/$qty);
556: $item->setBaseDiscountCalculationPrice($baseTaxSubtotal/$qty);
557: } elseif ($isPriceInclTax) {
558: $item->setDiscountCalculationPrice($subtotal/$qty);
559: $item->setBaseDiscountCalculationPrice($baseSubtotal/$qty);
560: }
561: return $this;
562: }
563:
564: 565: 566: 567: 568: 569: 570: 571:
572: protected function _sameRateAsStore($request)
573: {
574:
575: if ($this->_areTaxRequestsSimilar) {
576: return true;
577: }
578:
579:
580: $rate = $this->_calculator->getRate($request);
581: $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
582: return $rate == $storeRate;
583: }
584:
585: 586: 587: 588: 589: 590: 591: 592: 593:
594: protected function _deltaRound($price, $rate, $direction, $type='regular')
595: {
596: if ($price) {
597: $rate = (string) $rate;
598: $type = $type . $direction;
599: $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0;
600: $price += $delta;
601: $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
602: $price = $this->_calculator->round($price);
603: }
604: return $price;
605: }
606:
607: 608: 609: 610: 611: 612:
613: protected function _recalculateParent(Mage_Sales_Model_Quote_Item_Abstract $item)
614: {
615: $price = 0;
616: $basePrice = 0;
617: $rowTotal = 0;
618: $baseRowTotal= 0;
619: $priceInclTax = 0;
620: $basePriceInclTax = 0;
621: $rowTotalInclTax = 0;
622: $baseRowTotalInclTax= 0;
623: foreach ($item->getChildren() as $child) {
624: $price += $child->getPrice() * $child->getQty();
625: $basePrice += $child->getBasePrice() * $child->getQty();
626: $rowTotal += $child->getRowTotal();
627: $baseRowTotal += $child->getBaseRowTotal();
628: $priceInclTax += $child->getPriceInclTax() * $child->getQty();
629: $basePriceInclTax += $child->getBasePriceInclTax() * $child->getQty();
630: $rowTotalInclTax += $child->getRowTotalInclTax();
631: $baseRowTotalInclTax+= $child->getBaseRowTotalInclTax();
632: }
633: $item->setConvertedPrice($price);
634: $item->setPrice($basePrice);
635: $item->setRowTotal($rowTotal);
636: $item->setBaseRowTotal($baseRowTotal);
637: $item->setPriceInclTax($priceInclTax);
638: $item->setBasePriceInclTax($basePriceInclTax);
639: $item->setRowTotalInclTax($rowTotalInclTax);
640: $item->setBaseRowTotalInclTax($baseRowTotalInclTax);
641: return $this;
642: }
643:
644: 645: 646: 647: 648: 649:
650: protected function _getStoreTaxRequest($address)
651: {
652: if (is_null($this->_storeTaxRequest)) {
653: $this->_storeTaxRequest = $this->_calculator->getRateOriginRequest($address->getQuote()->getStore());
654: }
655: return $this->_storeTaxRequest;
656: }
657:
658: 659: 660: 661: 662: 663:
664: protected function _getAddressTaxRequest($address)
665: {
666: $addressTaxRequest = $this->_calculator->getRateRequest(
667: $address,
668: $address->getQuote()->getBillingAddress(),
669: $address->getQuote()->getCustomerTaxClassId(),
670: $address->getQuote()->getStore()
671: );
672: return $addressTaxRequest;
673: }
674:
675: 676: 677: 678: 679: 680: 681:
682: protected function _addSubtotalAmount(Mage_Sales_Model_Quote_Address $address, $item)
683: {
684: $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal')+$item->getRowTotal());
685: $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal')+$item->getBaseRowTotal());
686: $address->setSubtotalInclTax($address->getSubtotalInclTax()+$item->getRowTotalInclTax());
687: $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax()+$item->getBaseRowTotalInclTax());
688: return $this;
689: }
690:
691:
692:
693:
694:
695:
696:
697:
698:
699:
700:
701:
702:
703:
704: 705: 706: 707: 708: 709: 710: 711:
712: protected function _resetItemPriceInclTax(Mage_Sales_Model_Quote_Item_Abstract $item)
713: {
714: $item->setPriceInclTax(null);
715: $item->setBasePriceInclTax(null);
716: $item->setRowTotalInclTax(null);
717: $item->setBaseRowTotalInclTax(null);
718: return $this;
719: }
720:
721: 722: 723: 724: 725: 726:
727: protected function _processShippingAmount($address)
728: {
729: return $this;
730: }
731:
732: 733: 734: 735: 736: 737: 738:
739: protected function _recollectItem($address, Mage_Sales_Model_Quote_Item_Abstract $item)
740: {
741: $store = $address->getQuote()->getStore();
742: $request = $this->_getStoreTaxRequest($address);
743: $request->setProductClassId($item->getProduct()->getTaxClassId());
744: $rate = $this->_calculator->getRate($request);
745: $qty = $item->getTotalQty();
746:
747: $price = $taxPrice = $item->getCalculationPriceOriginal();
748: $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
749: $subtotal = $taxSubtotal = $item->getRowTotal();
750: $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
751:
752: if ($this->_config->discountTax($store)) {
753: $item->setDiscountCalculationPrice($price);
754: $item->setBaseDiscountCalculationPrice($basePrice);
755: }
756:
757: 758: 759:
760: if ($item->hasCustomPrice() && !$this->_helper->applyTaxOnCustomPrice($store)) {
761: $taxPrice = $item->getOriginalPrice();
762: $baseTaxPrice = $item->getBaseOriginalPrice();
763: $taxSubtotal = $taxPrice*$qty;
764: $baseTaxSubtotal = $baseTaxPrice*$qty;
765: }
766:
767: if ($this->_areTaxRequestsSimilar) {
768: $item->setRowTotalInclTax($subtotal);
769: $item->setBaseRowTotalInclTax($baseSubtotal);
770: $item->setPriceInclTax($price);
771: $item->setBasePriceInclTax($basePrice);
772:
773: $item->setTaxCalcPrice($taxPrice);
774: $item->setBaseTaxCalcPrice($baseTaxPrice);
775: $item->setTaxCalcRowTotal($taxSubtotal);
776: $item->setBaseTaxCalcRowTotal($baseTaxSubtotal);
777: }
778:
779: $this->_subtotalInclTax += $subtotal;
780: $this->_baseSubtotalInclTax += $baseSubtotal;
781:
782: if ($this->_config->getAlgorithm($store) == Mage_Tax_Model_Calculation::CALC_UNIT_BASE) {
783: $taxAmount = $this->_calculator->calcTaxAmount($taxPrice, $rate, true);
784: $baseTaxAmount = $this->_calculator->calcTaxAmount($baseTaxPrice, $rate, true);
785: $unitPrice = $this->_calculator->round($price-$taxAmount);
786: $baseUnitPrice = $this->_calculator->round($basePrice-$baseTaxAmount);
787: $subtotal = $this->_calculator->round($unitPrice*$qty);
788: $baseSubtotal = $this->_calculator->round($baseUnitPrice*$qty);
789: } else {
790: $taxAmount = $this->_calculator->calcTaxAmount($taxSubtotal, $rate, true, false);
791: $baseTaxAmount = $this->_calculator->calcTaxAmount($baseTaxSubtotal, $rate, true, false);
792: $unitPrice = ($subtotal-$taxAmount)/$qty;
793: $baseUnitPrice = ($baseSubtotal-$baseTaxAmount)/$qty;
794: $subtotal = $this->_calculator->round(($subtotal-$taxAmount));
795: $baseSubtotal = $this->_calculator->round(($baseSubtotal-$baseTaxAmount));
796: }
797:
798: if ($item->hasCustomPrice()) {
799: $item->setCustomPrice($unitPrice);
800: $item->setBaseCustomPrice($baseUnitPrice);
801: }
802: $item->setPrice($baseUnitPrice);
803: $item->setOriginalPrice($unitPrice);
804: $item->setBasePrice($baseUnitPrice);
805: $item->setRowTotal($subtotal);
806: $item->setBaseRowTotal($baseSubtotal);
807: return $this;
808: }
809:
810: 811: 812: 813: 814: 815: 816:
817: protected function _needSubtractTax($address)
818: {
819: $store = $address->getQuote()->getStore();
820: if ($this->_config->priceIncludesTax($store) || $this->_config->getNeedUsePriceExcludeTax()) {
821: return true;
822: }
823: return false;
824: }
825:
826: 827: 828: 829: 830: 831:
832: protected function _needSubtractShippingTax($address)
833: {
834: $store = $address->getQuote()->getStore();
835: if ($this->_config->shippingPriceIncludesTax($store) || $this->_config->getNeedUseShippingExcludeTax()) {
836: return true;
837: }
838: return false;
839: }
840: }
841: