Quote.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Quote\Model\ResourceModel;
  7. use Magento\Framework\Model\ResourceModel\Db\VersionControl\AbstractDb;
  8. use Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite;
  9. use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
  10. use Magento\SalesSequence\Model\Manager;
  11. /**
  12. * Quote resource model
  13. */
  14. class Quote extends AbstractDb
  15. {
  16. /**
  17. * @var \Magento\SalesSequence\Model\Manager
  18. */
  19. protected $sequenceManager;
  20. /**
  21. * @param \Magento\Framework\Model\ResourceModel\Db\Context $context
  22. * @param Snapshot $entitySnapshot
  23. * @param RelationComposite $entityRelationComposite
  24. * @param \Magento\SalesSequence\Model\Manager $sequenceManager
  25. * @param string $connectionName
  26. */
  27. public function __construct(
  28. \Magento\Framework\Model\ResourceModel\Db\Context $context,
  29. Snapshot $entitySnapshot,
  30. RelationComposite $entityRelationComposite,
  31. Manager $sequenceManager,
  32. $connectionName = null
  33. ) {
  34. parent::__construct($context, $entitySnapshot, $entityRelationComposite, $connectionName);
  35. $this->sequenceManager = $sequenceManager;
  36. }
  37. /**
  38. * Initialize table nad PK name
  39. *
  40. * @return void
  41. */
  42. protected function _construct()
  43. {
  44. $this->_init('quote', 'entity_id');
  45. }
  46. /**
  47. * Retrieve select object for load object data
  48. *
  49. * @param string $field
  50. * @param mixed $value
  51. * @param \Magento\Framework\Model\AbstractModel $object
  52. * @return \Magento\Framework\DB\Select
  53. */
  54. protected function _getLoadSelect($field, $value, $object)
  55. {
  56. $select = parent::_getLoadSelect($field, $value, $object);
  57. $storeIds = $object->getSharedStoreIds();
  58. if ($storeIds) {
  59. if ($storeIds != ['*']) {
  60. $select->where('store_id IN (?)', $storeIds);
  61. }
  62. } else {
  63. /**
  64. * For empty result
  65. */
  66. $select->where('store_id < ?', 0);
  67. }
  68. return $select;
  69. }
  70. /**
  71. * Load quote data by customer identifier
  72. *
  73. * @param \Magento\Quote\Model\Quote $quote
  74. * @param int $customerId
  75. * @return $this
  76. */
  77. public function loadByCustomerId($quote, $customerId)
  78. {
  79. $connection = $this->getConnection();
  80. $select = $this->_getLoadSelect(
  81. 'customer_id',
  82. $customerId,
  83. $quote
  84. )->where(
  85. 'is_active = ?',
  86. 1
  87. )->order(
  88. 'updated_at ' . \Magento\Framework\DB\Select::SQL_DESC
  89. )->limit(
  90. 1
  91. );
  92. $data = $connection->fetchRow($select);
  93. if ($data) {
  94. $quote->setData($data);
  95. }
  96. $this->_afterLoad($quote);
  97. return $this;
  98. }
  99. /**
  100. * Load only active quote
  101. *
  102. * @param \Magento\Quote\Model\Quote $quote
  103. * @param int $quoteId
  104. * @return $this
  105. */
  106. public function loadActive($quote, $quoteId)
  107. {
  108. $connection = $this->getConnection();
  109. $select = $this->_getLoadSelect('entity_id', $quoteId, $quote)->where('is_active = ?', 1);
  110. $data = $connection->fetchRow($select);
  111. if ($data) {
  112. $quote->setData($data);
  113. }
  114. $this->_afterLoad($quote);
  115. return $this;
  116. }
  117. /**
  118. * Load quote data by identifier without store
  119. *
  120. * @param \Magento\Quote\Model\Quote $quote
  121. * @param int $quoteId
  122. * @return $this
  123. */
  124. public function loadByIdWithoutStore($quote, $quoteId)
  125. {
  126. $connection = $this->getConnection();
  127. if ($connection) {
  128. $select = parent::_getLoadSelect('entity_id', $quoteId, $quote);
  129. $data = $connection->fetchRow($select);
  130. if ($data) {
  131. $quote->setData($data);
  132. }
  133. }
  134. $this->_afterLoad($quote);
  135. return $this;
  136. }
  137. /**
  138. * Get reserved order id
  139. *
  140. * @param \Magento\Quote\Model\Quote $quote
  141. * @return string
  142. */
  143. public function getReservedOrderId($quote)
  144. {
  145. return $this->sequenceManager->getSequence(
  146. \Magento\Sales\Model\Order::ENTITY,
  147. $quote->getStoreId()
  148. )
  149. ->getNextValue();
  150. }
  151. /**
  152. * Mark quotes - that depend on catalog price rules - to be recollected on demand
  153. *
  154. * @return $this
  155. */
  156. public function markQuotesRecollectOnCatalogRules()
  157. {
  158. $tableQuote = $this->getTable('quote');
  159. $subSelect = $this->getConnection()->select()->from(
  160. ['t2' => $this->getTable('quote_item')],
  161. ['entity_id' => 'quote_id']
  162. )->from(
  163. ['t3' => $this->getTable('catalogrule_product_price')],
  164. []
  165. )->where(
  166. 't2.product_id = t3.product_id'
  167. )->group(
  168. 'quote_id'
  169. );
  170. $select = $this->getConnection()->select()->join(
  171. ['t2' => $subSelect],
  172. 't1.entity_id = t2.entity_id',
  173. ['trigger_recollect' => new \Zend_Db_Expr('1')]
  174. );
  175. $updateQuery = $select->crossUpdateFromSelect(['t1' => $tableQuote]);
  176. $this->getConnection()->query($updateQuery);
  177. return $this;
  178. }
  179. /**
  180. * Subtract product from all quotes quantities
  181. *
  182. * @param \Magento\Catalog\Model\Product $product
  183. * @return $this
  184. */
  185. public function subtractProductFromQuotes($product)
  186. {
  187. $productId = (int)$product->getId();
  188. if (!$productId) {
  189. return $this;
  190. }
  191. $connection = $this->getConnection();
  192. $subSelect = $connection->select();
  193. $conditionCheck = $connection->quoteIdentifier('q.items_count') . " > 0";
  194. $conditionTrue = $connection->quoteIdentifier('q.items_count') . ' - 1';
  195. $ifSql = "IF (" . $conditionCheck . "," . $conditionTrue . ", 0)";
  196. $subSelect->from(
  197. false,
  198. [
  199. 'items_qty' => new \Zend_Db_Expr(
  200. $connection->quoteIdentifier('q.items_qty') . ' - ' . $connection->quoteIdentifier('qi.qty')
  201. ),
  202. 'items_count' => new \Zend_Db_Expr($ifSql)
  203. ]
  204. )->join(
  205. ['qi' => $this->getTable('quote_item')],
  206. implode(
  207. ' AND ',
  208. [
  209. 'q.entity_id = qi.quote_id',
  210. 'qi.parent_item_id IS NULL',
  211. $connection->quoteInto('qi.product_id = ?', $productId)
  212. ]
  213. ),
  214. []
  215. );
  216. $updateQuery = $connection->updateFromSelect($subSelect, ['q' => $this->getTable('quote')]);
  217. $connection->query($updateQuery);
  218. return $this;
  219. }
  220. /**
  221. * Subtract product from all quotes quantities
  222. *
  223. * @param \Magento\Catalog\Model\Product $product
  224. *
  225. * @deprecated 101.0.3
  226. * @see \Magento\Quote\Model\ResourceModel\Quote::subtractProductFromQuotes
  227. *
  228. * @return $this
  229. */
  230. public function substractProductFromQuotes($product)
  231. {
  232. return $this->subtractProductFromQuotes($product);
  233. }
  234. /**
  235. * Mark recollect contain product(s) quotes
  236. *
  237. * @param array|int|\Zend_Db_Expr $productIds
  238. * @return $this
  239. */
  240. public function markQuotesRecollect($productIds)
  241. {
  242. $tableQuote = $this->getTable('quote');
  243. $tableItem = $this->getTable('quote_item');
  244. $subSelect = $this->getConnection()->select()->from(
  245. $tableItem,
  246. ['entity_id' => 'quote_id']
  247. )->where(
  248. 'product_id IN ( ? )',
  249. $productIds
  250. )->group(
  251. 'quote_id'
  252. );
  253. $select = $this->getConnection()->select()->join(
  254. ['t2' => $subSelect],
  255. 't1.entity_id = t2.entity_id',
  256. ['trigger_recollect' => new \Zend_Db_Expr('1')]
  257. );
  258. $updateQuery = $select->crossUpdateFromSelect(['t1' => $tableQuote]);
  259. $this->getConnection()->query($updateQuery);
  260. return $this;
  261. }
  262. /**
  263. * @inheritdoc
  264. */
  265. public function save(\Magento\Framework\Model\AbstractModel $object)
  266. {
  267. if (!$object->isPreventSaving()) {
  268. return parent::save($object);
  269. }
  270. }
  271. }