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: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
41: abstract class Mage_Sales_Model_Quote_Item_Abstract extends Mage_Core_Model_Abstract
42: implements Mage_Catalog_Model_Product_Configuration_Item_Interface
43: {
44: protected $_parentItem = null;
45: protected $_children = array();
46: protected $_messages = array();
47:
48: 49: 50: 51: 52:
53: abstract function getQuote();
54:
55: 56: 57: 58: 59:
60: public function getProduct()
61: {
62: $product = $this->_getData('product');
63: if (($product === null) && $this->getProductId()) {
64: $product = Mage::getModel('catalog/product')
65: ->setStoreId($this->getQuote()->getStoreId())
66: ->load($this->getProductId());
67: $this->setProduct($product);
68: }
69:
70: 71: 72:
73: $product->setFinalPrice(null);
74: if (is_array($this->_optionsByCode)) {
75: $product->setCustomOptions($this->_optionsByCode);
76: }
77: return $product;
78: }
79:
80: 81: 82: 83: 84: 85: 86:
87: public function getFileDownloadParams()
88: {
89: return null;
90: }
91:
92: 93: 94: 95: 96:
97: protected function _beforeSave()
98: {
99: parent::_beforeSave();
100: if ($this->getParentItem()) {
101: $this->setParentItemId($this->getParentItem()->getId());
102: }
103: return $this;
104: }
105:
106:
107: 108: 109: 110: 111: 112:
113: public function setParentItem($parentItem)
114: {
115: if ($parentItem) {
116: $this->_parentItem = $parentItem;
117: $parentItem->addChild($this);
118: }
119: return $this;
120: }
121:
122: 123: 124: 125: 126:
127: public function getParentItem()
128: {
129: return $this->_parentItem;
130: }
131:
132: 133: 134: 135: 136:
137: public function getChildren()
138: {
139: return $this->_children;
140: }
141:
142: 143: 144: 145: 146: 147:
148: public function addChild($child)
149: {
150: $this->setHasChildren(true);
151: $this->_children[] = $child;
152: return $this;
153: }
154:
155: 156: 157: 158: 159: 160:
161: public function setMessage($messages)
162: {
163: $messagesExists = $this->getMessage(false);
164: if (!is_array($messages)) {
165: $messages = array($messages);
166: }
167: foreach ($messages as $message) {
168: if (!in_array($message, $messagesExists)) {
169: $this->addMessage($message);
170: }
171: }
172: return $this;
173: }
174:
175: 176: 177: 178: 179: 180:
181: public function addMessage($message)
182: {
183: $this->_messages[] = $message;
184: return $this;
185: }
186:
187: 188: 189: 190: 191: 192:
193: public function getMessage($string = true)
194: {
195: if ($string) {
196: return join("\n", $this->_messages);
197: }
198: return $this->_messages;
199: }
200:
201: 202: 203: 204: 205: 206:
207: public function removeMessageByText($text)
208: {
209: foreach ($this->_messages as $key => $message) {
210: if ($message == $text) {
211: unset($this->_messages[$key]);
212: }
213: }
214: return $this;
215: }
216:
217: 218: 219: 220: 221:
222: public function clearMessage()
223: {
224: $this->unsMessage();
225: $this->_messages = array();
226: return $this;
227: }
228:
229: 230: 231: 232: 233:
234: public function getStore()
235: {
236: return $this->getQuote()->getStore();
237: }
238:
239: 240: 241: 242: 243:
244: public function checkData()
245: {
246: $this->setHasError(false);
247: $this->clearMessage();
248:
249: $qty = $this->_getData('qty');
250:
251: try {
252: $this->setQty($qty);
253: } catch (Mage_Core_Exception $e){
254: $this->setHasError(true);
255: $this->setMessage($e->getMessage());
256: } catch (Exception $e){
257: $this->setHasError(true);
258: $this->setMessage(Mage::helper('sales')->__('Item qty declaration error.'));
259: }
260:
261: try {
262: $this->getProduct()->getTypeInstance(true)->checkProductBuyState($this->getProduct());
263: } catch (Mage_Core_Exception $e) {
264: $this->setHasError(true);
265: $this->setMessage($e->getMessage());
266: $this->getQuote()->setHasError(true);
267: $this->getQuote()->addMessage(
268: Mage::helper('sales')->__('Some of the products below do not have all the required options. Please edit them and configure all the required options.')
269: );
270: } catch (Exception $e) {
271: $this->setHasError(true);
272: $this->setMessage(Mage::helper('sales')->__('Item options declaration error.'));
273: $this->getQuote()->setHasError(true);
274: $this->getQuote()->addMessage(Mage::helper('sales')->__('Items options declaration error.'));
275: }
276:
277: return $this;
278: }
279:
280: 281: 282: 283: 284:
285: public function getQty()
286: {
287: return $this->_getData('qty');
288: }
289:
290: 291: 292: 293: 294:
295: public function getTotalQty()
296: {
297: if ($this->getParentItem()) {
298: return $this->getQty()*$this->getParentItem()->getQty();
299: }
300: return $this->getQty();
301: }
302:
303: 304: 305: 306: 307:
308: public function calcRowTotal()
309: {
310: $qty = $this->getTotalQty();
311:
312: $total = $this->getStore()->roundPrice($this->getCalculationPriceOriginal()) * $qty;
313: $baseTotal = $this->getBaseCalculationPriceOriginal() * $qty;
314:
315: $this->setRowTotal($this->getStore()->roundPrice($total));
316: $this->setBaseRowTotal($this->getStore()->roundPrice($baseTotal));
317: return $this;
318: }
319:
320: 321: 322: 323: 324: 325:
326: public function getCalculationPrice()
327: {
328: $price = $this->_getData('calculation_price');
329: if (is_null($price)) {
330: if ($this->hasCustomPrice()) {
331: $price = $this->getCustomPrice();
332: } else {
333: $price = $this->getConvertedPrice();
334: }
335: $this->setData('calculation_price', $price);
336: }
337: return $price;
338: }
339:
340: 341: 342: 343: 344: 345:
346: public function getCalculationPriceOriginal()
347: {
348: $price = $this->_getData('calculation_price');
349: if (is_null($price)) {
350: if ($this->hasOriginalCustomPrice()) {
351: $price = $this->getOriginalCustomPrice();
352: } else {
353: $price = $this->getConvertedPrice();
354: }
355: $this->setData('calculation_price', $price);
356: }
357: return $price;
358: }
359:
360: 361: 362: 363: 364:
365: public function getBaseCalculationPrice()
366: {
367: if (!$this->hasBaseCalculationPrice()) {
368: if ($this->hasCustomPrice()) {
369: $price = (float) $this->getCustomPrice();
370: if ($price) {
371: $rate = $this->getStore()->convertPrice($price) / $price;
372: $price = $price / $rate;
373: }
374: } else {
375: $price = $this->getPrice();
376: }
377: $this->setBaseCalculationPrice($price);
378: }
379: return $this->_getData('base_calculation_price');
380: }
381:
382: 383: 384: 385: 386:
387: public function getBaseCalculationPriceOriginal()
388: {
389: if (!$this->hasBaseCalculationPrice()) {
390: if ($this->hasOriginalCustomPrice()) {
391: $price = (float) $this->getOriginalCustomPrice();
392: if ($price) {
393: $rate = $this->getStore()->convertPrice($price) / $price;
394: $price = $price / $rate;
395: }
396: } else {
397: $price = $this->getPrice();
398: }
399: $this->setBaseCalculationPrice($price);
400: }
401: return $this->_getData('base_calculation_price');
402: }
403:
404: 405: 406: 407: 408: 409:
410: public function isNominal()
411: {
412: if (!$this->hasData('is_nominal')) {
413: $this->setData('is_nominal', $this->getProduct() ? '1' == $this->getProduct()->getIsRecurring() : false);
414: }
415: return $this->_getData('is_nominal');
416: }
417:
418: 419: 420: 421: 422: 423:
424: public function getIsNominal()
425: {
426: return (int)$this->isNominal();
427: }
428:
429: 430: 431: 432: 433: 434:
435: public function getOriginalPrice()
436: {
437: $price = $this->_getData('original_price');
438: if (is_null($price)) {
439: $price = $this->getStore()->convertPrice($this->getBaseOriginalPrice());
440: $this->setData('original_price', $price);
441: }
442: return $price;
443: }
444:
445: 446: 447: 448: 449: 450:
451: public function setOriginalPrice($price)
452: {
453: return $this->setData('original_price', $price);
454: }
455:
456: 457: 458: 459: 460:
461: public function getBaseOriginalPrice()
462: {
463: return $this->_getData('base_original_price');
464: }
465:
466: 467: 468: 469: 470: 471:
472: public function setCustomPrice($value)
473: {
474: $this->setCalculationPrice($value);
475: $this->setBaseCalculationPrice(null);
476: return $this->setData('custom_price', $value);
477: }
478:
479: 480: 481: 482: 483:
484: public function getPrice()
485: {
486: return $this->_getData('price');
487: }
488:
489: 490: 491: 492: 493: 494:
495: public function setPrice($value)
496: {
497: $this->setBaseCalculationPrice(null);
498: $this->setConvertedPrice(null);
499: return $this->setData('price', $value);
500: }
501:
502: 503: 504: 505:
506: public function getConvertedPrice()
507: {
508: $price = $this->_getData('converted_price');
509: if (is_null($price)) {
510: $price = $this->getStore()->convertPrice($this->getPrice());
511: $this->setData('converted_price', $price);
512: }
513: return $price;
514: }
515:
516: 517: 518: 519: 520:
521: public function setConvertedPrice($value)
522: {
523: $this->setCalculationPrice(null);
524: $this->setData('converted_price', $value);
525: return $this;
526: }
527:
528: 529: 530: 531: 532:
533: public function __clone()
534: {
535: $this->setId(null);
536: $this->_parentItem = null;
537: $this->_children = array();
538: $this->_messages = array();
539: return $this;
540: }
541:
542: 543: 544: 545: 546: 547:
548: public function isChildrenCalculated()
549: {
550: if ($this->getParentItem()) {
551: $calculate = $this->getParentItem()->getProduct()->getPriceType();
552: } else {
553: $calculate = $this->getProduct()->getPriceType();
554: }
555:
556: if ((null !== $calculate) && (int)$calculate === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
557: return true;
558: }
559: return false;
560: }
561:
562: 563: 564: 565: 566: 567:
568: public function isShipSeparately()
569: {
570: if ($this->getParentItem()) {
571: $shipmentType = $this->getParentItem()->getProduct()->getShipmentType();
572: } else {
573: $shipmentType = $this->getProduct()->getShipmentType();
574: }
575:
576: if ((null !== $shipmentType) &&
577: (int)$shipmentType === Mage_Catalog_Model_Product_Type_Abstract::SHIPMENT_SEPARATELY) {
578: return true;
579: }
580: return false;
581: }
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603: 604: 605: 606: 607: 608:
609: public function calcTaxAmount()
610: {
611: $store = $this->getStore();
612:
613: if (!Mage::helper('tax')->priceIncludesTax($store)) {
614: if (Mage::helper('tax')->applyTaxAfterDiscount($store)) {
615: $rowTotal = $this->getRowTotalWithDiscount();
616: $rowBaseTotal = $this->getBaseRowTotalWithDiscount();
617: } else {
618: $rowTotal = $this->getRowTotal();
619: $rowBaseTotal = $this->getBaseRowTotal();
620: }
621:
622: $taxPercent = $this->getTaxPercent()/100;
623:
624: $this->setTaxAmount($store->roundPrice($rowTotal * $taxPercent));
625: $this->setBaseTaxAmount($store->roundPrice($rowBaseTotal * $taxPercent));
626:
627: $rowTotal = $this->getRowTotal();
628: $rowBaseTotal = $this->getBaseRowTotal();
629: $this->setTaxBeforeDiscount($store->roundPrice($rowTotal * $taxPercent));
630: $this->setBaseTaxBeforeDiscount($store->roundPrice($rowBaseTotal * $taxPercent));
631: } else {
632: if (Mage::helper('tax')->applyTaxAfterDiscount($store)) {
633: $totalBaseTax = $this->getBaseTaxAmount();
634: $totalTax = $this->getTaxAmount();
635:
636: if ($totalTax && $totalBaseTax) {
637: $totalTax -= $this->getDiscountAmount()*($this->getTaxPercent()/100);
638: $totalBaseTax -= $this->getBaseDiscountAmount()*($this->getTaxPercent()/100);
639:
640: $this->setBaseTaxAmount($store->roundPrice($totalBaseTax));
641: $this->setTaxAmount($store->roundPrice($totalTax));
642: }
643: }
644: }
645:
646: if (Mage::helper('tax')->discountTax($store) && !Mage::helper('tax')->applyTaxAfterDiscount($store)) {
647: if ($this->getDiscountPercent()) {
648: $baseTaxAmount = $this->getBaseTaxBeforeDiscount();
649: $taxAmount = $this->getTaxBeforeDiscount();
650:
651: $baseDiscountDisposition = $baseTaxAmount/100*$this->getDiscountPercent();
652: $discountDisposition = $taxAmount/100*$this->getDiscountPercent();
653:
654: $this->setDiscountAmount($this->getDiscountAmount()+$discountDisposition);
655: $this->setBaseDiscountAmount($this->getBaseDiscountAmount()+$baseDiscountDisposition);
656: }
657: }
658:
659: return $this;
660: }
661:
662: 663: 664: 665: 666: 667:
668: public function getTaxAmount()
669: {
670: return $this->_getData('tax_amount');
671: }
672:
673:
674: 675: 676: 677: 678: 679:
680: public function getBaseTaxAmount()
681: {
682: return $this->_getData('base_tax_amount');
683: }
684:
685: 686: 687: 688: 689: 690:
691: protected function _calculatePrice($value, $saveTaxes = true)
692: {
693: $store = $this->getQuote()->getStore();
694:
695: if (Mage::helper('tax')->priceIncludesTax($store)) {
696: $bAddress = $this->getQuote()->getBillingAddress();
697: $sAddress = $this->getQuote()->getShippingAddress();
698:
699: $address = $this->getAddress();
700:
701: if ($address) {
702: switch ($address->getAddressType()) {
703: case Mage_Sales_Model_Quote_Address::TYPE_BILLING:
704: $bAddress = $address;
705: break;
706: case Mage_Sales_Model_Quote_Address::TYPE_SHIPPING:
707: $sAddress = $address;
708: break;
709: }
710: }
711:
712: if ($this->getProduct()->getIsVirtual()) {
713: $sAddress = $bAddress;
714: }
715:
716: $priceExcludingTax = Mage::helper('tax')->getPrice(
717: $this->getProduct()->setTaxPercent(null),
718: $value,
719: false,
720: $sAddress,
721: $bAddress,
722: $this->getQuote()->getCustomerTaxClassId(),
723: $store
724: );
725:
726: $priceIncludingTax = Mage::helper('tax')->getPrice(
727: $this->getProduct()->setTaxPercent(null),
728: $value,
729: true,
730: $sAddress,
731: $bAddress,
732: $this->getQuote()->getCustomerTaxClassId(),
733: $store
734: );
735:
736: if ($saveTaxes) {
737: $qty = $this->getQty();
738: if ($this->getParentItem()) {
739: $qty = $qty*$this->getParentItem()->getQty();
740: }
741:
742: if (Mage::helper('tax')->displayCartPriceInclTax($store)) {
743: $rowTotal = $value*$qty;
744: $rowTotalExcTax = Mage::helper('tax')->getPrice(
745: $this->getProduct()->setTaxPercent(null),
746: $rowTotal,
747: false,
748: $sAddress,
749: $bAddress,
750: $this->getQuote()->getCustomerTaxClassId(),
751: $store
752: );
753: $rowTotalIncTax = Mage::helper('tax')->getPrice(
754: $this->getProduct()->setTaxPercent(null),
755: $rowTotal,
756: true,
757: $sAddress,
758: $bAddress,
759: $this->getQuote()->getCustomerTaxClassId(),
760: $store
761: );
762: $totalBaseTax = $rowTotalIncTax-$rowTotalExcTax;
763: $this->setRowTotalExcTax($rowTotalExcTax);
764: }
765: else {
766: $taxAmount = $priceIncludingTax - $priceExcludingTax;
767: $this->setTaxPercent($this->getProduct()->getTaxPercent());
768: $totalBaseTax = $taxAmount*$qty;
769: }
770:
771: $totalTax = $this->getStore()->convertPrice($totalBaseTax);
772: $this->setTaxBeforeDiscount($totalTax);
773: $this->setBaseTaxBeforeDiscount($totalBaseTax);
774:
775: $this->setTaxAmount($totalTax);
776: $this->setBaseTaxAmount($totalBaseTax);
777: }
778:
779: $value = $priceExcludingTax;
780: }
781:
782: return $value;
783: }
784: }
785: