PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/magento/module-customer-segment/Model/Segment/Condition/Shoppingcart/Amount.php

https://bitbucket.org/sergiu-tot-fb/vendors
PHP | 306 lines | 200 code | 24 blank | 82 comment | 18 complexity | 65980762d9ba9359d9bb424f4c904134 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, MIT, Apache-2.0
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CustomerSegment\Model\Segment\Condition\Shoppingcart;
  7. use Magento\Customer\Model\Customer;
  8. use Magento\CustomerSegment\Model\Condition\AbstractCondition;
  9. /**
  10. * Shopping cart totals amount condition
  11. */
  12. class Amount extends AbstractCondition
  13. {
  14. /**
  15. * @var string
  16. */
  17. protected $_inputType = 'numeric';
  18. /**
  19. * @var \Magento\Quote\Model\ResourceModel\Quote
  20. */
  21. protected $resourceQuote;
  22. /**
  23. * @param \Magento\Rule\Model\Condition\Context $context
  24. * @param \Magento\CustomerSegment\Model\ResourceModel\Segment $resourceSegment
  25. * @param \Magento\Quote\Model\ResourceModel\Quote $resourceQuote
  26. * @param array $data
  27. */
  28. public function __construct(
  29. \Magento\Rule\Model\Condition\Context $context,
  30. \Magento\CustomerSegment\Model\ResourceModel\Segment $resourceSegment,
  31. \Magento\Quote\Model\ResourceModel\Quote $resourceQuote,
  32. array $data = []
  33. ) {
  34. parent::__construct($context, $resourceSegment, $data);
  35. $this->setType(\Magento\CustomerSegment\Model\Segment\Condition\Shoppingcart\Amount::class);
  36. $this->setValue(null);
  37. $this->resourceQuote = $resourceQuote;
  38. }
  39. /**
  40. * Get array of event names where segment with such conditions combine can be matched
  41. *
  42. * @return string[]
  43. */
  44. public function getMatchedEvents()
  45. {
  46. return ['sales_quote_save_commit_after', 'checkout_cart_save_after', 'sales_quote_collect_totals_after'];
  47. }
  48. /**
  49. * Get information for being presented in condition list
  50. *
  51. * @return array
  52. */
  53. public function getNewChildSelectOptions()
  54. {
  55. return [
  56. 'value' => $this->getType(),
  57. 'label' => __('Shopping Cart Total'),
  58. 'available_in_guest_mode' => true
  59. ];
  60. }
  61. /**
  62. * Init available options list
  63. *
  64. * @return $this
  65. */
  66. public function loadAttributeOptions()
  67. {
  68. $this->setAttributeOption(
  69. [
  70. 'subtotal' => __('Subtotal'),
  71. 'grand_total' => __('Grand Total'),
  72. 'tax' => __('Tax'),
  73. 'shipping' => __('Shipping'),
  74. 'store_credit' => __('Store Credit'),
  75. 'gift_card' => __('Gift Card'),
  76. ]
  77. );
  78. return $this;
  79. }
  80. /**
  81. * Set rule instance
  82. *
  83. * Modify attribute_option array if needed
  84. *
  85. * @param \Magento\Rule\Model\AbstractModel $rule
  86. * @return $this
  87. */
  88. public function setRule($rule)
  89. {
  90. $this->setData('rule', $rule);
  91. if ($rule instanceof \Magento\CustomerSegment\Model\Segment && $rule->getApplyTo() !== null) {
  92. $attributeOption = $this->loadAttributeOptions()->getAttributeOption();
  93. $applyTo = $rule->getApplyTo();
  94. if (\Magento\CustomerSegment\Model\Segment::APPLY_TO_VISITORS == $applyTo) {
  95. unset($attributeOption['store_credit']);
  96. } elseif (\Magento\CustomerSegment\Model\Segment::APPLY_TO_VISITORS_AND_REGISTERED == $applyTo) {
  97. foreach (array_keys($attributeOption) as $key) {
  98. if ('store_credit' != $key) {
  99. $attributeOption[$key] .= '*';
  100. }
  101. }
  102. }
  103. $this->setAttributeOption($attributeOption);
  104. }
  105. return $this;
  106. }
  107. /**
  108. * Condition string on conditions page
  109. *
  110. * @return string
  111. */
  112. public function asHtml()
  113. {
  114. return $this->getTypeElementHtml() . __(
  115. 'Shopping Cart %1 Amount %2 %3:',
  116. $this->getAttributeElementHtml(),
  117. $this->getOperatorElementHtml(),
  118. $this->getValueElementHtml()
  119. ) . $this->getRemoveLinkHtml();
  120. }
  121. /**
  122. * Build condition limitations sql string for specific website
  123. *
  124. * @param Customer|\Zend_Db_Expr $customer
  125. * @param int|\Zend_Db_Expr $website
  126. * @param bool $isFiltered
  127. * @throws \Magento\Framework\Exception\LocalizedException
  128. * @return \Magento\Framework\DB\Select
  129. *
  130. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  131. */
  132. public function getConditionsSql($customer, $website, $isFiltered = true)
  133. {
  134. $table = $this->getResource()->getTable('quote');
  135. $addressTable = $this->getResource()->getTable('quote_address');
  136. $operator = $this->getResource()->getSqlOperator($this->getOperator());
  137. $select = $this->getResource()->createSelect();
  138. $select->from(['quote' => $table], [new \Zend_Db_Expr(1)])->where('quote.is_active=1');
  139. $select->limit(1);
  140. $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
  141. $joinAddress = false;
  142. switch ($this->getAttribute()) {
  143. case 'subtotal':
  144. $field = 'quote.base_subtotal';
  145. break;
  146. case 'grand_total':
  147. $field = 'quote.base_grand_total';
  148. break;
  149. case 'tax':
  150. $field = 'base_tax_amount';
  151. $joinAddress = true;
  152. break;
  153. case 'shipping':
  154. $field = 'base_shipping_amount';
  155. $joinAddress = true;
  156. break;
  157. case 'store_credit':
  158. $field = 'quote.base_customer_bal_amount_used';
  159. break;
  160. case 'gift_card':
  161. $field = 'quote.base_gift_cards_amount_used';
  162. break;
  163. default:
  164. throw new \Magento\Framework\Exception\LocalizedException(__('Unknown quote total specified.'));
  165. }
  166. if ($joinAddress) {
  167. $subSelect = $this->getResource()->createSelect();
  168. $subSelect->from(
  169. ['address' => $addressTable],
  170. ['quote_id' => 'quote_id', $field => new \Zend_Db_Expr("SUM({$field})")]
  171. );
  172. $subSelect->group('quote_id');
  173. $select->joinInner(['address' => $subSelect], 'address.quote_id = quote.entity_id', []);
  174. $field = "address.{$field}";
  175. }
  176. $select->where("{$field} {$operator} ?", $this->getValue());
  177. if ($customer) {
  178. // Leave ability to check this condition not only by customer_id but also by quote_id
  179. $select->where('quote.customer_id = :customer_id OR quote.entity_id = :quote_id');
  180. } else {
  181. $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
  182. }
  183. return $select;
  184. }
  185. /**
  186. * @param int $customer
  187. * @param int $websiteId
  188. * @param array $params
  189. * @param bool $isFiltered
  190. * @return array
  191. * @throws \Magento\Framework\Exception\LocalizedException
  192. *
  193. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  194. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  195. */
  196. private function executeSql($customer, $websiteId, $params, $isFiltered = true)
  197. {
  198. $table = $this->getResource()->getTable('quote');
  199. $addressTable = $this->getResource()->getTable('quote_address');
  200. $operator = $this->getResource()->getSqlOperator($this->getOperator());
  201. $select = $this->getResource()->createSelect();
  202. if ($isFiltered) {
  203. $select->from(['quote' => $table], [new \Zend_Db_Expr(1)])->where('quote.is_active=1');
  204. $select->limit(1);
  205. } else {
  206. $select->from(['quote' => $table], ['customer_id'])->where('quote.is_active=1');
  207. }
  208. $select->where(
  209. 'quote.store_id IN(?)',
  210. $this->getStoreByWebsite($websiteId)
  211. );
  212. $joinAddress = false;
  213. switch ($this->getAttribute()) {
  214. case 'subtotal':
  215. $field = 'quote.base_subtotal';
  216. break;
  217. case 'grand_total':
  218. $field = 'quote.base_grand_total';
  219. break;
  220. case 'tax':
  221. $field = 'base_tax_amount';
  222. $joinAddress = true;
  223. break;
  224. case 'shipping':
  225. $field = 'base_shipping_amount';
  226. $joinAddress = true;
  227. break;
  228. case 'store_credit':
  229. $field = 'quote.base_customer_bal_amount_used';
  230. break;
  231. case 'gift_card':
  232. $field = 'quote.base_gift_cards_amount_used';
  233. break;
  234. default:
  235. throw new \Magento\Framework\Exception\LocalizedException(__('Unknown quote total specified.'));
  236. }
  237. if ($joinAddress) {
  238. $subSelect = $this->getResource()->createSelect();
  239. $subSelect->from(
  240. ['address' => $addressTable],
  241. ['quote_id' => 'quote_id', $field => new \Zend_Db_Expr("SUM({$field})")]
  242. );
  243. $subSelect->group('quote_id');
  244. $select->joinInner(['address' => $subSelect], 'address.quote_id = quote.entity_id', []);
  245. $field = "address.{$field}";
  246. }
  247. $select->where("{$field} {$operator} ?", $this->getValue());
  248. if ($isFiltered) {
  249. // Leave ability to check this condition not only by customer_id but also by quote_id
  250. $contextFilter = ['quote.entity_id = :quote_id'];
  251. if (!empty($params['customer_id'])) {
  252. $contextFilter[] = 'quote.customer_id = :customer_id';
  253. }
  254. $select->where(implode(' OR ', $contextFilter));
  255. } else {
  256. $select->where('customer_id IS NOT NULL');
  257. }
  258. $matchedParams = $this->matchParameters($select, $params);
  259. $result = $this->resourceQuote->getConnection()->fetchCol($select, $matchedParams);
  260. return $result;
  261. }
  262. /**
  263. * @param int $customer
  264. * @param int $websiteId
  265. * @param array $params
  266. * @return bool
  267. */
  268. public function isSatisfiedBy($customer, $websiteId, $params)
  269. {
  270. $result = $this->executeSql($customer, $websiteId, $params, true);
  271. return !empty($result);
  272. }
  273. /**
  274. * @param int $websiteId
  275. * @param null $requireValid
  276. * @return array
  277. */
  278. public function getSatisfiedIds($websiteId)
  279. {
  280. return $this->executeSql(null, $websiteId, [], false);
  281. }
  282. }