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
00033
00034
00035
00036
00037
00038
00039 class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
00040 {
00041
00042
00043
00044 const XML_PATH_EMAIL_TEMPLATE = 'sales_email/order/template';
00045 const XML_PATH_EMAIL_GUEST_TEMPLATE = 'sales_email/order/guest_template';
00046 const XML_PATH_EMAIL_IDENTITY = 'sales_email/order/identity';
00047 const XML_PATH_EMAIL_COPY_TO = 'sales_email/order/copy_to';
00048 const XML_PATH_EMAIL_COPY_METHOD = 'sales_email/order/copy_method';
00049 const XML_PATH_EMAIL_ENABLED = 'sales_email/order/enabled';
00050
00051 const XML_PATH_UPDATE_EMAIL_TEMPLATE = 'sales_email/order_comment/template';
00052 const XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE = 'sales_email/order_comment/guest_template';
00053 const XML_PATH_UPDATE_EMAIL_IDENTITY = 'sales_email/order_comment/identity';
00054 const XML_PATH_UPDATE_EMAIL_COPY_TO = 'sales_email/order_comment/copy_to';
00055 const XML_PATH_UPDATE_EMAIL_COPY_METHOD = 'sales_email/order_comment/copy_method';
00056 const XML_PATH_UPDATE_EMAIL_ENABLED = 'sales_email/order_comment/enabled';
00057
00058
00059
00060
00061 const STATE_NEW = 'new';
00062 const STATE_PENDING_PAYMENT = 'pending_payment';
00063 const STATE_PROCESSING = 'processing';
00064 const STATE_COMPLETE = 'complete';
00065 const STATE_CLOSED = 'closed';
00066 const STATE_CANCELED = 'canceled';
00067 const STATE_HOLDED = 'holded';
00068
00069
00070
00071
00072 const ACTION_FLAG_CANCEL = 'cancel';
00073 const ACTION_FLAG_HOLD = 'hold';
00074 const ACTION_FLAG_UNHOLD = 'unhold';
00075 const ACTION_FLAG_EDIT = 'edit';
00076 const ACTION_FLAG_CREDITMEMO = 'creditmemo';
00077 const ACTION_FLAG_INVOICE = 'invoice';
00078 const ACTION_FLAG_REORDER = 'reorder';
00079 const ACTION_FLAG_SHIP = 'ship';
00080 const ACTION_FLAG_COMMENT = 'comment';
00081
00082
00083 protected $_eventPrefix = 'sales_order';
00084 protected $_eventObject = 'order';
00085
00086 protected $_addresses;
00087 protected $_items;
00088 protected $_payments;
00089 protected $_statusHistory;
00090 protected $_invoices;
00091 protected $_tracks;
00092 protected $_shipments;
00093 protected $_creditmemos;
00094 protected $_relatedObjects = array();
00095 protected $_orderCurrency = null;
00096 protected $_baseCurrency = null;
00097
00098
00099
00100
00101
00102
00103 protected $_actionFlag = array();
00104
00105
00106
00107
00108 protected function _construct()
00109 {
00110 $this->_init('sales/order');
00111 }
00112
00113 public function unsetData($key=null)
00114 {
00115 parent::unsetData($key);
00116 if (is_null($key)) {
00117 $this->_items = null;
00118 }
00119 return $this;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 public function getActionFlag($action)
00129 {
00130 if (isset($this->_actionFlag[$action])) {
00131 return $this->_actionFlag[$action];
00132 }
00133
00134 return null;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 public function setActionFlag($action, $flag)
00145 {
00146 $this->_actionFlag[$action] = (boolean) $flag;
00147 return $this;
00148 }
00149
00150 public function loadByIncrementId($incrementId)
00151 {
00152 return $this->loadByAttribute('increment_id', $incrementId);
00153 }
00154
00155 public function loadByAttribute($attribute, $value)
00156 {
00157 $collection = $this->getCollection()
00158 ->addAttributeToSelect('*')
00159 ->addAttributeToFilter($attribute, $value)
00160 ->load()
00161 ->getItems();
00162 if (sizeof($collection)) {
00163 reset($collection);
00164 $order = current($collection);
00165 $this->setData($order->getData());
00166 }
00167 return $this;
00168 }
00169
00170
00171
00172
00173
00174
00175 public function getStore()
00176 {
00177 if ($storeId = $this->getStoreId()) {
00178 return Mage::app()->getStore($storeId);
00179 }
00180 return Mage::app()->getStore();
00181 }
00182
00183
00184
00185
00186
00187
00188 public function canCancel()
00189 {
00190 if ($this->canUnhold()) {
00191 return false;
00192 }
00193
00194 if ($this->getState() === self::STATE_CANCELED ||
00195 $this->getState() === self::STATE_COMPLETE ||
00196 $this->getState() === self::STATE_CLOSED) {
00197 return false;
00198 }
00199
00200 if ($this->getActionFlag(self::ACTION_FLAG_CANCEL) === false) {
00201 return false;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 return true;
00214 }
00215
00216
00217
00218
00219
00220
00221 public function canInvoice()
00222 {
00223 if ($this->canUnhold()) {
00224 return false;
00225 }
00226 if ($this->getState() === self::STATE_CANCELED ||
00227 $this->getState() === self::STATE_COMPLETE ||
00228 $this->getState() === self::STATE_CLOSED ) {
00229 return false;
00230 }
00231
00232 if ($this->getActionFlag(self::ACTION_FLAG_INVOICE) === false) {
00233 return false;
00234 }
00235
00236 foreach ($this->getAllItems() as $item) {
00237 if ($item->getQtyToInvoice()>0 && !$item->getLockedDoInvoice()) {
00238 return true;
00239 }
00240 }
00241 return false;
00242 }
00243
00244
00245
00246
00247
00248
00249 public function canCreditmemo()
00250 {
00251 if ($this->hasForcedCanCreditmemo()) {
00252 return $this->getForcedCanCreditmemo();
00253 }
00254
00255 if ($this->canUnhold()) {
00256 return false;
00257 }
00258
00259 if ($this->getState() === self::STATE_CANCELED ||
00260 $this->getState() === self::STATE_CLOSED ) {
00261 return false;
00262 }
00263
00264
00265
00266
00267
00268 if (abs($this->getTotalPaid()-$this->getTotalRefunded())<.0001) {
00269 return false;
00270 }
00271
00272 if ($this->getActionFlag(self::ACTION_FLAG_EDIT) === false) {
00273 return false;
00274 }
00275
00276
00277 return true;
00278 }
00279
00280
00281
00282
00283
00284
00285 public function canHold()
00286 {
00287 if ($this->getState() === self::STATE_CANCELED ||
00288 $this->getState() === self::STATE_COMPLETE ||
00289 $this->getState() === self::STATE_CLOSED ||
00290 $this->getState() === self::STATE_HOLDED) {
00291 return false;
00292 }
00293
00294 if ($this->getActionFlag(self::ACTION_FLAG_HOLD) === false) {
00295 return false;
00296 }
00297
00298 return true;
00299 }
00300
00301
00302
00303
00304
00305
00306 public function canUnhold()
00307 {
00308 if ($this->getActionFlag(self::ACTION_FLAG_UNHOLD) === false) {
00309 return false;
00310 }
00311
00312 return $this->getState() === self::STATE_HOLDED;
00313 }
00314
00315 public function canComment()
00316 {
00317 if ($this->getActionFlag(self::ACTION_FLAG_COMMENT) === false) {
00318 return false;
00319 }
00320
00321 return true;
00322 }
00323
00324
00325
00326
00327
00328
00329 public function canShip()
00330 {
00331 if ($this->canUnhold()) {
00332 return false;
00333 }
00334
00335 if ($this->getIsVirtual()) {
00336 return false;
00337 }
00338
00339 if ($this->getActionFlag(self::ACTION_FLAG_SHIP) === false) {
00340 return false;
00341 }
00342
00343 foreach ($this->getAllItems() as $item) {
00344 if ($item->getQtyToShip()>0 && !$item->getIsVirtual()
00345 && !$item->getLockedDoShip())
00346 {
00347 return true;
00348 }
00349 }
00350 return false;
00351 }
00352
00353
00354
00355
00356
00357
00358 public function canEdit()
00359 {
00360 if ($this->canUnhold()) {
00361 return false;
00362 }
00363
00364 if ($this->getState() === self::STATE_CANCELED ||
00365 $this->getState() === self::STATE_COMPLETE ||
00366 $this->getState() === self::STATE_CLOSED) {
00367 return false;
00368 }
00369
00370 if (!$this->getPayment()->getMethodInstance()->canEdit()) {
00371 return false;
00372 }
00373
00374 if ($this->getActionFlag(self::ACTION_FLAG_EDIT) === false) {
00375 return false;
00376 }
00377
00378 return true;
00379 }
00380
00381
00382
00383
00384
00385
00386 public function canReorder()
00387 {
00388 if ($this->canUnhold() || !$this->getCustomerId()) {
00389 return false;
00390 }
00391
00392 $products = array();
00393 foreach ($this->getItemsCollection() as $item) {
00394 $products[] = $item->getProductId();
00395 }
00396 $productsCollection = Mage::getModel('catalog/product')->getCollection()
00397 ->setStoreId($this->getStoreId());
00398
00399 if (!empty($products)) {
00400 $productsCollection->addIdFilter($products)
00401 ->addAttributeToSelect('status')
00402 ->load();
00403 foreach ($productsCollection as $product) {
00404 if (!$product->isSalable()) {
00405 return false;
00406 }
00407 }
00408 }
00409
00410 if ($this->getActionFlag(self::ACTION_FLAG_REORDER) === false) {
00411 return false;
00412 }
00413
00414 return true;
00415 }
00416
00417
00418
00419
00420
00421
00422 public function getConfig()
00423 {
00424 return Mage::getSingleton('sales/order_config');
00425 }
00426
00427
00428
00429
00430
00431
00432 protected function _placePayment()
00433 {
00434 $this->getPayment()->place();
00435 return $this;
00436 }
00437
00438
00439
00440
00441
00442
00443 public function getPayment()
00444 {
00445 foreach ($this->getPaymentsCollection() as $payment) {
00446 if (!$payment->isDeleted()) {
00447 return $payment;
00448 }
00449 }
00450 return false;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459 public function setBillingAddress(Mage_Sales_Model_Order_Address $address)
00460 {
00461 $old = $this->getBillingAddress();
00462 if (!empty($old)) {
00463 $address->setId($old->getId());
00464 }
00465 $this->addAddress($address->setAddressType('billing'));
00466 return $this;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475 public function setShippingAddress(Mage_Sales_Model_Order_Address $address)
00476 {
00477 $old = $this->getShippingAddress();
00478 if (!empty($old)) {
00479 $address->setId($old->getId());
00480 }
00481 $this->addAddress($address->setAddressType('shipping'));
00482 return $this;
00483 }
00484
00485
00486
00487
00488
00489
00490 public function getBillingAddress()
00491 {
00492 foreach ($this->getAddressesCollection() as $address) {
00493 if ($address->getAddressType()=='billing' && !$address->isDeleted()) {
00494 return $address;
00495 }
00496 }
00497 return false;
00498 }
00499
00500
00501
00502
00503
00504
00505 public function getShippingAddress()
00506 {
00507 foreach ($this->getAddressesCollection() as $address) {
00508 if ($address->getAddressType()=='shipping' && !$address->isDeleted()) {
00509 return $address;
00510 }
00511 }
00512 return false;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 public function setState($state, $status = false, $comment = '', $isCustomerNotified = false)
00525 {
00526 $this->setData('state', $state);
00527 if ($status) {
00528 if ($status === true) {
00529 $status = $this->getConfig()->getStateDefaultStatus($state);
00530 }
00531 $this->addStatusToHistory($status, $comment, $isCustomerNotified);
00532 }
00533 return $this;
00534 }
00535
00536
00537
00538
00539
00540
00541 public function getStatusLabel()
00542 {
00543 return $this->getConfig()->getStatusLabel($this->getStatus());
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 public function addStatusToHistory($status, $comment='', $isCustomerNotified = false)
00555 {
00556 $status = Mage::getModel('sales/order_status_history')
00557 ->setStatus($status)
00558 ->setComment($comment)
00559 ->setIsCustomerNotified($isCustomerNotified);
00560 $this->addStatusHistory($status);
00561 return $this;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 public function place()
00571 {
00572 Mage::dispatchEvent('sales_order_place_before', array('order'=>$this));
00573 $this->_placePayment();
00574 Mage::dispatchEvent('sales_order_place_after', array('order'=>$this));
00575 return $this;
00576 }
00577
00578 public function hold()
00579 {
00580 if (!$this->canHold()) {
00581 Mage::throwException(Mage::helper('sales')->__('Hold action is not available'));
00582 }
00583 $this->setHoldBeforeState($this->getState());
00584 $this->setHoldBeforeStatus($this->getStatus());
00585 $this->setState(self::STATE_HOLDED, true);
00586 return $this;
00587 }
00588
00589 public function unhold()
00590 {
00591 $this->setState($this->getHoldBeforeState(), $this->getHoldBeforeStatus());
00592 $this->setHoldBeforeState(null);
00593 $this->setHoldBeforeStatus(null);
00594 return $this;
00595 }
00596
00597
00598
00599
00600
00601
00602 public function cancel()
00603 {
00604 if ($this->canCancel()) {
00605 $this->getPayment()->cancel();
00606 $cancelState = self::STATE_CANCELED;
00607 foreach ($this->getAllItems() as $item) {
00608 if ($item->getQtyInvoiced()>$item->getQtyRefunded()) {
00609 $cancelState = self::STATE_COMPLETE;
00610 }
00611 $item->cancel();
00612 }
00613
00614 $this->setSubtotalCanceled($this->getSubtotal() - $this->getSubtotalInvoiced());
00615 $this->setBaseSubtotalCanceled($this->getBaseSubtotal() - $this->getBaseSubtotalInvoiced());
00616
00617 $this->setTaxCanceled($this->getTaxAmount() - $this->getTaxInvoiced());
00618 $this->setBaseTaxCanceled($this->getBaseTaxAmount() - $this->getBaseTaxInvoiced());
00619
00620 $this->setShippingCanceled($this->getShippingAmount() - $this->getShippingInvoiced());
00621 $this->setBaseShippingCanceled($this->getBaseShippingAmount() - $this->getBaseShippingInvoiced());
00622
00623 $this->setDiscountCanceled(
00624 $this->getDiscountAmount() - $this->getDiscountInvoiced()
00625 );
00626 $this->setBaseDiscountCanceled(
00627 $this->getBaseDiscountAmount() - $this->getBaseDiscountInvoiced()
00628 );
00629
00630 $this->setState($cancelState, true);
00631 }
00632 return $this;
00633 }
00634
00635
00636
00637
00638
00639
00640 public function getTrackingNumbers()
00641 {
00642 if ($this->getData('tracking_numbers')) {
00643 return explode(',', $this->getData('tracking_numbers'));
00644 }
00645 return array();
00646 }
00647
00648 public function getShippingCarrier()
00649 {
00650 $carrierModel = $this->getData('shipping_carrier');
00651 if (is_null($carrierModel)) {
00652 $carrierModel = false;
00653
00654
00655
00656 if ($method = $this->getShippingMethod()) {
00657 $data = explode('_', $method);
00658 $carrierCode = $data[0];
00659 $className = Mage::getStoreConfig('carriers/'.$carrierCode.'/model');
00660 if ($className) {
00661 $carrierModel = Mage::getModel($className);
00662 }
00663 }
00664 $this->setData('shipping_carrier', $carrierModel);
00665 }
00666 return $carrierModel;
00667 }
00668
00669
00670
00671
00672
00673
00674 public function sendNewOrderEmail()
00675 {
00676 if (!Mage::helper('sales')->canSendNewOrderEmail($this->getStore()->getId())) {
00677 return $this;
00678 }
00679
00680 $translate = Mage::getSingleton('core/translate');
00681
00682 $translate->setTranslateInline(false);
00683
00684 $paymentBlock = Mage::helper('payment')->getInfoBlock($this->getPayment())
00685 ->setIsSecureMode(true);
00686
00687 $paymentBlock->getMethod()->setStore($this->getStore()->getId());
00688
00689 $mailTemplate = Mage::getModel('core/email_template');
00690
00691 $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
00692 $copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $this->getStoreId());
00693 if ($copyTo && $copyMethod == 'bcc') {
00694 foreach ($copyTo as $email) {
00695 $mailTemplate->addBcc($email);
00696 }
00697 }
00698
00699 if ($this->getCustomerIsGuest()) {
00700 $template = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $this->getStoreId());
00701 $customerName = $this->getBillingAddress()->getName();
00702 } else {
00703 $template = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $this->getStoreId());
00704 $customerName = $this->getCustomerName();
00705 }
00706
00707 $sendTo = array(
00708 array(
00709 'email' => $this->getCustomerEmail(),
00710 'name' => $customerName
00711 )
00712 );
00713 if ($copyTo && $copyMethod == 'copy') {
00714 foreach ($copyTo as $email) {
00715 $sendTo[] = array(
00716 'email' => $email,
00717 'name' => null
00718 );
00719 }
00720 }
00721
00722 foreach ($sendTo as $recipient) {
00723 $mailTemplate->setDesignConfig(array('area'=>'frontend', 'store'=>$this->getStoreId()))
00724 ->sendTransactional(
00725 $template,
00726 Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $this->getStoreId()),
00727 $recipient['email'],
00728 $recipient['name'],
00729 array(
00730 'order' => $this,
00731 'billing' => $this->getBillingAddress(),
00732 'payment_html' => $paymentBlock->toHtml(),
00733 )
00734 );
00735 }
00736
00737 $translate->setTranslateInline(true);
00738
00739 return $this;
00740 }
00741
00742
00743
00744
00745
00746
00747 public function sendOrderUpdateEmail($notifyCustomer=true, $comment='')
00748 {
00749 if (!Mage::helper('sales')->canSendOrderCommentEmail($this->getStore()->getId())) {
00750 return $this;
00751 }
00752
00753 $copyTo = $this->_getEmails(self::XML_PATH_UPDATE_EMAIL_COPY_TO);
00754 $copyMethod = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_COPY_METHOD, $this->getStoreId());
00755 if (!$notifyCustomer && !$copyTo) {
00756 return $this;
00757 }
00758
00759
00760 $currentDesign = Mage::getDesign()->setAllGetOld(array(
00761 'store' => $this->getStoreId(),
00762 'area' => 'frontend',
00763 'package' => Mage::getStoreConfig('design/package/name', $this->getStoreId()),
00764 ));
00765
00766 $translate = Mage::getSingleton('core/translate');
00767
00768 $translate->setTranslateInline(false);
00769
00770 $sendTo = array();
00771
00772 $mailTemplate = Mage::getModel('core/email_template');
00773
00774 if ($this->getCustomerIsGuest()) {
00775 $template = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE, $this->getStoreId());
00776 $customerName = $this->getBillingAddress()->getName();
00777 } else {
00778 $template = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_TEMPLATE, $this->getStoreId());
00779 $customerName = $this->getCustomerName();
00780 }
00781
00782 if ($notifyCustomer) {
00783 $sendTo[] = array(
00784 'name' => $customerName,
00785 'email' => $this->getCustomerEmail()
00786 );
00787 if ($copyTo && $copyMethod == 'bcc') {
00788 foreach ($copyTo as $email) {
00789 $mailTemplate->addBcc($email);
00790 }
00791 }
00792
00793 }
00794
00795 if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
00796 foreach ($copyTo as $email) {
00797 $sendTo[] = array(
00798 'name' => null,
00799 'email' => $email
00800 );
00801 }
00802 }
00803
00804 foreach ($sendTo as $recipient) {
00805 $mailTemplate->setDesignConfig(array('area'=>'frontend', 'store' => $this->getStoreId()))
00806 ->sendTransactional(
00807 $template,
00808 Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_IDENTITY, $this->getStoreId()),
00809 $recipient['email'],
00810 $recipient['name'],
00811 array(
00812 'order' => $this,
00813 'billing' => $this->getBillingAddress(),
00814 'comment' => $comment
00815 )
00816 );
00817 }
00818
00819 $translate->setTranslateInline(true);
00820
00821
00822 Mage::getDesign()->setAllGetOld($currentDesign);
00823
00824 return $this;
00825 }
00826
00827 protected function _getEmails($configPath)
00828 {
00829 $data = Mage::getStoreConfig($configPath, $this->getStoreId());
00830 if (!empty($data)) {
00831 return explode(',', $data);
00832 }
00833 return false;
00834 }
00835
00836
00837
00838 public function getAddressesCollection()
00839 {
00840 if (is_null($this->_addresses)) {
00841 $this->_addresses = Mage::getResourceModel('sales/order_address_collection')
00842 ->addAttributeToSelect('*')
00843 ->setOrderFilter($this->getId());
00844
00845 if ($this->getId()) {
00846 foreach ($this->_addresses as $address) {
00847 $address->setOrder($this);
00848 }
00849 }
00850 }
00851
00852 return $this->_addresses;
00853 }
00854
00855 public function getAddressById($addressId)
00856 {
00857 foreach ($this->getAddressesCollection() as $address) {
00858 if ($address->getId()==$addressId) {
00859 return $address;
00860 }
00861 }
00862 return false;
00863 }
00864
00865 public function addAddress(Mage_Sales_Model_Order_Address $address)
00866 {
00867 $address->setOrder($this)->setParentId($this->getId());
00868 if (!$address->getId()) {
00869 $this->getAddressesCollection()->addItem($address);
00870 }
00871 return $this;
00872 }
00873
00874 public function getItemsCollection($filterByTypes = array(), $nonChildrenOnly = false)
00875 {
00876 if (is_null($this->_items)) {
00877 $this->_items = Mage::getResourceModel('sales/order_item_collection')
00878 ->setOrderFilter($this->getId());
00879 if ($filterByTypes) {
00880 $this->_items->filterByTypes($filterByTypes);
00881 }
00882 if ($nonChildrenOnly) {
00883 $this->_items->filterByParent();
00884 }
00885
00886 if ($this->getId()) {
00887 foreach ($this->_items as $item) {
00888 $item->setOrder($this);
00889 }
00890 }
00891 }
00892 return $this->_items;
00893 }
00894
00895 public function getItemsRandomCollection($limit=1)
00896 {
00897 $collection = Mage::getModel('sales/order_item')->getCollection()
00898 ->setOrderFilter($this->getId())
00899 ->setRandomOrder()
00900 ->setPageSize($limit);
00901
00902 $products = array();
00903 foreach ($collection as $item) {
00904 $products[] = $item->getProductId();
00905 }
00906
00907 $productsCollection = Mage::getModel('catalog/product')
00908 ->getCollection()
00909 ->addIdFilter($products)
00910 ->load();
00911 Mage::getSingleton('catalog/product_visibility')
00912 ->addVisibleInSiteFilterToCollection($productsCollection);
00913 foreach ($collection as $item) {
00914 $item->setProduct($productsCollection->getItemById($item->getProductId()));
00915 }
00916 return $collection;
00917 }
00918
00919 public function getAllItems()
00920 {
00921 $items = array();
00922 foreach ($this->getItemsCollection() as $item) {
00923 if (!$item->isDeleted()) {
00924 $items[] = $item;
00925 }
00926 }
00927 return $items;
00928 }
00929
00930 public function getAllVisibleItems()
00931 {
00932 $items = array();
00933 foreach ($this->getItemsCollection() as $item) {
00934 if (!$item->isDeleted() && !$item->getParentItemId()) {
00935 $items[] = $item;
00936 }
00937 }
00938 return $items;
00939 }
00940
00941 public function getItemById($itemId)
00942 {
00943 return $this->getItemsCollection()->getItemById($itemId);
00944 }
00945
00946 public function getItemByQuoteItemId($quoteItemId)
00947 {
00948 foreach ($this->getItemsCollection() as $item) {
00949 if ($item->getQuoteItemId()==$quoteItemId) {
00950 return $item;
00951 }
00952 }
00953 return null;
00954 }
00955
00956 public function addItem(Mage_Sales_Model_Order_Item $item)
00957 {
00958 $item->setOrder($this);
00959 if (!$item->getId()) {
00960 $this->getItemsCollection()->addItem($item);
00961 }
00962 return $this;
00963 }
00964
00965
00966
00967 public function getPaymentsCollection()
00968 {
00969 if (is_null($this->_payments)) {
00970 $this->_payments = Mage::getResourceModel('sales/order_payment_collection')
00971 ->addAttributeToSelect('*')
00972 ->setOrderFilter($this->getId());
00973
00974 if ($this->getId()) {
00975 foreach ($this->_payments as $payment) {
00976 $payment->setOrder($this);
00977 }
00978 }
00979 }
00980 return $this->_payments;
00981 }
00982
00983 public function getAllPayments()
00984 {
00985 $payments = array();
00986 foreach ($this->getPaymentsCollection() as $payment) {
00987 if (!$payment->isDeleted()) {
00988 $payments[] = $payment;
00989 }
00990 }
00991 return $payments;
00992 }
00993
00994
00995 public function getPaymentById($paymentId)
00996 {
00997 foreach ($this->getPaymentsCollection() as $payment) {
00998 if ($payment->getId()==$paymentId) {
00999 return $payment;
01000 }
01001 }
01002 return false;
01003 }
01004
01005 public function addPayment(Mage_Sales_Model_Order_Payment $payment)
01006 {
01007 $payment->setOrder($this)
01008 ->setParentId($this->getId());
01009 if (!$payment->getId()) {
01010 $this->getPaymentsCollection()->addItem($payment);
01011 }
01012 return $this;
01013 }
01014
01015 public function setPayment(Mage_Sales_Model_Order_Payment $payment)
01016 {
01017 if (!$this->getIsMultiPayment() && ($old = $this->getPayment())) {
01018 $payment->setId($old->getId());
01019 }
01020 $this->addPayment($payment);
01021 return $payment;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031 public function getStatusHistoryCollection($reload=false)
01032 {
01033 if (is_null($this->_statusHistory) || $reload) {
01034 $this->_statusHistory = Mage::getResourceModel('sales/order_status_history_collection')
01035 ->addAttributeToSelect('*')
01036 ->setOrderFilter($this->getId())
01037 ->setOrder('created_at', 'desc')
01038 ->setOrder('entity_id', 'desc');
01039
01040 if ($this->getId()) {
01041 foreach ($this->_statusHistory as $status) {
01042 $status->setOrder($this);
01043 }
01044 }
01045 }
01046 return $this->_statusHistory;
01047 }
01048
01049
01050
01051
01052
01053
01054 public function getAllStatusHistory()
01055 {
01056 $history = array();
01057 foreach ($this->getStatusHistoryCollection() as $status) {
01058 if (!$status->isDeleted()) {
01059 $history[] = $status;
01060 }
01061 }
01062 return $history;
01063 }
01064
01065
01066
01067
01068
01069
01070 public function getVisibleStatusHistory()
01071 {
01072 $history = array();
01073 foreach ($this->getStatusHistoryCollection() as $status) {
01074 if (!$status->isDeleted() && $status->getComment() && $status->getIsCustomerNotified()) {
01075 $history[] = $status;
01076 }
01077 }
01078 return $history;
01079 }
01080
01081 public function getStatusHistoryById($statusId)
01082 {
01083 foreach ($this->getStatusHistoryCollection() as $status) {
01084 if ($status->getId()==$statusId) {
01085 return $status;
01086 }
01087 }
01088 return false;
01089 }
01090
01091 public function addStatusHistory(Mage_Sales_Model_Order_Status_History $status)
01092 {
01093 $status->setOrder($this)
01094 ->setParentId($this->getId())
01095 ->setStoreId($this->getStoreId());
01096 $this->setStatus($status->getStatus());
01097 if (!$status->getId()) {
01098 $this->getStatusHistoryCollection()->addItem($status);
01099 }
01100 return $this;
01101 }
01102
01103
01104
01105
01106
01107
01108
01109 public function getRealOrderId()
01110 {
01111 $id = $this->getData('real_order_id');
01112 if (is_null($id)) {
01113 $id = $this->getIncrementId();
01114 }
01115 return $id;
01116 }
01117
01118
01119
01120
01121
01122
01123 public function getOrderCurrency()
01124 {
01125 if (is_null($this->_orderCurrency)) {
01126 $this->_orderCurrency = Mage::getModel('directory/currency')->load($this->getOrderCurrencyCode());
01127 }
01128 return $this->_orderCurrency;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138 public function formatPrice($price, $addBrackets = false)
01139 {
01140 return $this->getOrderCurrency()->format($price, array(), true, $addBrackets);
01141 }
01142
01143
01144
01145
01146
01147
01148
01149 public function formatPriceTxt($price)
01150 {
01151 return $this->getOrderCurrency()->formatTxt($price);
01152 }
01153
01154
01155
01156
01157
01158
01159 public function getBaseCurrency()
01160 {
01161 if (is_null($this->_baseCurrency)) {
01162 $this->_baseCurrency = Mage::getModel('directory/currency')->load($this->getBaseCurrencyCode());
01163 }
01164 return $this->_baseCurrency;
01165 }
01166
01167
01168
01169
01170
01171
01172
01173 public function getStoreCurrency()
01174 {
01175 return $this->getStoreCurrency();
01176 }
01177
01178 public function formatBasePrice($price)
01179 {
01180 return $this->getBaseCurrency()->format($price);
01181 }
01182
01183 public function isCurrencyDifferent()
01184 {
01185 return $this->getOrderCurrencyCode() != $this->getBaseCurrencyCode();
01186 }
01187
01188
01189
01190
01191
01192
01193 public function getTotalDue()
01194 {
01195 $total = $this->getGrandTotal()-$this->getTotalPaid();
01196 $total = Mage::app()->getStore($this->getStoreId())->roundPrice($total);
01197 return max($total, 0);
01198 }
01199
01200
01201
01202
01203
01204
01205 public function getBaseTotalDue()
01206 {
01207 $total = $this->getBaseGrandTotal()-$this->getBaseTotalPaid();
01208 $total = Mage::app()->getStore($this->getStoreId())->roundPrice($total);
01209 return max($total, 0);
01210 }
01211
01212 public function getData($key='', $index=null)
01213 {
01214 if ($key == 'total_due') {
01215 return $this->getTotalDue();
01216 }
01217 if ($key == 'base_total_due') {
01218 return $this->getBaseTotalDue();
01219 }
01220 return parent::getData($key, $index);
01221 }
01222
01223
01224
01225
01226
01227
01228 public function getInvoiceCollection()
01229 {
01230 if (is_null($this->_invoices)) {
01231 $this->_invoices = Mage::getResourceModel('sales/order_invoice_collection')
01232 ->addAttributeToSelect('*')
01233 ->setOrderFilter($this->getId());
01234
01235 if ($this->getId()) {
01236 foreach ($this->_invoices as $invoice) {
01237 $invoice->setOrder($this);
01238 }
01239 }
01240 }
01241 return $this->_invoices;
01242 }
01243
01244
01245
01246
01247
01248
01249 public function getShipmentsCollection()
01250 {
01251 if (empty($this->_shipments)) {
01252 if ($this->getId()) {
01253
01254 $this->_shipments = Mage::getResourceModel('sales/order_shipment_collection')
01255 ->addAttributeToSelect('increment_id')
01256 ->addAttributeToSelect('created_at')
01257 ->addAttributeToSelect('total_qty')
01258 ->addAttributeToSelect('email_sent')
01259 ->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
01260 ->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
01261 ->setOrderFilter($this->getId())
01262 ->load()
01263 ;
01264 } else {
01265 return false;
01266 }
01267 }
01268 return $this->_shipments;
01269 }
01270
01271
01272
01273
01274
01275
01276 public function getCreditmemosCollection()
01277 {
01278 if (empty($this->_creditmemos)) {
01279 if ($this->getId()) {
01280 $this->_creditmemos = Mage::getResourceModel('sales/order_Creditmemo_collection')
01281 ->addAttributeToSelect('*')
01282 ->setOrderFilter($this->getId())
01283 ->load();
01284 } else {
01285 return false;
01286 }
01287 }
01288 return $this->_creditmemos;
01289 }
01290
01291
01292
01293
01294
01295
01296 public function getTracksCollection()
01297 {
01298 if (empty($this->_tracks)) {
01299 $this->_tracks = Mage::getResourceModel('sales/order_shipment_track_collection')
01300 ->addAttributeToSelect('*')
01301 ->setOrderFilter($this->getId());
01302
01303 if ($this->getId()) {
01304 $this->_tracks->load();
01305 }
01306 }
01307 return $this->_tracks;
01308 }
01309
01310
01311
01312
01313
01314
01315 public function hasInvoices()
01316 {
01317 return $this->getInvoiceCollection()->count();
01318 }
01319
01320
01321
01322
01323
01324
01325 public function hasShipments()
01326 {
01327 return $this->getShipmentsCollection()->count();
01328 }
01329
01330
01331
01332
01333
01334
01335 public function hasCreditmemos()
01336 {
01337 return $this->getCreditmemosCollection()->count();
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348 public function getRelatedObjects()
01349 {
01350 return $this->_relatedObjects;
01351 }
01352
01353 public function getCustomerName()
01354 {
01355 if ($this->getCustomerFirstname()) {
01356 $customerName = $this->getCustomerFirstname() . ' ' . $this->getCustomerLastname();
01357 }
01358 else {
01359 $customerName = Mage::helper('sales')->__('Guest');
01360 }
01361 return $customerName;
01362 }
01363
01364
01365
01366
01367
01368
01369
01370 public function addRelatedObject(Mage_Core_Model_Abstract $object)
01371 {
01372 $this->_relatedObjects[] = $object;
01373 return $this;
01374 }
01375
01376
01377
01378
01379
01380
01381
01382 public function getCreatedAtFormated($format)
01383 {
01384 return Mage::helper('core')->formatDate($this->getCreatedAtStoreDate(), $format);
01385 }
01386
01387 public function getEmailCustomerNote()
01388 {
01389 if ($this->getCustomerNoteNotify()) {
01390 return $this->getCustomerNote();
01391 }
01392 return '';
01393 }
01394
01395
01396
01397
01398
01399
01400 protected function _beforeSave()
01401 {
01402 parent::_beforeSave();
01403 $this->_checkState();
01404 if (!$this->getId()) {
01405 $store = $this->getStore();
01406 $name = array($store->getWebsite()->getName(),$store->getGroup()->getName(),$store->getName());
01407 $this->setStoreName(implode("\n", $name));
01408 }
01409
01410
01411
01412
01413 if (!$this->getId()) {
01414 foreach ($this->getAllItems() as $item) {
01415 if ($parent = $item->getQuoteParentItemId() && !$item->getParentItem()) {
01416 $item->setParentItem($this->getItemByQuoteItemId($parent));
01417 }
01418 }
01419 }
01420
01421 return $this;
01422 }
01423
01424 protected function _checkState()
01425 {
01426 if (!$this->getId()) {
01427 return $this;
01428 }
01429
01430 if ($this->getState() !== self::STATE_CANCELED
01431 && !$this->canUnhold()
01432 && !$this->canInvoice()
01433 && !$this->canShip()) {
01434 if ($this->canCreditmemo()) {
01435 if ($this->getState() !== self::STATE_COMPLETE) {
01436 $this->setState(self::STATE_COMPLETE, true);
01437 }
01438 }
01439
01440
01441
01442 elseif(floatval($this->getTotalRefunded())) {
01443 if ($this->getState() !== self::STATE_CLOSED) {
01444 $this->setState(self::STATE_CLOSED, true);
01445 }
01446 }
01447 }
01448
01449 if ($this->getState() == self::STATE_NEW && $this->getIsInProcess()) {
01450 $this->setState(self::STATE_PROCESSING, true);
01451 }
01452 return $this;
01453 }
01454
01455 public function getStoreGroupName()
01456 {
01457 $storeId = $this->getStoreId();
01458 if (is_null($storeId)) {
01459 return $this->getStoreName(1);
01460 }
01461 return $this->getStore()->getGroup()->getName();
01462 }
01463
01464
01465
01466
01467
01468
01469
01470 public function reset()
01471 {
01472 $this->unsetData();
01473 $this->_addresses = null;
01474 $this->_items = null;
01475 $this->_payments = null;
01476 $this->_statusHistory = null;
01477 $this->_invoices = null;
01478 $this->_tracks = null;
01479 $this->_shipments = null;
01480 $this->_creditmemos = null;
01481 $this->_relatedObjects = array();
01482 $this->_orderCurrency = null;
01483 $this->_baseCurrency = null;
01484
01485 return $this;
01486 }
01487
01488 public function getIsNotVirtual()
01489 {
01490 return !$this->getIsVirtual();
01491 }
01492
01493 public function getFullTaxInfo()
01494 {
01495 $rates = Mage::getModel('sales/order_tax')->getCollection()->loadByOrder($this)->toArray();
01496 return Mage::getSingleton('tax/calculation')->reproduceProcess($rates['items']);
01497 }
01498
01499
01500
01501
01502
01503
01504 public function prepareInvoice($qtys = array())
01505 {
01506 $convertor = Mage::getModel('sales/convert_order');
01507 $invoice = $convertor->toInvoice($this);
01508 foreach ($this->getAllItems() as $orderItem) {
01509 if (!$orderItem->isDummy() && !$orderItem->getQtyToInvoice()) {
01510 continue;
01511 }
01512 if ($orderItem->isDummy() && !$this->_needToAddDummy($orderItem, $qtys)) {
01513 continue;
01514 }
01515 $item = $convertor->itemToInvoiceItem($orderItem);
01516 if ($orderItem->isDummy()) {
01517 $qty = 1;
01518 } else {
01519 if (isset($qtys[$orderItem->getId()])) {
01520 $qty = $qtys[$orderItem->getId()];
01521 } else {
01522 $qty = $orderItem->getQtyToInvoice();
01523 }
01524 }
01525
01526 $item->setQty($qty);
01527 $invoice->addItem($item);
01528 }
01529 $invoice->collectTotals();
01530
01531 return $invoice;
01532 }
01533
01534
01535
01536
01537
01538
01539 public function prepareShipment($qtys = array())
01540 {
01541 $totalToShip = 0;
01542 $convertor = Mage::getModel('sales/convert_order');
01543 $shipment = $convertor->toShipment($this);
01544 foreach ($this->getAllItems() as $orderItem) {
01545 if (!$orderItem->isDummy() && !$orderItem->getQtyToShip()) {
01546 continue;
01547 }
01548 if ($orderItem->isDummy() && !$this->_needToAddDummy($orderItem, $qtys)) {
01549 continue;
01550 }
01551 $item = $convertor->itemToShipmentItem($orderItem);
01552 if ($orderItem->isDummy()) {
01553 $qty = 1;
01554 } else {
01555 if (isset($qtys[$orderItem->getId()])) {
01556 $qty = $qtys[$orderItem->getId()];
01557 } else {
01558 $qty = $orderItem->getQtyToShip();
01559 }
01560 }
01561
01562 $totalToShip += $qty;
01563 $item->setQty($qty);
01564 $shipment->addItem($item);
01565 }
01566
01567 if ($totalToShip) {
01568 return $shipment;
01569 } else {
01570 return null;
01571 }
01572 }
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 protected function _needToAddDummy($item, $qtys = array()) {
01584 if ($item->getHasChildren()) {
01585 foreach ($item->getChildrenItems() as $child) {
01586 if (empty($qtys)) {
01587 if ($child->getQtyToInvoice() > 0) {
01588 return true;
01589 }
01590 } else {
01591 if (isset($qtys[$child->getId()]) && $qtys[$child->getId()] > 0) {
01592 return true;
01593 }
01594 }
01595 }
01596 return false;
01597 } else if($item->getParentItem()) {
01598 if (empty($qtys)) {
01599 if ($item->getParentItem()->getQtyToInvoice() > 0) {
01600 return true;
01601 }
01602 } else {
01603 if (isset($qtys[$child->getId()]) && $qtys[$child->getId()] > 0) {
01604 return true;
01605 }
01606 }
01607 return false;
01608 }
01609 }
01610
01611 protected function _beforeDelete()
01612 {
01613 $this->_protectFromNonAdmin();
01614 return parent::_beforeDelete();
01615 }
01616 }