PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 481 lines | 330 code | 44 blank | 107 comment | 51 complexity | ac306e143b3a9e136720a525b5b05d23 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Adminhtml
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Adminhtml sales order edit controller
  28. *
  29. * @category Mage
  30. * @package Mage_Adminhtml
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Adminhtml_Sales_Order_InvoiceController extends Mage_Adminhtml_Controller_Sales_Invoice
  34. {
  35. /**
  36. * Get requested items qty's from request
  37. */
  38. protected function _getItemQtys()
  39. {
  40. $data = $this->getRequest()->getParam('invoice');
  41. if (isset($data['items'])) {
  42. $qtys = $data['items'];
  43. } else {
  44. $qtys = array();
  45. }
  46. return $qtys;
  47. }
  48. /**
  49. * Initialize invoice model instance
  50. *
  51. * @return Mage_Sales_Model_Order_Invoice
  52. */
  53. protected function _initInvoice($update = false)
  54. {
  55. $this->_title($this->__('Sales'))->_title($this->__('Invoices'));
  56. $invoice = false;
  57. $itemsToInvoice = 0;
  58. $invoiceId = $this->getRequest()->getParam('invoice_id');
  59. $orderId = $this->getRequest()->getParam('order_id');
  60. if ($invoiceId) {
  61. $invoice = Mage::getModel('sales/order_invoice')->load($invoiceId);
  62. if (!$invoice->getId()) {
  63. $this->_getSession()->addError($this->__('The invoice no longer exists.'));
  64. return false;
  65. }
  66. } elseif ($orderId) {
  67. $order = Mage::getModel('sales/order')->load($orderId);
  68. /**
  69. * Check order existing
  70. */
  71. if (!$order->getId()) {
  72. $this->_getSession()->addError($this->__('The order no longer exists.'));
  73. return false;
  74. }
  75. /**
  76. * Check invoice create availability
  77. */
  78. if (!$order->canInvoice()) {
  79. $this->_getSession()->addError($this->__('The order does not allow creating an invoice.'));
  80. return false;
  81. }
  82. $savedQtys = $this->_getItemQtys();
  83. $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($savedQtys);
  84. if (!$invoice->getTotalQty()) {
  85. Mage::throwException($this->__('Cannot create an invoice without products.'));
  86. }
  87. }
  88. Mage::register('current_invoice', $invoice);
  89. return $invoice;
  90. }
  91. /**
  92. * Save data for invoice and related order
  93. *
  94. * @param Mage_Sales_Model_Order_Invoice $invoice
  95. * @return Mage_Adminhtml_Sales_Order_InvoiceController
  96. */
  97. protected function _saveInvoice($invoice)
  98. {
  99. $invoice->getOrder()->setIsInProcess(true);
  100. $transactionSave = Mage::getModel('core/resource_transaction')
  101. ->addObject($invoice)
  102. ->addObject($invoice->getOrder())
  103. ->save();
  104. return $this;
  105. }
  106. /**
  107. * Prepare shipment
  108. *
  109. * @param Mage_Sales_Model_Order_Invoice $invoice
  110. * @return Mage_Sales_Model_Order_Shipment
  111. */
  112. protected function _prepareShipment($invoice)
  113. {
  114. $savedQtys = $this->_getItemQtys();
  115. $shipment = Mage::getModel('sales/service_order', $invoice->getOrder())->prepareShipment($savedQtys);
  116. if (!$shipment->getTotalQty()) {
  117. return false;
  118. }
  119. $shipment->register();
  120. $tracks = $this->getRequest()->getPost('tracking');
  121. if ($tracks) {
  122. foreach ($tracks as $data) {
  123. $track = Mage::getModel('sales/order_shipment_track')
  124. ->addData($data);
  125. $shipment->addTrack($track);
  126. }
  127. }
  128. return $shipment;
  129. }
  130. /**
  131. * Invoice information page
  132. */
  133. public function viewAction()
  134. {
  135. $invoice = $this->_initInvoice();
  136. if ($invoice) {
  137. $this->_title(sprintf("#%s", $invoice->getIncrementId()));
  138. $this->loadLayout()
  139. ->_setActiveMenu('sales/order');
  140. $this->getLayout()->getBlock('sales_invoice_view')
  141. ->updateBackButtonUrl($this->getRequest()->getParam('come_from'));
  142. $this->renderLayout();
  143. }
  144. else {
  145. $this->_forward('noRoute');
  146. }
  147. }
  148. /**
  149. * Start create invoice action
  150. */
  151. public function startAction()
  152. {
  153. /**
  154. * Clear old values for invoice qty's
  155. */
  156. $this->_getSession()->getInvoiceItemQtys(true);
  157. $this->_redirect('*/*/new', array('order_id'=>$this->getRequest()->getParam('order_id')));
  158. }
  159. /**
  160. * Invoice create page
  161. */
  162. public function newAction()
  163. {
  164. $invoice = $this->_initInvoice();
  165. if ($invoice) {
  166. $this->_title($this->__('New Invoice'));
  167. if ($comment = Mage::getSingleton('adminhtml/session')->getCommentText(true)) {
  168. $invoice->setCommentText($comment);
  169. }
  170. $this->loadLayout()
  171. ->_setActiveMenu('sales/order')
  172. ->renderLayout();
  173. } else {
  174. $this->_redirect('*/sales_order/view', array('order_id'=>$this->getRequest()->getParam('order_id')));
  175. }
  176. }
  177. /**
  178. * Update items qty action
  179. */
  180. public function updateQtyAction()
  181. {
  182. try {
  183. $invoice = $this->_initInvoice(true);
  184. // Save invoice comment text in current invoice object in order to display it in corresponding view
  185. $invoiceRawData = $this->getRequest()->getParam('invoice');
  186. $invoiceRawCommentText = $invoiceRawData['comment_text'];
  187. $invoice->setCommentText($invoiceRawCommentText);
  188. $this->loadLayout();
  189. $response = $this->getLayout()->getBlock('order_items')->toHtml();
  190. } catch (Mage_Core_Exception $e) {
  191. $response = array(
  192. 'error' => true,
  193. 'message' => $e->getMessage()
  194. );
  195. $response = Mage::helper('core')->jsonEncode($response);
  196. } catch (Exception $e) {
  197. $response = array(
  198. 'error' => true,
  199. 'message' => $this->__('Cannot update item quantity.')
  200. );
  201. $response = Mage::helper('core')->jsonEncode($response);
  202. }
  203. $this->getResponse()->setBody($response);
  204. }
  205. /**
  206. * Save invoice
  207. * We can save only new invoice. Existing invoices are not editable
  208. */
  209. public function saveAction()
  210. {
  211. $data = $this->getRequest()->getPost('invoice');
  212. $orderId = $this->getRequest()->getParam('order_id');
  213. if (!empty($data['comment_text'])) {
  214. Mage::getSingleton('adminhtml/session')->setCommentText($data['comment_text']);
  215. }
  216. try {
  217. $invoice = $this->_initInvoice();
  218. if ($invoice) {
  219. if (!empty($data['capture_case'])) {
  220. $invoice->setRequestedCaptureCase($data['capture_case']);
  221. }
  222. if (!empty($data['comment_text'])) {
  223. $invoice->addComment(
  224. $data['comment_text'],
  225. isset($data['comment_customer_notify']),
  226. isset($data['is_visible_on_front'])
  227. );
  228. }
  229. $invoice->register();
  230. if (!empty($data['send_email'])) {
  231. $invoice->setEmailSent(true);
  232. }
  233. $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
  234. $invoice->getOrder()->setIsInProcess(true);
  235. $transactionSave = Mage::getModel('core/resource_transaction')
  236. ->addObject($invoice)
  237. ->addObject($invoice->getOrder());
  238. $shipment = false;
  239. if (!empty($data['do_shipment']) || (int) $invoice->getOrder()->getForcedDoShipmentWithInvoice()) {
  240. $shipment = $this->_prepareShipment($invoice);
  241. if ($shipment) {
  242. $shipment->setEmailSent($invoice->getEmailSent());
  243. $transactionSave->addObject($shipment);
  244. }
  245. }
  246. $transactionSave->save();
  247. if (!empty($data['do_shipment'])) {
  248. $this->_getSession()->addSuccess($this->__('The invoice and shipment have been created.'));
  249. } else {
  250. $this->_getSession()->addSuccess($this->__('The invoice has been created.'));
  251. }
  252. // send invoice/shipment emails
  253. $comment = '';
  254. if (isset($data['comment_customer_notify'])) {
  255. $comment = $data['comment_text'];
  256. }
  257. try {
  258. $invoice->sendEmail(!empty($data['send_email']), $comment);
  259. } catch (Exception $e) {
  260. Mage::logException($e);
  261. $this->_getSession()->addError($this->__('Unable to send the invoice email.'));
  262. }
  263. if ($shipment) {
  264. try {
  265. $shipment->sendEmail(!empty($data['send_email']));
  266. } catch (Exception $e) {
  267. Mage::logException($e);
  268. $this->_getSession()->addError($this->__('Unable to send the shipment email.'));
  269. }
  270. }
  271. Mage::getSingleton('adminhtml/session')->getCommentText(true);
  272. $this->_redirect('*/sales_order/view', array('order_id' => $orderId));
  273. } else {
  274. $this->_redirect('*/*/new', array('order_id' => $orderId));
  275. }
  276. return;
  277. } catch (Mage_Core_Exception $e) {
  278. $this->_getSession()->addError($e->getMessage());
  279. } catch (Exception $e) {
  280. $this->_getSession()->addError($this->__('Unable to save the invoice.'));
  281. Mage::logException($e);
  282. }
  283. $this->_redirect('*/*/new', array('order_id' => $orderId));
  284. }
  285. /**
  286. * Capture invoice action
  287. */
  288. public function captureAction()
  289. {
  290. if ($invoice = $this->_initInvoice()) {
  291. try {
  292. $invoice->capture();
  293. $this->_saveInvoice($invoice);
  294. $this->_getSession()->addSuccess($this->__('The invoice has been captured.'));
  295. } catch (Mage_Core_Exception $e) {
  296. $this->_getSession()->addError($e->getMessage());
  297. } catch (Exception $e) {
  298. $this->_getSession()->addError($this->__('Invoice capturing error.'));
  299. }
  300. $this->_redirect('*/*/view', array('invoice_id'=>$invoice->getId()));
  301. } else {
  302. $this->_forward('noRoute');
  303. }
  304. }
  305. /**
  306. * Cancel invoice action
  307. */
  308. public function cancelAction()
  309. {
  310. if ($invoice = $this->_initInvoice()) {
  311. try {
  312. $invoice->cancel();
  313. $this->_saveInvoice($invoice);
  314. $this->_getSession()->addSuccess($this->__('The invoice has been canceled.'));
  315. } catch (Mage_Core_Exception $e) {
  316. $this->_getSession()->addError($e->getMessage());
  317. } catch (Exception $e) {
  318. $this->_getSession()->addError($this->__('Invoice canceling error.'));
  319. }
  320. $this->_redirect('*/*/view', array('invoice_id'=>$invoice->getId()));
  321. } else {
  322. $this->_forward('noRoute');
  323. }
  324. }
  325. /**
  326. * Void invoice action
  327. */
  328. public function voidAction()
  329. {
  330. if ($invoice = $this->_initInvoice()) {
  331. try {
  332. $invoice->void();
  333. $this->_saveInvoice($invoice);
  334. $this->_getSession()->addSuccess($this->__('The invoice has been voided.'));
  335. } catch (Mage_Core_Exception $e) {
  336. $this->_getSession()->addError($e->getMessage());
  337. } catch (Exception $e) {
  338. $this->_getSession()->addError($this->__('Invoice voiding error.'));
  339. }
  340. $this->_redirect('*/*/view', array('invoice_id'=>$invoice->getId()));
  341. } else {
  342. $this->_forward('noRoute');
  343. }
  344. }
  345. public function addCommentAction()
  346. {
  347. try {
  348. $this->getRequest()->setParam('invoice_id', $this->getRequest()->getParam('id'));
  349. $data = $this->getRequest()->getPost('comment');
  350. if (empty($data['comment'])) {
  351. Mage::throwException($this->__('The Comment Text field cannot be empty.'));
  352. }
  353. $invoice = $this->_initInvoice();
  354. $invoice->addComment(
  355. $data['comment'],
  356. isset($data['is_customer_notified']),
  357. isset($data['is_visible_on_front'])
  358. );
  359. $invoice->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
  360. $invoice->save();
  361. $this->loadLayout();
  362. $response = $this->getLayout()->getBlock('invoice_comments')->toHtml();
  363. } catch (Mage_Core_Exception $e) {
  364. $response = array(
  365. 'error' => true,
  366. 'message' => $e->getMessage()
  367. );
  368. $response = Mage::helper('core')->jsonEncode($response);
  369. } catch (Exception $e) {
  370. $response = array(
  371. 'error' => true,
  372. 'message' => $this->__('Cannot add new comment.')
  373. );
  374. $response = Mage::helper('core')->jsonEncode($response);
  375. }
  376. $this->getResponse()->setBody($response);
  377. }
  378. /**
  379. * Decides if we need to create dummy invoice item or not
  380. * for eaxample we don't need create dummy parent if all
  381. * children are not in process
  382. *
  383. * @deprecated after 1.4, Mage_Sales_Model_Service_Order used
  384. * @param Mage_Sales_Model_Order_Item $item
  385. * @param array $qtys
  386. * @return bool
  387. */
  388. protected function _needToAddDummy($item, $qtys) {
  389. if ($item->getHasChildren()) {
  390. foreach ($item->getChildrenItems() as $child) {
  391. if (isset($qtys[$child->getId()]) && $qtys[$child->getId()] > 0) {
  392. return true;
  393. }
  394. }
  395. return false;
  396. } else if($item->getParentItem()) {
  397. if (isset($qtys[$item->getParentItem()->getId()]) && $qtys[$item->getParentItem()->getId()] > 0) {
  398. return true;
  399. }
  400. return false;
  401. }
  402. }
  403. /**
  404. * Decides if we need to create dummy shipment item or not
  405. * for eaxample we don't need create dummy parent if all
  406. * children are not in process
  407. *
  408. * @deprecated after 1.4, Mage_Sales_Model_Service_Order used
  409. * @param Mage_Sales_Model_Order_Item $item
  410. * @param array $qtys
  411. * @return bool
  412. */
  413. protected function _needToAddDummyForShipment($item, $qtys) {
  414. if ($item->getHasChildren()) {
  415. foreach ($item->getChildrenItems() as $child) {
  416. if ($child->getIsVirtual()) {
  417. continue;
  418. }
  419. if (isset($qtys[$child->getId()]) && $qtys[$child->getId()] > 0) {
  420. return true;
  421. }
  422. }
  423. if ($item->isShipSeparately()) {
  424. return true;
  425. }
  426. return false;
  427. } else if($item->getParentItem()) {
  428. if ($item->getIsVirtual()) {
  429. return false;
  430. }
  431. if (isset($qtys[$item->getParentItem()->getId()]) && $qtys[$item->getParentItem()->getId()] > 0) {
  432. return true;
  433. }
  434. return false;
  435. }
  436. }
  437. }