PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 445 lines | 312 code | 34 blank | 99 comment | 53 complexity | 0fb67bdb198d35106d8e98b27d99b01c 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 creditmemo controller
  28. *
  29. * @category Mage
  30. * @package Mage_Adminhtml
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Adminhtml_Sales_Order_CreditmemoController extends Mage_Adminhtml_Controller_Sales_Creditmemo
  34. {
  35. /**
  36. * Get requested items qtys and return to stock flags
  37. */
  38. protected function _getItemData()
  39. {
  40. $data = $this->getRequest()->getParam('creditmemo');
  41. if (!$data) {
  42. $data = Mage::getSingleton('adminhtml/session')->getFormData(true);
  43. }
  44. if (isset($data['items'])) {
  45. $qtys = $data['items'];
  46. } else {
  47. $qtys = array();
  48. }
  49. return $qtys;
  50. }
  51. /**
  52. * Check if creditmeno can be created for order
  53. * @param Mage_Sales_Model_Order $order
  54. * @return bool
  55. */
  56. protected function _canCreditmemo($order)
  57. {
  58. /**
  59. * Check order existing
  60. */
  61. if (!$order->getId()) {
  62. $this->_getSession()->addError($this->__('The order no longer exists.'));
  63. return false;
  64. }
  65. /**
  66. * Check creditmemo create availability
  67. */
  68. if (!$order->canCreditmemo()) {
  69. $this->_getSession()->addError($this->__('Cannot create credit memo for the order.'));
  70. return false;
  71. }
  72. return true;
  73. }
  74. /**
  75. * Initialize requested invoice instance
  76. * @param unknown_type $order
  77. */
  78. protected function _initInvoice($order)
  79. {
  80. $invoiceId = $this->getRequest()->getParam('invoice_id');
  81. if ($invoiceId) {
  82. $invoice = Mage::getModel('sales/order_invoice')
  83. ->load($invoiceId)
  84. ->setOrder($order);
  85. if ($invoice->getId()) {
  86. return $invoice;
  87. }
  88. }
  89. return false;
  90. }
  91. /**
  92. * Initialize creditmemo model instance
  93. *
  94. * @return Mage_Sales_Model_Order_Creditmemo
  95. */
  96. protected function _initCreditmemo($update = false)
  97. {
  98. $this->_title($this->__('Sales'))->_title($this->__('Credit Memos'));
  99. $creditmemo = false;
  100. $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
  101. $orderId = $this->getRequest()->getParam('order_id');
  102. if ($creditmemoId) {
  103. $creditmemo = Mage::getModel('sales/order_creditmemo')->load($creditmemoId);
  104. } elseif ($orderId) {
  105. $data = $this->getRequest()->getParam('creditmemo');
  106. $order = Mage::getModel('sales/order')->load($orderId);
  107. $invoice = $this->_initInvoice($order);
  108. if (!$this->_canCreditmemo($order)) {
  109. return false;
  110. }
  111. $savedData = $this->_getItemData();
  112. $qtys = array();
  113. $backToStock = array();
  114. foreach ($savedData as $orderItemId =>$itemData) {
  115. if (isset($itemData['qty'])) {
  116. $qtys[$orderItemId] = $itemData['qty'];
  117. }
  118. if (isset($itemData['back_to_stock'])) {
  119. $backToStock[$orderItemId] = true;
  120. }
  121. }
  122. $data['qtys'] = $qtys;
  123. $service = Mage::getModel('sales/service_order', $order);
  124. if ($invoice) {
  125. $creditmemo = $service->prepareInvoiceCreditmemo($invoice, $data);
  126. } else {
  127. $creditmemo = $service->prepareCreditmemo($data);
  128. }
  129. /**
  130. * Process back to stock flags
  131. */
  132. foreach ($creditmemo->getAllItems() as $creditmemoItem) {
  133. $orderItem = $creditmemoItem->getOrderItem();
  134. $parentId = $orderItem->getParentItemId();
  135. if (isset($backToStock[$orderItem->getId()])) {
  136. $creditmemoItem->setBackToStock(true);
  137. } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
  138. $creditmemoItem->setBackToStock(true);
  139. } elseif (empty($savedData)) {
  140. $creditmemoItem->setBackToStock(Mage::helper('cataloginventory')->isAutoReturnEnabled());
  141. } else {
  142. $creditmemoItem->setBackToStock(false);
  143. }
  144. }
  145. }
  146. $args = array('creditmemo' => $creditmemo, 'request' => $this->getRequest());
  147. Mage::dispatchEvent('adminhtml_sales_order_creditmemo_register_before', $args);
  148. Mage::register('current_creditmemo', $creditmemo);
  149. return $creditmemo;
  150. }
  151. /**
  152. * Save creditmemo and related order, invoice in one transaction
  153. * @param Mage_Sales_Model_Order_Creditmemo $creditmemo
  154. */
  155. protected function _saveCreditmemo($creditmemo)
  156. {
  157. $transactionSave = Mage::getModel('core/resource_transaction')
  158. ->addObject($creditmemo)
  159. ->addObject($creditmemo->getOrder());
  160. if ($creditmemo->getInvoice()) {
  161. $transactionSave->addObject($creditmemo->getInvoice());
  162. }
  163. $transactionSave->save();
  164. return $this;
  165. }
  166. /**
  167. * creditmemo information page
  168. */
  169. public function viewAction()
  170. {
  171. $creditmemo = $this->_initCreditmemo();
  172. if ($creditmemo) {
  173. if ($creditmemo->getInvoice()) {
  174. $this->_title($this->__("View Memo for #%s", $creditmemo->getInvoice()->getIncrementId()));
  175. } else {
  176. $this->_title($this->__("View Memo"));
  177. }
  178. $this->loadLayout();
  179. $this->getLayout()->getBlock('sales_creditmemo_view')
  180. ->updateBackButtonUrl($this->getRequest()->getParam('come_from'));
  181. $this->_setActiveMenu('sales/order')
  182. ->renderLayout();
  183. } else {
  184. $this->_forward('noRoute');
  185. }
  186. }
  187. /**
  188. * Start create creditmemo action
  189. */
  190. public function startAction()
  191. {
  192. /**
  193. * Clear old values for creditmemo qty's
  194. */
  195. $this->_redirect('*/*/new', array('_current'=>true));
  196. }
  197. /**
  198. * creditmemo create page
  199. */
  200. public function newAction()
  201. {
  202. if ($creditmemo = $this->_initCreditmemo()) {
  203. if ($creditmemo->getInvoice()) {
  204. $this->_title($this->__("New Memo for #%s", $creditmemo->getInvoice()->getIncrementId()));
  205. } else {
  206. $this->_title($this->__("New Memo"));
  207. }
  208. if ($comment = Mage::getSingleton('adminhtml/session')->getCommentText(true)) {
  209. $creditmemo->setCommentText($comment);
  210. }
  211. $this->loadLayout()
  212. ->_setActiveMenu('sales/order')
  213. ->renderLayout();
  214. } else {
  215. $this->_forward('noRoute');
  216. }
  217. }
  218. /**
  219. * Update items qty action
  220. */
  221. public function updateQtyAction()
  222. {
  223. try {
  224. $creditmemo = $this->_initCreditmemo(true);
  225. $this->loadLayout();
  226. $response = $this->getLayout()->getBlock('order_items')->toHtml();
  227. } catch (Mage_Core_Exception $e) {
  228. $response = array(
  229. 'error' => true,
  230. 'message' => $e->getMessage()
  231. );
  232. $response = Mage::helper('core')->jsonEncode($response);
  233. } catch (Exception $e) {
  234. $response = array(
  235. 'error' => true,
  236. 'message' => $this->__('Cannot update the item\'s quantity.')
  237. );
  238. $response = Mage::helper('core')->jsonEncode($response);
  239. }
  240. $this->getResponse()->setBody($response);
  241. }
  242. /**
  243. * Save creditmemo
  244. * We can save only new creditmemo. Existing creditmemos are not editable
  245. */
  246. public function saveAction()
  247. {
  248. $data = $this->getRequest()->getPost('creditmemo');
  249. if (!empty($data['comment_text'])) {
  250. Mage::getSingleton('adminhtml/session')->setCommentText($data['comment_text']);
  251. }
  252. try {
  253. $creditmemo = $this->_initCreditmemo();
  254. if ($creditmemo) {
  255. if (($creditmemo->getGrandTotal() <=0) && (!$creditmemo->getAllowZeroGrandTotal())) {
  256. Mage::throwException(
  257. $this->__('Credit memo\'s total must be positive.')
  258. );
  259. }
  260. $comment = '';
  261. if (!empty($data['comment_text'])) {
  262. $creditmemo->addComment(
  263. $data['comment_text'],
  264. isset($data['comment_customer_notify']),
  265. isset($data['is_visible_on_front'])
  266. );
  267. if (isset($data['comment_customer_notify'])) {
  268. $comment = $data['comment_text'];
  269. }
  270. }
  271. if (isset($data['do_refund'])) {
  272. $creditmemo->setRefundRequested(true);
  273. }
  274. if (isset($data['do_offline'])) {
  275. $creditmemo->setOfflineRequested((bool)(int)$data['do_offline']);
  276. }
  277. $creditmemo->register();
  278. if (!empty($data['send_email'])) {
  279. $creditmemo->setEmailSent(true);
  280. }
  281. $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
  282. $this->_saveCreditmemo($creditmemo);
  283. $creditmemo->sendEmail(!empty($data['send_email']), $comment);
  284. $this->_getSession()->addSuccess($this->__('The credit memo has been created.'));
  285. Mage::getSingleton('adminhtml/session')->getCommentText(true);
  286. $this->_redirect('*/sales_order/view', array('order_id' => $creditmemo->getOrderId()));
  287. return;
  288. } else {
  289. $this->_forward('noRoute');
  290. return;
  291. }
  292. } catch (Mage_Core_Exception $e) {
  293. $this->_getSession()->addError($e->getMessage());
  294. Mage::getSingleton('adminhtml/session')->setFormData($data);
  295. } catch (Exception $e) {
  296. Mage::logException($e);
  297. $this->_getSession()->addError($this->__('Cannot save the credit memo.'));
  298. }
  299. $this->_redirect('*/*/new', array('_current' => true));
  300. }
  301. /**
  302. * Cancel creditmemo action
  303. */
  304. public function cancelAction()
  305. {
  306. if ($creditmemo = $this->_initCreditmemo()) {
  307. try {
  308. $creditmemo->cancel();
  309. $this->_saveCreditmemo($creditmemo);
  310. $this->_getSession()->addSuccess($this->__('The credit memo has been canceled.'));
  311. } catch (Mage_Core_Exception $e) {
  312. $this->_getSession()->addError($e->getMessage());
  313. } catch (Exception $e) {
  314. $this->_getSession()->addError($this->__('Unable to cancel the credit memo.'));
  315. }
  316. $this->_redirect('*/*/view', array('creditmemo_id'=>$creditmemo->getId()));
  317. } else {
  318. $this->_forward('noRoute');
  319. }
  320. }
  321. /**
  322. * Void creditmemo action
  323. */
  324. public function voidAction()
  325. {
  326. if ($invoice = $this->_initCreditmemo()) {
  327. try {
  328. $creditmemo->void();
  329. $this->_saveCreditmemo($creditmemo);
  330. $this->_getSession()->addSuccess($this->__('The credit memo has been voided.'));
  331. } catch (Mage_Core_Exception $e) {
  332. $this->_getSession()->addError($e->getMessage());
  333. } catch (Exception $e) {
  334. $this->_getSession()->addError($this->__('Unable to void the credit memo.'));
  335. }
  336. $this->_redirect('*/*/view', array('creditmemo_id'=>$creditmemo->getId()));
  337. } else {
  338. $this->_forward('noRoute');
  339. }
  340. }
  341. /**
  342. * Add comment to creditmemo history
  343. */
  344. public function addCommentAction()
  345. {
  346. try {
  347. $this->getRequest()->setParam(
  348. 'creditmemo_id',
  349. $this->getRequest()->getParam('id')
  350. );
  351. $data = $this->getRequest()->getPost('comment');
  352. if (empty($data['comment'])) {
  353. Mage::throwException($this->__('The Comment Text field cannot be empty.'));
  354. }
  355. $creditmemo = $this->_initCreditmemo();
  356. $creditmemo->addComment(
  357. $data['comment'],
  358. isset($data['is_customer_notified']),
  359. isset($data['is_visible_on_front'])
  360. );
  361. $creditmemo->save();
  362. $creditmemo->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
  363. $this->loadLayout();
  364. $response = $this->getLayout()->getBlock('creditmemo_comments')->toHtml();
  365. } catch (Mage_Core_Exception $e) {
  366. $response = array(
  367. 'error' => true,
  368. 'message' => $e->getMessage()
  369. );
  370. $response = Mage::helper('core')->jsonEncode($response);
  371. } catch (Exception $e) {
  372. $response = array(
  373. 'error' => true,
  374. 'message' => $this->__('Cannot add new comment.')
  375. );
  376. $response = Mage::helper('core')->jsonEncode($response);
  377. }
  378. $this->getResponse()->setBody($response);
  379. }
  380. /**
  381. * Decides if we need to create dummy invoice item or not
  382. * for eaxample we don't need create dummy parent if all
  383. * children are not in process
  384. *
  385. * @deprecated after 1.4, Mage_Sales_Model_Service_Order used
  386. * @param Mage_Sales_Model_Order_Item $item
  387. * @param array $qtys
  388. * @return bool
  389. */
  390. protected function _needToAddDummy($item, $qtys) {
  391. if ($item->getHasChildren()) {
  392. foreach ($item->getChildrenItems() as $child) {
  393. if (isset($qtys[$child->getId()])
  394. && isset($qtys[$child->getId()]['qty'])
  395. && $qtys[$child->getId()]['qty'] > 0)
  396. {
  397. return true;
  398. }
  399. }
  400. return false;
  401. } else if($item->getParentItem()) {
  402. if (isset($qtys[$item->getParentItem()->getId()])
  403. && isset($qtys[$item->getParentItem()->getId()]['qty'])
  404. && $qtys[$item->getParentItem()->getId()]['qty'] > 0)
  405. {
  406. return true;
  407. }
  408. return false;
  409. }
  410. }
  411. }