PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Adminhtml/Block/Sales/Items/Abstract.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 616 lines | 338 code | 47 blank | 231 comment | 62 complexity | d65fc7fad538e702aa751eea030cc0ed 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. * Abstract items renderer
  28. *
  29. * @category Mage
  30. * @package Mage_Adminhtml
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Adminhtml_Block_Sales_Items_Abstract extends Mage_Adminhtml_Block_Template
  34. {
  35. /**
  36. * Renderers with render type key
  37. * block => the block name
  38. * template => the template file
  39. * renderer => the block object
  40. *
  41. * @var array
  42. */
  43. protected $_itemRenders = array();
  44. /**
  45. * Renderers for other column with column name key
  46. * block => the block name
  47. * template => the template file
  48. * renderer => the block object
  49. *
  50. * @var array
  51. */
  52. protected $_columnRenders = array();
  53. /**
  54. * Flag - if it is set method canEditQty will return value of it
  55. *
  56. * @var boolean | null
  57. */
  58. protected $_canEditQty = null;
  59. /**
  60. * Init block
  61. *
  62. */
  63. protected function _construct()
  64. {
  65. $this->addColumnRender('qty', 'adminhtml/sales_items_column_qty', 'sales/items/column/qty.phtml');
  66. $this->addColumnRender('name', 'adminhtml/sales_items_column_name', 'sales/items/column/name.phtml');
  67. parent::_construct();
  68. }
  69. /**
  70. * Add item renderer
  71. *
  72. * @param string $type
  73. * @param string $block
  74. * @param string $template
  75. * @return Mage_Adminhtml_Block_Sales_Items_Abstract
  76. */
  77. public function addItemRender($type, $block, $template)
  78. {
  79. $this->_itemRenders[$type] = array(
  80. 'block' => $block,
  81. 'template' => $template,
  82. 'renderer' => null
  83. );
  84. return $this;
  85. }
  86. /**
  87. * Add column renderer
  88. *
  89. * @param string $column
  90. * @param string $block
  91. * @param string $template
  92. * @return Mage_Adminhtml_Block_Sales_Items_Abstract
  93. */
  94. public function addColumnRender($column, $block, $template, $type=null)
  95. {
  96. if (!is_null($type)) {
  97. $column .= '_' . $type;
  98. }
  99. $this->_columnRenders[$column] = array(
  100. 'block' => $block,
  101. 'template' => $template,
  102. 'renderer' => null
  103. );
  104. return $this;
  105. }
  106. /**
  107. * Retrieve item renderer block
  108. *
  109. * @param string $type
  110. * @return Mage_Core_Block_Abstract
  111. */
  112. public function getItemRenderer($type)
  113. {
  114. if (!isset($this->_itemRenders[$type])) {
  115. $type = 'default';
  116. }
  117. if (is_null($this->_itemRenders[$type]['renderer'])) {
  118. $this->_itemRenders[$type]['renderer'] = $this->getLayout()
  119. ->createBlock($this->_itemRenders[$type]['block'])
  120. ->setTemplate($this->_itemRenders[$type]['template']);
  121. foreach ($this->_columnRenders as $columnType=>$renderer) {
  122. $this->_itemRenders[$type]['renderer']->addColumnRender($columnType, $renderer['block'], $renderer['template']);
  123. }
  124. }
  125. return $this->_itemRenders[$type]['renderer'];
  126. }
  127. /**
  128. * Retrieve column renderer block
  129. *
  130. * @param string $column
  131. * @param string $compositePart
  132. * @return Mage_Core_Block_Abstract
  133. */
  134. public function getColumnRenderer($column, $compositePart='')
  135. {
  136. if (isset($this->_columnRenders[$column . '_' . $compositePart])) {
  137. $column .= '_' . $compositePart;
  138. }
  139. if (!isset($this->_columnRenders[$column])) {
  140. return false;
  141. }
  142. if (is_null($this->_columnRenders[$column]['renderer'])) {
  143. $this->_columnRenders[$column]['renderer'] = $this->getLayout()
  144. ->createBlock($this->_columnRenders[$column]['block'])
  145. ->setTemplate($this->_columnRenders[$column]['template'])
  146. ->setRenderedBlock($this);
  147. }
  148. return $this->_columnRenders[$column]['renderer'];
  149. }
  150. /**
  151. * Retrieve rendered item html content
  152. *
  153. * @param Varien_Object $item
  154. * @return string
  155. */
  156. public function getItemHtml(Varien_Object $item)
  157. {
  158. if ($item->getOrderItem()) {
  159. $type = $item->getOrderItem()->getProductType();
  160. } else {
  161. $type = $item->getProductType();
  162. }
  163. return $this->getItemRenderer($type)
  164. ->setItem($item)
  165. ->setCanEditQty($this->canEditQty())
  166. ->toHtml();
  167. }
  168. /**
  169. * Retrieve rendered item extra info html content
  170. *
  171. * @param Varien_Object $item
  172. * @return string
  173. */
  174. public function getItemExtraInfoHtml(Varien_Object $item)
  175. {
  176. $extraInfoBlock = $this->getChild('order_item_extra_info');
  177. if ($extraInfoBlock) {
  178. return $extraInfoBlock
  179. ->setItem($item)
  180. ->toHtml();
  181. }
  182. return '';
  183. }
  184. /**
  185. * Retrieve rendered column html content
  186. *
  187. * @param Varien_Object $item
  188. * @param string $column the column key
  189. * @param string $field the custom item field
  190. * @return string
  191. */
  192. public function getColumnHtml(Varien_Object $item, $column, $field = null)
  193. {
  194. if ($item->getOrderItem()) {
  195. $block = $this->getColumnRenderer($column, $item->getOrderItem()->getProductType());
  196. } else {
  197. $block = $this->getColumnRenderer($column, $item->getProductType());
  198. }
  199. if ($block) {
  200. $block->setItem($item);
  201. if (!is_null($field)) {
  202. $block->setField($field);
  203. }
  204. return $block->toHtml();
  205. }
  206. return '&nbsp;';
  207. }
  208. public function getCreditmemo()
  209. {
  210. return Mage::registry('current_creditmemo');
  211. }
  212. /**
  213. * ######################### SALES ##################################
  214. */
  215. /**
  216. * Retrieve available order
  217. *
  218. * @return Mage_Sales_Model_Order
  219. */
  220. public function getOrder()
  221. {
  222. if ($this->hasOrder()) {
  223. return $this->getData('order');
  224. }
  225. if (Mage::registry('current_order')) {
  226. return Mage::registry('current_order');
  227. }
  228. if (Mage::registry('order')) {
  229. return Mage::registry('order');
  230. }
  231. if ($this->getInvoice())
  232. {
  233. return $this->getInvoice()->getOrder();
  234. }
  235. if ($this->getCreditmemo())
  236. {
  237. return $this->getCreditmemo()->getOrder();
  238. }
  239. if ($this->getItem()->getOrder())
  240. {
  241. return $this->getItem()->getOrder();
  242. }
  243. Mage::throwException(Mage::helper('sales')->__('Cannot get order instance'));
  244. }
  245. /**
  246. * Retrieve price data object
  247. *
  248. * @return Mage_Sales_Model_Order
  249. */
  250. public function getPriceDataObject()
  251. {
  252. $obj = $this->getData('price_data_object');
  253. if (is_null($obj)) {
  254. return $this->getOrder();
  255. }
  256. return $obj;
  257. }
  258. /**
  259. * Retrieve price attribute html content
  260. *
  261. * @param string $code
  262. * @param bool $strong
  263. * @param string $separator
  264. * @return string
  265. */
  266. public function displayPriceAttribute($code, $strong = false, $separator = '<br />')
  267. {
  268. if ($code == 'tax_amount' && $this->getOrder()->getRowTaxDisplayPrecision()) {
  269. return $this->displayRoundedPrices(
  270. $this->getPriceDataObject()->getData('base_'.$code),
  271. $this->getPriceDataObject()->getData($code),
  272. $this->getOrder()->getRowTaxDisplayPrecision(),
  273. $strong,
  274. $separator
  275. );
  276. } else {
  277. return $this->displayPrices(
  278. $this->getPriceDataObject()->getData('base_'.$code),
  279. $this->getPriceDataObject()->getData($code),
  280. $strong,
  281. $separator
  282. );
  283. }
  284. }
  285. /**
  286. * Retrieve price formated html content
  287. *
  288. * @param float $basePrice
  289. * @param float $price
  290. * @param bool $strong
  291. * @param string $separator
  292. * @return string
  293. */
  294. public function displayPrices($basePrice, $price, $strong = false, $separator = '<br />')
  295. {
  296. return $this->displayRoundedPrices($basePrice, $price, 2, $strong, $separator);
  297. }
  298. /**
  299. * Display base and regular prices with specified rounding precision
  300. *
  301. * @param float $basePrice
  302. * @param float $price
  303. * @param int $precision
  304. * @param bool $strong
  305. * @param string $separator
  306. * @return string
  307. */
  308. public function displayRoundedPrices($basePrice, $price, $precision=2, $strong = false, $separator = '<br />')
  309. {
  310. if ($this->getOrder()->isCurrencyDifferent()) {
  311. $res = '';
  312. $res.= $this->getOrder()->formatBasePricePrecision($basePrice, $precision);
  313. $res.= $separator;
  314. $res.= $this->getOrder()->formatPricePrecision($price, $precision, true);
  315. }
  316. else {
  317. $res = $this->getOrder()->formatPricePrecision($price, $precision);
  318. if ($strong) {
  319. $res = '<strong>'.$res.'</strong>';
  320. }
  321. }
  322. return $res;
  323. }
  324. /**
  325. * Retrieve include tax html formated content
  326. *
  327. * @param Varien_Object $item
  328. * @return string
  329. */
  330. public function displayPriceInclTax(Varien_Object $item)
  331. {
  332. $qty = ($item->getQtyOrdered() ? $item->getQtyOrdered() : ($item->getQty() ? $item->getQty() : 1));
  333. $baseTax = ($item->getTaxBeforeDiscount() ? $item->getTaxBeforeDiscount() : ($item->getTaxAmount() ? $item->getTaxAmount() : 0));
  334. $tax = ($item->getBaseTaxBeforeDiscount() ? $item->getBaseTaxBeforeDiscount() : ($item->getBaseTaxAmount() ? $item->getBaseTaxAmount() : 0));
  335. $basePriceTax = 0;
  336. $priceTax = 0;
  337. if (floatval($qty)) {
  338. $basePriceTax = $item->getBasePrice()+$baseTax/$qty;
  339. $priceTax = $item->getPrice()+$tax/$qty;
  340. }
  341. return $this->displayPrices(
  342. $this->getOrder()->getStore()->roundPrice($basePriceTax),
  343. $this->getOrder()->getStore()->roundPrice($priceTax)
  344. );
  345. }
  346. /**
  347. * Retrieve subtotal price include tax html formated content
  348. *
  349. * @param Varien_Object $item
  350. * @return string
  351. */
  352. public function displaySubtotalInclTax($item)
  353. {
  354. $baseTax = ($item->getTaxBeforeDiscount() ? $item->getTaxBeforeDiscount() : ($item->getTaxAmount() ? $item->getTaxAmount() : 0));
  355. $tax = ($item->getBaseTaxBeforeDiscount() ? $item->getBaseTaxBeforeDiscount() : ($item->getBaseTaxAmount() ? $item->getBaseTaxAmount() : 0));
  356. return $this->displayPrices(
  357. $item->getBaseRowTotal()+$baseTax,
  358. $item->getRowTotal()+$tax
  359. );
  360. }
  361. /**
  362. * Retrieve tax calculation html content
  363. *
  364. * @param Varien_Object $item
  365. * @return string
  366. */
  367. public function displayTaxCalculation(Varien_Object $item)
  368. {
  369. if ($item->getTaxPercent() && $item->getTaxString() == '') {
  370. $percents = array($item->getTaxPercent());
  371. } else if ($item->getTaxString()) {
  372. $percents = explode(Mage_Tax_Model_Config::CALCULATION_STRING_SEPARATOR, $item->getTaxString());
  373. } else {
  374. return '0%';
  375. }
  376. foreach ($percents as &$percent) {
  377. $percent = sprintf('%.2f%%', $percent);
  378. }
  379. return implode(' + ', $percents);
  380. }
  381. /**
  382. * Retrieve tax with persent html content
  383. *
  384. * @param Varien_Object $item
  385. * @return string
  386. */
  387. public function displayTaxPercent(Varien_Object $item)
  388. {
  389. if ($item->getTaxPercent()) {
  390. return sprintf('%s%%', $item->getTaxPercent() + 0);
  391. } else {
  392. return '0%';
  393. }
  394. }
  395. /**
  396. * INVOICES
  397. */
  398. /**
  399. * Check shipment availability for current invoice
  400. *
  401. * @return bool
  402. */
  403. public function canCreateShipment()
  404. {
  405. foreach ($this->getInvoice()->getAllItems() as $item) {
  406. if ($item->getOrderItem()->getQtyToShip()) {
  407. return true;
  408. }
  409. }
  410. return false;
  411. }
  412. /**
  413. * Setter for flag _canEditQty
  414. *
  415. * @return Mage_Adminhtml_Block_Sales_Items_Abstract
  416. * @see self::_canEditQty
  417. * @see self::canEditQty
  418. */
  419. public function setCanEditQty($value) {
  420. $this->_canEditQty = $value;
  421. return $this;
  422. }
  423. /**
  424. * Check availability to edit quantity of item
  425. *
  426. * @return boolean
  427. */
  428. public function canEditQty()
  429. {
  430. /**
  431. * If parent block has set
  432. */
  433. if (!is_null($this->_canEditQty)) {
  434. return $this->_canEditQty;
  435. }
  436. /**
  437. * Disable editing of quantity of item if creating of shipment forced
  438. * and ship partially disabled for order
  439. */
  440. if ($this->getOrder()->getForcedDoShipmentWithInvoice()
  441. && ($this->canShipPartially($this->getOrder()) || $this->canShipPartiallyItem($this->getOrder()))
  442. ) {
  443. return false;
  444. }
  445. if ($this->getOrder()->getPayment()->canCapture()) {
  446. return $this->getOrder()->getPayment()->canCapturePartial();
  447. }
  448. return true;
  449. }
  450. public function canCapture()
  451. {
  452. if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/capture')) {
  453. return $this->getInvoice()->canCapture();
  454. }
  455. return false;
  456. }
  457. public function formatPrice($price)
  458. {
  459. return $this->getOrder()->formatPrice($price);
  460. }
  461. /**
  462. * Retrieve source
  463. *
  464. * @return Mage_Sales_Model_Order_Invoice
  465. */
  466. public function getSource()
  467. {
  468. return $this->getInvoice();
  469. }
  470. /**
  471. * Retrieve invoice model instance
  472. *
  473. * @return Mage_Sales_Model_Invoice
  474. */
  475. public function getInvoice()
  476. {
  477. return Mage::registry('current_invoice');
  478. }
  479. /**
  480. * CREDITMEMO
  481. */
  482. public function canReturnToStock() {
  483. $canReturnToStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_CAN_SUBTRACT);
  484. if (Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_CAN_SUBTRACT)) {
  485. return true;
  486. } else {
  487. return false;
  488. }
  489. }
  490. /**
  491. * Whether to show 'Return to stock' checkbox for item
  492. * @param Mage_Sales_Model_Order_Creditmemo_Item $item
  493. * @return bool
  494. */
  495. public function canReturnItemToStock($item=null) {
  496. $canReturnToStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_CAN_SUBTRACT);
  497. if (!is_null($item)) {
  498. if (!$item->hasCanReturnToStock()) {
  499. $product = Mage::getModel('catalog/product')->load($item->getOrderItem()->getProductId());
  500. if ( $product->getId() && $product->getStockItem()->getManageStock() ) {
  501. $item->setCanReturnToStock(true);
  502. }
  503. else {
  504. $item->setCanReturnToStock(false);
  505. }
  506. }
  507. $canReturnToStock = $item->getCanReturnToStock();
  508. }
  509. return $canReturnToStock;
  510. }
  511. /**
  512. * Whether to show 'Return to stock' column for item parent
  513. * @param Mage_Sales_Model_Order_Creditmemo_Item $item
  514. * @return bool
  515. */
  516. public function canParentReturnToStock($item = null)
  517. {
  518. $canReturnToStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_CAN_SUBTRACT);
  519. if (!is_null($item)) {
  520. if ( $item->getCreditmemo()->getOrder()->hasCanReturnToStock() ) {
  521. $canReturnToStock = $item->getCreditmemo()->getOrder()->getCanReturnToStock();
  522. }
  523. } elseif ( $this->getOrder()->hasCanReturnToStock() ) {
  524. $canReturnToStock = $this->getOrder()->getCanReturnToStock();
  525. }
  526. return $canReturnToStock;
  527. }
  528. /**
  529. * Return true if can ship partially
  530. *
  531. * @param Mage_Sales_Model_Order|null $order
  532. * @return boolean
  533. */
  534. public function canShipPartially($order = null)
  535. {
  536. if (is_null($order) || !$order instanceof Mage_Sales_Model_Order) {
  537. $order = Mage::registry('current_shipment')->getOrder();
  538. }
  539. $value = $order->getCanShipPartially();
  540. if (!is_null($value) && !$value) {
  541. return false;
  542. }
  543. return true;
  544. }
  545. /**
  546. * Return true if can ship items partially
  547. *
  548. * @param Mage_Sales_Model_Order|null $order
  549. * @return boolean
  550. */
  551. public function canShipPartiallyItem($order = null)
  552. {
  553. if (is_null($order) || !$order instanceof Mage_Sales_Model_Order) {
  554. $order = Mage::registry('current_shipment')->getOrder();
  555. }
  556. $value = $order->getCanShipPartiallyItem();
  557. if (!is_null($value) && !$value) {
  558. return false;
  559. }
  560. return true;
  561. }
  562. public function isShipmentRegular()
  563. {
  564. if (!$this->canShipPartiallyItem() || !$this->canShipPartially()) {
  565. return false;
  566. }
  567. return true;
  568. }
  569. }