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: class Mage_Sales_Model_Order_Shipment extends Mage_Sales_Model_Abstract
63: {
64: const STATUS_NEW = 1;
65:
66: const XML_PATH_EMAIL_TEMPLATE = 'sales_email/shipment/template';
67: const XML_PATH_EMAIL_GUEST_TEMPLATE = 'sales_email/shipment/guest_template';
68: const XML_PATH_EMAIL_IDENTITY = 'sales_email/shipment/identity';
69: const XML_PATH_EMAIL_COPY_TO = 'sales_email/shipment/copy_to';
70: const XML_PATH_EMAIL_COPY_METHOD = 'sales_email/shipment/copy_method';
71: const XML_PATH_EMAIL_ENABLED = 'sales_email/shipment/enabled';
72:
73: const XML_PATH_UPDATE_EMAIL_TEMPLATE = 'sales_email/shipment_comment/template';
74: const XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE = 'sales_email/shipment_comment/guest_template';
75: const XML_PATH_UPDATE_EMAIL_IDENTITY = 'sales_email/shipment_comment/identity';
76: const XML_PATH_UPDATE_EMAIL_COPY_TO = 'sales_email/shipment_comment/copy_to';
77: const XML_PATH_UPDATE_EMAIL_COPY_METHOD = 'sales_email/shipment_comment/copy_method';
78: const XML_PATH_UPDATE_EMAIL_ENABLED = 'sales_email/shipment_comment/enabled';
79:
80: const REPORT_DATE_TYPE_ORDER_CREATED = 'order_created';
81: const REPORT_DATE_TYPE_SHIPMENT_CREATED = 'shipment_created';
82:
83: 84: 85:
86: const HISTORY_ENTITY_NAME = 'shipment';
87:
88: protected $_items;
89: protected $_tracks;
90: protected $_order;
91: protected ;
92:
93: protected $_eventPrefix = 'sales_order_shipment';
94: protected $_eventObject = 'shipment';
95:
96: 97: 98:
99: protected function _construct()
100: {
101: $this->_init('sales/order_shipment');
102: }
103:
104: 105: 106: 107: 108:
109: protected function _initOldFieldsMap()
110: {
111: $this->_oldFieldsMap = Mage::helper('sales')->getOldFieldMap('order_shipment');
112: return $this;
113: }
114:
115: 116: 117: 118: 119: 120:
121: public function loadByIncrementId($incrementId)
122: {
123: $ids = $this->getCollection()
124: ->addAttributeToFilter('increment_id', $incrementId)
125: ->getAllIds();
126:
127: if (!empty($ids)) {
128: reset($ids);
129: $this->load(current($ids));
130: }
131: return $this;
132: }
133:
134:
135: 136: 137: 138: 139: 140:
141: public function setOrder(Mage_Sales_Model_Order $order)
142: {
143: $this->_order = $order;
144: $this->setOrderId($order->getId())
145: ->setStoreId($order->getStoreId());
146: return $this;
147: }
148:
149:
150: 151: 152: 153: 154:
155: public function getProtectCode()
156: {
157: return (string)$this->getOrder()->getProtectCode();
158: }
159:
160: 161: 162: 163: 164:
165: public function getOrder()
166: {
167: if (!$this->_order instanceof Mage_Sales_Model_Order) {
168: $this->_order = Mage::getModel('sales/order')->load($this->getOrderId());
169: }
170: return $this->_order->setHistoryEntityName(self::HISTORY_ENTITY_NAME);
171: }
172:
173: 174: 175: 176: 177:
178: public function getBillingAddress()
179: {
180: return $this->getOrder()->getBillingAddress();
181: }
182:
183: 184: 185: 186: 187:
188: public function getShippingAddress()
189: {
190: return $this->getOrder()->getShippingAddress();
191: }
192:
193: 194: 195: 196: 197: 198: 199:
200: public function register()
201: {
202: if ($this->getId()) {
203: Mage::throwException(
204: Mage::helper('sales')->__('Cannot register existing shipment')
205: );
206: }
207:
208: $totalQty = 0;
209: foreach ($this->getAllItems() as $item) {
210: if ($item->getQty()>0) {
211: $item->register();
212: if (!$item->getOrderItem()->isDummy(true)) {
213: $totalQty+= $item->getQty();
214: }
215: }
216: else {
217: $item->isDeleted(true);
218: }
219: }
220: $this->setTotalQty($totalQty);
221:
222: return $this;
223: }
224:
225: public function getItemsCollection()
226: {
227: if (empty($this->_items)) {
228: $this->_items = Mage::getResourceModel('sales/order_shipment_item_collection')
229: ->setShipmentFilter($this->getId());
230:
231: if ($this->getId()) {
232: foreach ($this->_items as $item) {
233: $item->setShipment($this);
234: }
235: }
236: }
237: return $this->_items;
238: }
239:
240: public function getAllItems()
241: {
242: $items = array();
243: foreach ($this->getItemsCollection() as $item) {
244: if (!$item->isDeleted()) {
245: $items[] = $item;
246: }
247: }
248: return $items;
249: }
250:
251: public function getItemById($itemId)
252: {
253: foreach ($this->getItemsCollection() as $item) {
254: if ($item->getId()==$itemId) {
255: return $item;
256: }
257: }
258: return false;
259: }
260:
261: public function addItem(Mage_Sales_Model_Order_Shipment_Item $item)
262: {
263: $item->setShipment($this)
264: ->setParentId($this->getId())
265: ->setStoreId($this->getStoreId());
266: if (!$item->getId()) {
267: $this->getItemsCollection()->addItem($item);
268: }
269: return $this;
270: }
271:
272:
273: public function getTracksCollection()
274: {
275: if (empty($this->_tracks)) {
276: $this->_tracks = Mage::getResourceModel('sales/order_shipment_track_collection')
277: ->setShipmentFilter($this->getId());
278:
279: if ($this->getId()) {
280: foreach ($this->_tracks as $track) {
281: $track->setShipment($this);
282: }
283: }
284: }
285: return $this->_tracks;
286: }
287:
288: public function getAllTracks()
289: {
290: $tracks = array();
291: foreach ($this->getTracksCollection() as $track) {
292: if (!$track->isDeleted()) {
293: $tracks[] = $track;
294: }
295: }
296: return $tracks;
297: }
298:
299: public function getTrackById($trackId)
300: {
301: foreach ($this->getTracksCollection() as $track) {
302: if ($track->getId()==$trackId) {
303: return $track;
304: }
305: }
306: return false;
307: }
308:
309: public function addTrack(Mage_Sales_Model_Order_Shipment_Track $track)
310: {
311: $track->setShipment($this)
312: ->setParentId($this->getId())
313: ->setOrderId($this->getOrderId())
314: ->setStoreId($this->getStoreId());
315: if (!$track->getId()) {
316: $this->getTracksCollection()->addItem($track);
317: }
318:
319: 320: 321: 322:
323: $this->_hasDataChanges = true;
324:
325: return $this;
326: }
327:
328: 329: 330: 331: 332: 333: 334: 335: 336:
337: public function ($comment, $notify=false, $visibleOnFront=false)
338: {
339: if (!($comment instanceof Mage_Sales_Model_Order_Shipment_Comment)) {
340: $comment = Mage::getModel('sales/order_shipment_comment')
341: ->setComment($comment)
342: ->setIsCustomerNotified($notify)
343: ->setIsVisibleOnFront($visibleOnFront);
344: }
345: $comment->setShipment($this)
346: ->setParentId($this->getId())
347: ->setStoreId($this->getStoreId());
348: if (!$comment->getId()) {
349: $this->getCommentsCollection()->addItem($comment);
350: }
351: $this->_hasDataChanges = true;
352: return $this;
353: }
354:
355: public function ($reload=false)
356: {
357: if (is_null($this->_comments) || $reload) {
358: $this->_comments = Mage::getResourceModel('sales/order_shipment_comment_collection')
359: ->setShipmentFilter($this->getId())
360: ->setCreatedAtOrder();
361:
362: 363: 364: 365:
366: $this->_comments->load();
367:
368: if ($this->getId()) {
369: foreach ($this->_comments as $comment) {
370: $comment->setShipment($this);
371: }
372: }
373: }
374: return $this->_comments;
375: }
376:
377: 378: 379: 380: 381: 382: 383:
384: public function sendEmail($notifyCustomer = true, $comment = '')
385: {
386: $order = $this->getOrder();
387: $storeId = $order->getStore()->getId();
388:
389: if (!Mage::helper('sales')->canSendNewShipmentEmail($storeId)) {
390: return $this;
391: }
392:
393: $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
394: $copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $storeId);
395:
396: if (!$notifyCustomer && !$copyTo) {
397: return $this;
398: }
399:
400:
401: $appEmulation = Mage::getSingleton('core/app_emulation');
402: $initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($storeId);
403:
404: try {
405:
406: $paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
407: ->setIsSecureMode(true);
408: $paymentBlock->getMethod()->setStore($storeId);
409: $paymentBlockHtml = $paymentBlock->toHtml();
410: } catch (Exception $exception) {
411:
412: $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
413: throw $exception;
414: }
415:
416:
417: $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);
418:
419:
420: if ($order->getCustomerIsGuest()) {
421: $templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $storeId);
422: $customerName = $order->getBillingAddress()->getName();
423: } else {
424: $templateId = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $storeId);
425: $customerName = $order->getCustomerName();
426: }
427:
428: $mailer = Mage::getModel('core/email_template_mailer');
429: if ($notifyCustomer) {
430: $emailInfo = Mage::getModel('core/email_info');
431: $emailInfo->addTo($order->getCustomerEmail(), $customerName);
432: if ($copyTo && $copyMethod == 'bcc') {
433:
434: foreach ($copyTo as $email) {
435: $emailInfo->addBcc($email);
436: }
437: }
438: $mailer->addEmailInfo($emailInfo);
439: }
440:
441:
442: if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
443: foreach ($copyTo as $email) {
444: $emailInfo = Mage::getModel('core/email_info');
445: $emailInfo->addTo($email);
446: $mailer->addEmailInfo($emailInfo);
447: }
448: }
449:
450:
451: $mailer->setSender(Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $storeId));
452: $mailer->setStoreId($storeId);
453: $mailer->setTemplateId($templateId);
454: $mailer->setTemplateParams(array(
455: 'order' => $order,
456: 'shipment' => $this,
457: 'comment' => $comment,
458: 'billing' => $order->getBillingAddress(),
459: 'payment_html' => $paymentBlockHtml
460: )
461: );
462: $mailer->send();
463:
464: return $this;
465: }
466:
467: 468: 469: 470: 471: 472: 473:
474: public function sendUpdateEmail($notifyCustomer = true, $comment = '')
475: {
476: $order = $this->getOrder();
477: $storeId = $order->getStore()->getId();
478:
479: if (!Mage::helper('sales')->canSendShipmentCommentEmail($storeId)) {
480: return $this;
481: }
482:
483: $copyTo = $this->_getEmails(self::XML_PATH_UPDATE_EMAIL_COPY_TO);
484: $copyMethod = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_COPY_METHOD, $storeId);
485:
486: if (!$notifyCustomer && !$copyTo) {
487: return $this;
488: }
489:
490:
491: if ($order->getCustomerIsGuest()) {
492: $templateId = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_GUEST_TEMPLATE, $storeId);
493: $customerName = $order->getBillingAddress()->getName();
494: } else {
495: $templateId = Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_TEMPLATE, $storeId);
496: $customerName = $order->getCustomerName();
497: }
498:
499: $mailer = Mage::getModel('core/email_template_mailer');
500: if ($notifyCustomer) {
501: $emailInfo = Mage::getModel('core/email_info');
502: $emailInfo->addTo($order->getCustomerEmail(), $customerName);
503: if ($copyTo && $copyMethod == 'bcc') {
504:
505: foreach ($copyTo as $email) {
506: $emailInfo->addBcc($email);
507: }
508: }
509: $mailer->addEmailInfo($emailInfo);
510: }
511:
512:
513: if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
514: foreach ($copyTo as $email) {
515: $emailInfo = Mage::getModel('core/email_info');
516: $emailInfo->addTo($email);
517: $mailer->addEmailInfo($emailInfo);
518: }
519: }
520:
521:
522: $mailer->setSender(Mage::getStoreConfig(self::XML_PATH_UPDATE_EMAIL_IDENTITY, $storeId));
523: $mailer->setStoreId($storeId);
524: $mailer->setTemplateId($templateId);
525: $mailer->setTemplateParams(array(
526: 'order' => $order,
527: 'shipment' => $this,
528: 'comment' => $comment,
529: 'billing' => $order->getBillingAddress()
530: )
531: );
532: $mailer->send();
533:
534: return $this;
535: }
536:
537: protected function _getEmails($configPath)
538: {
539: $data = Mage::getStoreConfig($configPath, $this->getStoreId());
540: if (!empty($data)) {
541: return explode(',', $data);
542: }
543: return false;
544: }
545:
546: 547: 548: 549: 550:
551: protected function _beforeSave()
552: {
553: if ((!$this->getId() || null !== $this->_items) && !count($this->getAllItems())) {
554: Mage::throwException(
555: Mage::helper('sales')->__('Cannot create an empty shipment.')
556: );
557: }
558:
559: if (!$this->getOrderId() && $this->getOrder()) {
560: $this->setOrderId($this->getOrder()->getId());
561: $this->setShippingAddressId($this->getOrder()->getShippingAddress()->getId());
562: }
563: if ($this->getPackages()) {
564: $this->setPackages(serialize($this->getPackages()));
565: }
566:
567: return parent::_beforeSave();
568: }
569:
570: protected function _beforeDelete()
571: {
572: $this->_protectFromNonAdmin();
573: return parent::_beforeDelete();
574: }
575:
576: 577: 578: 579: 580:
581: protected function _afterSave()
582: {
583: if (null !== $this->_items) {
584: foreach ($this->_items as $item) {
585: $item->save();
586: }
587: }
588:
589: if (null !== $this->_tracks) {
590: foreach($this->_tracks as $track) {
591: $track->save();
592: }
593: }
594:
595: if (null !== $this->_comments) {
596: foreach($this->_comments as $comment) {
597: $comment->save();
598: }
599: }
600:
601: return parent::_afterSave();
602: }
603:
604: 605: 606: 607: 608:
609: public function getStore()
610: {
611: return $this->getOrder()->getStore();
612: }
613:
614: 615: 616: 617: 618: 619:
620: public function setShippingLabel($label)
621: {
622: $this->setData('shipping_label', $label);
623: return $this;
624: }
625:
626: 627: 628: 629: 630:
631: public function getShippingLabel()
632: {
633: $label = $this->getData('shipping_label');
634: if ($label) {
635: return $this->getResource()->getReadConnection()->decodeVarbinary($label);
636: }
637: return $label;
638: }
639: }
640: