Status.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Model\ResourceModel\Order;
  7. use Magento\Framework\App\ResourceConnection;
  8. use Psr\Log\LoggerInterface as LogWriter;
  9. use Magento\Framework\Exception\LocalizedException;
  10. use Magento\SalesSequence\Model\Manager;
  11. use \Magento\Sales\Model\ResourceModel\EntityAbstract;
  12. use \Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
  13. /**
  14. * Order status resource model
  15. *
  16. * @author Magento Core Team <core@magentocommerce.com>
  17. */
  18. class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  19. {
  20. /**
  21. * Status labels table
  22. *
  23. * @var string
  24. */
  25. protected $labelsTable;
  26. /**
  27. * Status state table
  28. *
  29. * @var string
  30. */
  31. protected $stateTable;
  32. /**
  33. * Internal constructor
  34. *
  35. * @return void
  36. */
  37. protected function _construct()
  38. {
  39. $this->_init('sales_order_status', 'status');
  40. $this->_isPkAutoIncrement = false;
  41. $this->labelsTable = $this->getTable('sales_order_status_label');
  42. $this->stateTable = $this->getTable('sales_order_status_state');
  43. }
  44. /**
  45. * Retrieve select object for load object data
  46. *
  47. * @param string $field
  48. * @param mixed $value
  49. * @param \Magento\Framework\Model\AbstractModel $object
  50. * @return \Magento\Framework\DB\Select
  51. */
  52. protected function _getLoadSelect($field, $value, $object)
  53. {
  54. if ($field == 'default_state') {
  55. $select = $this->getConnection()->select()->from(
  56. $this->getMainTable(),
  57. ['label']
  58. )->join(
  59. ['state_table' => $this->stateTable],
  60. $this->getMainTable() . '.status = state_table.status',
  61. 'status'
  62. )->where(
  63. 'state_table.state = ?',
  64. $value
  65. )->order(
  66. 'state_table.is_default DESC'
  67. )->limit(
  68. 1
  69. );
  70. } else {
  71. $select = parent::_getLoadSelect($field, $value, $object);
  72. }
  73. return $select;
  74. }
  75. /**
  76. * Store labels getter
  77. *
  78. * @param \Magento\Sales\Model\Order\Status $status
  79. * @return array
  80. */
  81. public function getStoreLabels(\Magento\Sales\Model\Order\Status $status)
  82. {
  83. $select = $this->getConnection()->select()
  84. ->from(['ssl' => $this->labelsTable], [])
  85. ->where('status = ?', $status->getStatus())
  86. ->columns([
  87. 'store_id',
  88. 'label',
  89. ]);
  90. return $this->getConnection()->fetchPairs($select);
  91. }
  92. /**
  93. * Save status labels per store
  94. *
  95. * @param \Magento\Framework\Model\AbstractModel $object
  96. * @return $this
  97. */
  98. protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
  99. {
  100. if ($object->hasStoreLabels()) {
  101. $labels = $object->getStoreLabels();
  102. $this->getConnection()->delete($this->labelsTable, ['status = ?' => $object->getStatus()]);
  103. $data = [];
  104. foreach ($labels as $storeId => $label) {
  105. if (empty($label)) {
  106. continue;
  107. }
  108. $data[] = ['status' => $object->getStatus(), 'store_id' => $storeId, 'label' => $label];
  109. }
  110. if (!empty($data)) {
  111. $this->getConnection()->insertMultiple($this->labelsTable, $data);
  112. }
  113. }
  114. return parent::_afterSave($object);
  115. }
  116. /**
  117. * Assign order status to order state
  118. *
  119. * @param string $status
  120. * @param string $state
  121. * @param bool $isDefault
  122. * @param bool $visibleOnFront
  123. * @return $this
  124. */
  125. public function assignState($status, $state, $isDefault, $visibleOnFront = false)
  126. {
  127. if ($isDefault) {
  128. $this->getConnection()->update(
  129. $this->stateTable,
  130. ['is_default' => 0],
  131. ['state = ?' => $state]
  132. );
  133. }
  134. $this->getConnection()->insertOnDuplicate(
  135. $this->stateTable,
  136. [
  137. 'status' => $status,
  138. 'state' => $state,
  139. 'is_default' => (int)$isDefault,
  140. 'visible_on_front' => (int)$visibleOnFront
  141. ]
  142. );
  143. return $this;
  144. }
  145. /**
  146. * Unassign order status from order state
  147. *
  148. * @param string $status
  149. * @param string $state
  150. * @return $this
  151. * @throws \Magento\Framework\Exception\LocalizedException
  152. */
  153. public function unassignState($status, $state)
  154. {
  155. $this->getConnection()->beginTransaction();
  156. try {
  157. $isStateDefault = $this->checkIsStateDefault($state, $status);
  158. $this->getConnection()->delete(
  159. $this->stateTable,
  160. [
  161. 'state = ?' => $state,
  162. 'status = ?' => $status
  163. ]
  164. );
  165. if ($isStateDefault) {
  166. $newDefaultStatus = $this->getStatusByState($state);
  167. if ($newDefaultStatus) {
  168. $this->getConnection()->update(
  169. $this->stateTable,
  170. ['is_default' => 1],
  171. [
  172. 'state = ?' => $state,
  173. 'status = ?' => $newDefaultStatus
  174. ]
  175. );
  176. }
  177. }
  178. $this->getConnection()->commit();
  179. } catch (\Exception $e) {
  180. $this->getConnection()->rollBack();
  181. throw new LocalizedException(__('The status needs to remain assigned to its state.'));
  182. }
  183. return $this;
  184. }
  185. /**
  186. * Check is this state last
  187. *
  188. * @param string $state
  189. * @return bool
  190. */
  191. public function checkIsStateLast($state)
  192. {
  193. return (1 == $this->getConnection()->fetchOne(
  194. $this->getConnection()->select()
  195. ->from(['sss' => $this->stateTable], [])
  196. ->where('state = ?', $state)
  197. ->columns([new\Zend_Db_Expr('COUNT(1)')])
  198. ));
  199. }
  200. /**
  201. * Check is this status used in orders
  202. *
  203. * @param string $status
  204. * @return bool
  205. */
  206. public function checkIsStatusUsed($status)
  207. {
  208. return (bool)$this->getConnection()->fetchOne(
  209. $this->getConnection()->select()
  210. ->from(['sfo' => $this->getTable('sales_order')], [])
  211. ->where('status = ?', $status)
  212. ->limit(1)
  213. ->columns([new \Zend_Db_Expr(1)])
  214. );
  215. }
  216. /**
  217. * Check is this pair of state and status default
  218. *
  219. * @param string $state
  220. * @param string $status
  221. * @return bool
  222. */
  223. protected function checkIsStateDefault($state, $status)
  224. {
  225. return (bool)$this->getConnection()->fetchOne(
  226. $this->getConnection()->select()
  227. ->from(['sss' => $this->stateTable], [])
  228. ->where('state = ?', $state)
  229. ->where('status = ?', $status)
  230. ->limit(1)
  231. ->columns(['is_default'])
  232. );
  233. }
  234. /**
  235. * Returns any possible status for state
  236. *
  237. * @param string $state
  238. * @return string
  239. * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  240. */
  241. protected function getStatusByState($state)
  242. {
  243. return (string)$this->getConnection()->fetchOne(
  244. $select = $this->getConnection()->select()
  245. ->from(['sss' => $this->stateTable, []])
  246. ->where('state = ?', $state)
  247. ->limit(1)
  248. ->columns(['status'])
  249. );
  250. }
  251. }