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: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128:
129: class Mage_Sales_Model_Order_Creditmemo extends Mage_Sales_Model_Abstract
130: {
131: const STATE_OPEN = 1;
132: const STATE_REFUNDED = 2;
133: const STATE_CANCELED = 3;
134:
135: const XML_PATH_EMAIL_TEMPLATE = 'sales_email/creditmemo/template';
136: const XML_PATH_EMAIL_GUEST_TEMPLATE = 'sales_email/creditmemo/guest_template';
137: const XML_PATH_EMAIL_IDENTITY = 'sales_email/creditmemo/identity';
138: const XML_PATH_EMAIL_COPY_TO = 'sales_email/creditmemo/copy_to';
139: const XML_PATH_EMAIL_COPY_METHOD = 'sales_email/creditmemo/copy_method';
140: const XML_PATH_EMAIL_ENABLED = 'sales_email/creditmemo/enabled';
141:
142: const XML_PATH_UPDATE_EMAIL_TEMPLATE = 'sales_email/creditmemo_comment/template';
143: const XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE = 'sales_email/creditmemo_comment/guest_template';
144: const XML_PATH_UPDATE_EMAIL_IDENTITY = 'sales_email/creditmemo_comment/identity';
145: const XML_PATH_UPDATE_EMAIL_COPY_TO = 'sales_email/creditmemo_comment/copy_to';
146: const XML_PATH_UPDATE_EMAIL_COPY_METHOD = 'sales_email/creditmemo_comment/copy_method';
147: const XML_PATH_UPDATE_EMAIL_ENABLED = 'sales_email/creditmemo_comment/enabled';
148:
149: const REPORT_DATE_TYPE_ORDER_CREATED = 'order_created';
150: const REPORT_DATE_TYPE_REFUND_CREATED = 'refund_created';
151:
152: 153: 154:
155: const HISTORY_ENTITY_NAME = 'creditmemo';
156:
157: protected static $_states;
158:
159: protected $_items;
160: protected $_order;
161: protected ;
162:
163: 164: 165: 166: 167:
168: protected $_calculators = array();
169:
170: protected $_eventPrefix = 'sales_order_creditmemo';
171: protected $_eventObject = 'creditmemo';
172:
173: 174: 175:
176: protected function _construct()
177: {
178: $this->_init('sales/order_creditmemo');
179: }
180:
181: 182: 183: 184: 185:
186: protected function _initOldFieldsMap()
187: {
188: $this->_oldFieldsMap = Mage::helper('sales')->getOldFieldMap('order_creditmemo');
189: return $this;
190: }
191:
192: 193: 194: 195: 196:
197: public function getConfig()
198: {
199: return Mage::getSingleton('sales/order_creditmemo_config');
200: }
201:
202: 203: 204: 205: 206:
207: public function getStore()
208: {
209: return $this->getOrder()->getStore();
210: }
211:
212: 213: 214: 215: 216: 217:
218: public function setOrder(Mage_Sales_Model_Order $order)
219: {
220: $this->_order = $order;
221: $this->setOrderId($order->getId())
222: ->setStoreId($order->getStoreId());
223: return $this;
224: }
225:
226: 227: 228: 229: 230:
231: public function getOrder()
232: {
233: if (!$this->_order instanceof Mage_Sales_Model_Order) {
234: $this->_order = Mage::getModel('sales/order')->load($this->getOrderId());
235: }
236: return $this->_order->setHistoryEntityName(self::HISTORY_ENTITY_NAME);
237: }
238:
239: 240: 241: 242: 243:
244: public function getBillingAddress()
245: {
246: return $this->getOrder()->getBillingAddress();
247: }
248:
249: 250: 251: 252: 253:
254: public function getShippingAddress()
255: {
256: return $this->getOrder()->getShippingAddress();
257: }
258:
259: public function getItemsCollection()
260: {
261: if (empty($this->_items)) {
262: $this->_items = Mage::getResourceModel('sales/order_creditmemo_item_collection')
263: ->setCreditmemoFilter($this->getId());
264:
265: if ($this->getId()) {
266: foreach ($this->_items as $item) {
267: $item->setCreditmemo($this);
268: }
269: }
270: }
271: return $this->_items;
272: }
273:
274: public function getAllItems()
275: {
276: $items = array();
277: foreach ($this->getItemsCollection() as $item) {
278: if (!$item->isDeleted()) {
279: $items[] = $item;
280: }
281: }
282: return $items;
283: }
284:
285: public function getItemById($itemId)
286: {
287: foreach ($this->getItemsCollection() as $item) {
288: if ($item->getId()==$itemId) {
289: return $item;
290: }
291: }
292: return false;
293: }
294:
295: 296: 297: 298: 299: 300:
301: public function getItemByOrderId($orderId)
302: {
303: foreach ($this->getItemsCollection() as $item) {
304: if ($item->getOrderItemId() == $orderId) {
305: return $item;
306: }
307: }
308: return false;
309: }
310:
311: public function addItem(Mage_Sales_Model_Order_Creditmemo_Item $item)
312: {
313: $item->setCreditmemo($this)
314: ->setParentId($this->getId())
315: ->setStoreId($this->getStoreId());
316: if (!$item->getId()) {
317: $this->getItemsCollection()->addItem($item);
318: }
319: return $this;
320: }
321:
322: 323: 324: 325: 326:
327: public function collectTotals()
328: {
329: foreach ($this->getConfig()->getTotalModels() as $model) {
330: $model->collect($this);
331: }
332: return $this;
333: }
334:
335: 336: 337: 338: 339: 340: 341: 342:
343: public function roundPrice($price, $type = 'regular', $negative = false)
344: {
345: if ($price) {
346: if (!isset($this->_calculators[$type])) {
347: $this->_calculators[$type] = Mage::getModel('core/calculator', $this->getStore());
348: }
349: $price = $this->_calculators[$type]->deltaRound($price, $negative);
350: }
351: return $price;
352: }
353:
354: public function canRefund()
355: {
356: if ($this->getState() != self::STATE_CANCELED
357: && $this->getState() != self::STATE_REFUNDED
358: && $this->getOrder()->getPayment()->canRefund()
359: ) {
360: return true;
361: }
362: return false;
363: }
364:
365: 366: 367: 368: 369:
370: public function canCancel()
371: {
372: return $this->getState() == self::STATE_OPEN;
373: }
374:
375: 376: 377: 378: 379:
380: public function canVoid()
381: {
382: $canVoid = false;
383: return false;
384: if ($this->getState() == self::STATE_REFUNDED) {
385: $canVoid = $this->getCanVoidFlag();
386: 387: 388:
389: if (is_null($canVoid)) {
390: $canVoid = $this->getOrder()->getPayment()->canVoid($this);
391: if ($canVoid === false) {
392: $this->setCanVoidFlag(false);
393: $this->_saveBeforeDestruct = true;
394: }
395: }
396: else {
397: $canVoid = (bool) $canVoid;
398: }
399: }
400: return $canVoid;
401: }
402:
403:
404: public function refund()
405: {
406: $this->setState(self::STATE_REFUNDED);
407: $orderRefund = Mage::app()->getStore()->roundPrice(
408: $this->getOrder()->getTotalRefunded()+$this->getGrandTotal()
409: );
410: $baseOrderRefund = Mage::app()->getStore()->roundPrice(
411: $this->getOrder()->getBaseTotalRefunded()+$this->getBaseGrandTotal()
412: );
413:
414: if ($baseOrderRefund > Mage::app()->getStore()->roundPrice($this->getOrder()->getBaseTotalPaid())) {
415:
416: $baseAvailableRefund = $this->getOrder()->getBaseTotalPaid()- $this->getOrder()->getBaseTotalRefunded();
417:
418: Mage::throwException(
419: Mage::helper('sales')->__('Maximum amount available to refund is %s', $this->getOrder()->formatBasePrice($baseAvailableRefund))
420: );
421: }
422: $order = $this->getOrder();
423: $order->setBaseTotalRefunded($baseOrderRefund);
424: $order->setTotalRefunded($orderRefund);
425:
426: $order->setBaseSubtotalRefunded($order->getBaseSubtotalRefunded()+$this->getBaseSubtotal());
427: $order->setSubtotalRefunded($order->getSubtotalRefunded()+$this->getSubtotal());
428:
429: $order->setBaseTaxRefunded($order->getBaseTaxRefunded()+$this->getBaseTaxAmount());
430: $order->setTaxRefunded($order->getTaxRefunded()+$this->getTaxAmount());
431: $order->setBaseHiddenTaxRefunded($order->getBaseHiddenTaxRefunded()+$this->getBaseHiddenTaxAmount());
432: $order->setHiddenTaxRefunded($order->getHiddenTaxRefunded()+$this->getHiddenTaxAmount());
433:
434: $order->setBaseShippingRefunded($order->getBaseShippingRefunded()+$this->getBaseShippingAmount());
435: $order->setShippingRefunded($order->getShippingRefunded()+$this->getShippingAmount());
436:
437: $order->setBaseShippingTaxRefunded($order->getBaseShippingTaxRefunded()+$this->getBaseShippingTaxAmount());
438: $order->setShippingTaxRefunded($order->getShippingTaxRefunded()+$this->getShippingTaxAmount());
439:
440: $order->setAdjustmentPositive($order->getAdjustmentPositive()+$this->getAdjustmentPositive());
441: $order->setBaseAdjustmentPositive($order->getBaseAdjustmentPositive()+$this->getBaseAdjustmentPositive());
442:
443: $order->setAdjustmentNegative($order->getAdjustmentNegative()+$this->getAdjustmentNegative());
444: $order->setBaseAdjustmentNegative($order->getBaseAdjustmentNegative()+$this->getBaseAdjustmentNegative());
445:
446: $order->setDiscountRefunded($order->getDiscountRefunded()+$this->getDiscountAmount());
447: $order->setBaseDiscountRefunded($order->getBaseDiscountRefunded()+$this->getBaseDiscountAmount());
448:
449: if ($this->getInvoice()) {
450: $this->getInvoice()->setIsUsedForRefund(true);
451: $this->getInvoice()->setBaseTotalRefunded(
452: $this->getInvoice()->getBaseTotalRefunded() + $this->getBaseGrandTotal()
453: );
454: $this->setInvoiceId($this->getInvoice()->getId());
455: }
456:
457: if (!$this->getPaymentRefundDisallowed()) {
458: $order->getPayment()->refund($this);
459: }
460:
461: Mage::dispatchEvent('sales_order_creditmemo_refund', array($this->_eventObject=>$this));
462: return $this;
463: }
464:
465: 466: 467: 468: 469:
470: public function cancel()
471: {
472: $this->setState(self::STATE_CANCELED);
473: foreach ($this->getAllItems() as $item) {
474: $item->cancel();
475: }
476: $this->getOrder()->getPayment()->cancelCreditmemo($this);
477:
478: if ($this->getTransactionId()) {
479: $this->getOrder()->setTotalOnlineRefunded(
480: $this->getOrder()->getTotalOnlineRefunded()-$this->getGrandTotal()
481: );
482: $this->getOrder()->setBaseTotalOnlineRefunded(
483: $this->getOrder()->getBaseTotalOnlineRefunded()-$this->getBaseGrandTotal()
484: );
485: }
486: else {
487: $this->getOrder()->setTotalOfflineRefunded(
488: $this->getOrder()->getTotalOfflineRefunded()-$this->getGrandTotal()
489: );
490: $this->getOrder()->setBaseTotalOfflineRefunded(
491: $this->getOrder()->getBaseTotalOfflineRefunded()-$this->getBaseGrandTotal()
492: );
493: }
494:
495: $this->getOrder()->setBaseSubtotalRefunded(
496: $this->getOrder()->getBaseSubtotalRefunded()-$this->getBaseSubtotal()
497: );
498: $this->getOrder()->setSubtotalRefunded($this->getOrder()->getSubtotalRefunded()-$this->getSubtotal());
499:
500: $this->getOrder()->setBaseTaxRefunded($this->getOrder()->getBaseTaxRefunded()-$this->getBaseTaxAmount());
501: $this->getOrder()->setTaxRefunded($this->getOrder()->getTaxRefunded()-$this->getTaxAmount());
502:
503: $this->getOrder()->setBaseShippingRefunded(
504: $this->getOrder()->getBaseShippingRefunded()-$this->getBaseShippingAmount()
505: );
506: $this->getOrder()->setShippingRefunded($this->getOrder()->getShippingRefunded()-$this->getShippingAmount());
507:
508: Mage::dispatchEvent('sales_order_creditmemo_cancel', array($this->_eventObject=>$this));
509: return $this;
510: }
511:
512: 513: 514: 515: 516: 517: 518:
519: public function register()
520: {
521: if ($this->getId()) {
522: Mage::throwException(
523: Mage::helper('sales')->__('Cannot register an existing credit memo.')
524: );
525: }
526:
527: foreach ($this->getAllItems() as $item) {
528: if ($item->getQty()>0) {
529: $item->register();
530: }
531: else {
532: $item->isDeleted(true);
533: }
534: }
535:
536: $this->setDoTransaction(true);
537: if ($this->getOfflineRequested()) {
538: $this->setDoTransaction(false);
539: }
540: $this->refund();
541:
542: if ($this->getDoTransaction()) {
543: $this->getOrder()->setTotalOnlineRefunded(
544: $this->getOrder()->getTotalOnlineRefunded()+$this->getGrandTotal()
545: );
546: $this->getOrder()->setBaseTotalOnlineRefunded(
547: $this->getOrder()->getBaseTotalOnlineRefunded()+$this->getBaseGrandTotal()
548: );
549: }
550: else {
551: $this->getOrder()->setTotalOfflineRefunded(
552: $this->getOrder()->getTotalOfflineRefunded()+$this->getGrandTotal()
553: );
554: $this->getOrder()->setBaseTotalOfflineRefunded(
555: $this->getOrder()->getBaseTotalOfflineRefunded()+$this->getBaseGrandTotal()
556: );
557: }
558:
559: $this->getOrder()->setBaseTotalInvoicedCost(
560: $this->getOrder()->getBaseTotalInvoicedCost()-$this->getBaseCost()
561: );
562:
563: $state = $this->getState();
564: if (is_null($state)) {
565: $this->setState(self::STATE_OPEN);
566: }
567: return $this;
568: }
569:
570: 571: 572: 573: 574:
575: public static function getStates()
576: {
577: if (is_null(self::$_states)) {
578: self::$_states = array(
579: self::STATE_OPEN => Mage::helper('sales')->__('Pending'),
580: self::STATE_REFUNDED => Mage::helper('sales')->__('Refunded'),
581: self::STATE_CANCELED => Mage::helper('sales')->__('Canceled'),
582: );
583: }
584: return self::$_states;
585: }
586:
587: 588: 589: 590: 591: 592:
593: public function getStateName($stateId = null)
594: {
595: if (is_null($stateId)) {
596: $stateId = $this->getState();
597: }
598:
599: if (is_null(self::$_states)) {
600: self::getStates();
601: }
602: if (isset(self::$_states[$stateId])) {
603: return self::$_states[$stateId];
604: }
605: return Mage::helper('sales')->__('Unknown State');
606: }
607:
608: public function setShippingAmount($amount)
609: {
610:
611:
612:
613:
614:
615:
616:
617: $this->setData('shipping_amount', $amount);
618: return $this;
619: }
620:
621:
622: public function setAdjustmentPositive($amount)
623: {
624: $amount = trim($amount);
625: if (substr($amount, -1) == '%') {
626: $amount = (float) substr($amount, 0, -1);
627: $amount = $this->getOrder()->getGrandTotal() * $amount / 100;
628: }
629:
630: $amount = $this->getStore()->roundPrice($amount);
631: $this->setData('base_adjustment_positive', $amount);
632:
633: $amount = $this->getStore()->roundPrice(
634: $amount*$this->getOrder()->getStoreToOrderRate()
635: );
636: $this->setData('adjustment_positive', $amount);
637: return $this;
638: }
639:
640: public function setAdjustmentNegative($amount)
641: {
642: $amount = trim($amount);
643: if (substr($amount, -1) == '%') {
644: $amount = (float) substr($amount, 0, -1);
645: $amount = $this->getOrder()->getGrandTotal() * $amount / 100;
646: }
647:
648: $amount = $this->getStore()->roundPrice($amount);
649: $this->setData('base_adjustment_negative', $amount);
650:
651: $amount = $this->getStore()->roundPrice(
652: $amount*$this->getOrder()->getStoreToOrderRate()
653: );
654: $this->setData('adjustment_negative', $amount);
655: return $this;
656: }
657:
658: 659: 660: 661: 662: 663: 664: 665: 666:
667: public function ($comment, $notify=false, $visibleOnFront=false)
668: {
669: if (!($comment instanceof Mage_Sales_Model_Order_Creditmemo_Comment)) {
670: $comment = Mage::getModel('sales/order_creditmemo_comment')
671: ->setComment($comment)
672: ->setIsCustomerNotified($notify)
673: ->setIsVisibleOnFront($visibleOnFront);
674: }
675: $comment->setCreditmemo($this)
676: ->setParentId($this->getId())
677: ->setStoreId($this->getStoreId());
678: if (!$comment->getId()) {
679: $this->getCommentsCollection()->addItem($comment);
680: }
681: $this->_hasDataChanges = true;
682: return $this;
683: }
684:
685: public function ($reload=false)
686: {
687: if (is_null($this->_comments) || $reload) {
688: $this->_comments = Mage::getResourceModel('sales/order_creditmemo_comment_collection')
689: ->setCreditmemoFilter($this->getId())
690: ->setCreatedAtOrder();
691: 692: 693: 694:
695: $this->_comments->load();
696:
697: if ($this->getId()) {
698: foreach ($this->_comments as $comment) {
699: $comment->setCreditmemo($this);
700: }
701: }
702: }
703: return $this->_comments;
704: }
705:
706:
707: 708: 709: 710: 711: 712: 713:
714: public function sendEmail($notifyCustomer = true, $comment = '')
715: {
716: $order = $this->getOrder();
717: $storeId = $order->getStore()->getId();
718:
719: if (!Mage::helper('sales')->canSendNewCreditmemoEmail($storeId)) {
720: return $this;
721: }
722:
723: $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
724: $copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $storeId);
725:
726: if (!$notifyCustomer && !$copyTo) {
727: return $this;
728: }
729:
730:
731: $appEmulation = Mage::getSingleton('core/app_emulation');
732: $initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($storeId);
733:
734: try {
735:
736: $paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
737: ->setIsSecureMode(true);
738: $paymentBlock->getMethod()->setStore($storeId);
739: $paymentBlockHtml = $paymentBlock->toHtml();
740: } catch (Exception $exception) {
741:
742: $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
743: throw $exception;
744: }
745:
746:
747: $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
748:
749:
750: if ($order->getCustomerIsGuest()) {
751: $templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $storeId);
752: $customerName = $order->getBillingAddress()->getName();
753: } else {
754: $templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $storeId);
755: $customerName = $order->getCustomerName();
756: }
757:
758: $mailer = Mage::getModel('core/email_template_mailer');
759: if ($notifyCustomer) {
760: $emailInfo = Mage::getModel('core/email_info');
761: $emailInfo->addTo($order->getCustomerEmail(), $customerName);
762: if ($copyTo && $copyMethod == 'bcc') {
763:
764: foreach ($copyTo as $email) {
765: $emailInfo->addBcc($email);
766: }
767: }
768: $mailer->addEmailInfo($emailInfo);
769: }
770:
771:
772: if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
773: foreach ($copyTo as $email) {
774: $emailInfo = Mage::getModel('core/email_info');
775: $emailInfo->addTo($email);
776: $mailer->addEmailInfo($emailInfo);
777: }
778: }
779:
780:
781: $mailer->setSender(Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId));
782: $mailer->setStoreId($storeId);
783: $mailer->setTemplateId($templateId);
784: $mailer->setTemplateParams(array(
785: 'order' => $order,
786: 'creditmemo' => $this,
787: 'comment' => $comment,
788: 'billing' => $order->getBillingAddress(),
789: 'payment_html' => $paymentBlockHtml
790: )
791: );
792: $mailer->send();
793: $this->setEmailSent(true);
794: $this->_getResource()->saveAttribute($this, 'email_sent');
795:
796: return $this;
797: }
798:
799: 800: 801: 802: 803: 804: 805:
806: public function sendUpdateEmail($notifyCustomer = true, $comment = '')
807: {
808: $order = $this->getOrder();
809: $storeId = $order->getStore()->getId();
810:
811: if (!Mage::helper('sales')->canSendCreditmemoCommentEmail($storeId)) {
812: return $this;
813: }
814:
815: $copyTo = $this->_getEmails(self::XML_PATH_UPDATE_EMAIL_COPY_TO);
816: $copyMethod = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_COPY_METHOD, $storeId);
817:
818: if (!$notifyCustomer && !$copyTo) {
819: return $this;
820: }
821:
822:
823: if ($order->getCustomerIsGuest()) {
824: $templateId = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE, $storeId);
825: $customerName = $order->getBillingAddress()->getName();
826: } else {
827: $templateId = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_TEMPLATE, $storeId);
828: $customerName = $order->getCustomerName();
829: }
830:
831: $mailer = Mage::getModel('core/email_template_mailer');
832: if ($notifyCustomer) {
833: $emailInfo = Mage::getModel('core/email_info');
834: $emailInfo->addTo($order->getCustomerEmail(), $customerName);
835: if ($copyTo && $copyMethod == 'bcc') {
836:
837: foreach ($copyTo as $email) {
838: $emailInfo->addBcc($email);
839: }
840: }
841: $mailer->addEmailInfo($emailInfo);
842: }
843:
844:
845: if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
846: foreach ($copyTo as $email) {
847: $emailInfo = Mage::getModel('core/email_info');
848: $emailInfo->addTo($email);
849: $mailer->addEmailInfo($emailInfo);
850: }
851: }
852:
853:
854: $mailer->setSender(Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_IDENTITY, $storeId));
855: $mailer->setStoreId($storeId);
856: $mailer->setTemplateId($templateId);
857: $mailer->setTemplateParams(array(
858: 'order' => $order,
859: 'creditmemo' => $this,
860: 'comment' => $comment,
861: 'billing' => $order->getBillingAddress()
862: )
863: );
864: $mailer->send();
865:
866: return $this;
867: }
868:
869: protected function _getEmails($configPath)
870: {
871: $data = Mage::getStoreConfig($configPath, $this->getStoreId());
872: if (!empty($data)) {
873: return explode(',', $data);
874: }
875: return false;
876: }
877:
878: protected function _beforeDelete()
879: {
880: $this->_protectFromNonAdmin();
881: return parent::_beforeDelete();
882: }
883:
884: 885: 886: 887: 888:
889: protected function _afterSave()
890: {
891: if (null != $this->_items) {
892: foreach ($this->_items as $item) {
893: $item->save();
894: }
895: }
896:
897: if (null != $this->_comments) {
898: foreach($this->_comments as $comment) {
899: $comment->save();
900: }
901: }
902:
903:
904: return parent::_afterSave();
905: }
906:
907: 908: 909: 910: 911:
912: protected function _beforeSave()
913: {
914: parent::_beforeSave();
915:
916: if (!$this->getOrderId() && $this->getOrder()) {
917: $this->setOrderId($this->getOrder()->getId());
918: $this->setBillingAddressId($this->getOrder()->getBillingAddress()->getId());
919: }
920:
921: return $this;
922: }
923:
924: 925: 926: 927: 928: 929:
930: public function getFilteredCollectionItems($filter = null)
931: {
932: return $this->getResourceCollection()->getFiltered($filter);
933: }
934: }
935: