Skip to content

Commit dac83de

Browse files
committed
MC-19515: Cart price rule based on payment methods not applied in checkout
1 parent 03dd86e commit dac83de

File tree

12 files changed

+268
-63
lines changed

12 files changed

+268
-63
lines changed

app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndProductWithTierPricesTest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
<checkOption selector="{{CheckoutPaymentSection.bankTransfer}}" stepKey="selectBankTransfer"/>
7878
<waitForElementVisible selector="{{CheckoutPaymentSection.billingAddressNotSameBankTransferCheckbox}}" stepKey="waitForElementToBeVisible"/>
7979
<uncheckOption selector="{{CheckoutPaymentSection.billingAddressNotSameBankTransferCheckbox}}" stepKey="uncheckSameBillingAndShippingAddress"/>
80+
<waitForElementVisible selector="{{CheckoutShippingSection.editActiveAddressButton}}" stepKey="waitForEditButtonToBeVisible"/>
8081
<conditionalClick selector="{{CheckoutShippingSection.editActiveAddressButton}}" dependentSelector="{{CheckoutShippingSection.editActiveAddressButton}}" visible="true" stepKey="clickEditButton"/>
8182
<waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/>
8283

@@ -127,4 +128,4 @@
127128
<!-- Assert order buttons -->
128129
<actionGroup ref="AdminAssertOrderAvailableButtonsActionGroup" stepKey="assertOrderButtons"/>
129130
</test>
130-
</tests>
131+
</tests>

app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Conditions.php

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab;
79

810
use Magento\Framework\App\ObjectManager;
11+
use Magento\Framework\Data\Form\Element\Fieldset;
12+
use Magento\SalesRule\Model\Rule;
913

14+
/**
15+
* Block for rendering Conditions tab on Sales Rules creation page.
16+
*
17+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
18+
*/
1019
class Conditions extends \Magento\Backend\Block\Widget\Form\Generic implements
1120
\Magento\Ui\Component\Layout\Tabs\TabInterface
1221
{
@@ -33,8 +42,6 @@ class Conditions extends \Magento\Backend\Block\Widget\Form\Generic implements
3342
private $ruleFactory;
3443

3544
/**
36-
* Constructor
37-
*
3845
* @param \Magento\Backend\Block\Template\Context $context
3946
* @param \Magento\Framework\Registry $registry
4047
* @param \Magento\Framework\Data\FormFactory $formFactory
@@ -60,7 +67,8 @@ public function __construct(
6067
}
6168

6269
/**
63-
* {@inheritdoc}
70+
* @inheritdoc
71+
*
6472
* @codeCoverageIgnore
6573
*/
6674
public function getTabClass()
@@ -69,47 +77,47 @@ public function getTabClass()
6977
}
7078

7179
/**
72-
* {@inheritdoc}
80+
* @inheritdoc
7381
*/
7482
public function getTabUrl()
7583
{
7684
return null;
7785
}
7886

7987
/**
80-
* {@inheritdoc}
88+
* @inheritdoc
8189
*/
8290
public function isAjaxLoaded()
8391
{
8492
return false;
8593
}
8694

8795
/**
88-
* {@inheritdoc}
96+
* @inheritdoc
8997
*/
9098
public function getTabLabel()
9199
{
92100
return __('Conditions');
93101
}
94102

95103
/**
96-
* {@inheritdoc}
104+
* @inheritdoc
97105
*/
98106
public function getTabTitle()
99107
{
100108
return __('Conditions');
101109
}
102110

103111
/**
104-
* {@inheritdoc}
112+
* @inheritdoc
105113
*/
106114
public function canShowTab()
107115
{
108116
return true;
109117
}
110118

111119
/**
112-
* {@inheritdoc}
120+
* @inheritdoc
113121
*/
114122
public function isHidden()
115123
{
@@ -133,7 +141,7 @@ protected function _prepareForm()
133141
/**
134142
* Handles addition of conditions tab to supplied form.
135143
*
136-
* @param \Magento\SalesRule\Model\Rule $model
144+
* @param Rule $model
137145
* @param string $fieldsetId
138146
* @param string $formName
139147
* @return \Magento\Framework\Data\Form
@@ -188,6 +196,7 @@ protected function addTabToForm($model, $fieldsetId = 'conditions_fieldset', $fo
188196
)->setRenderer(
189197
$this->_conditions
190198
);
199+
$this->addComment($model, $fieldset);
191200

192201
$form->setValues($model->getData());
193202
$this->setConditionFormName($model->getConditions(), $formName);
@@ -210,4 +219,22 @@ private function setConditionFormName(\Magento\Rule\Model\Condition\AbstractCond
210219
}
211220
}
212221
}
222+
223+
/**
224+
* Adding comment if using specific sales rule.
225+
*
226+
* @param Rule $rule
227+
* @param Fieldset $fieldset
228+
* @return void
229+
*/
230+
private function addComment(Rule $rule, Fieldset $fieldset): void
231+
{
232+
foreach ($rule->getConditions()->getConditions() as $condition) {
233+
if ($condition->getAttribute() === 'payment_method') {
234+
$fieldset->setComment(
235+
__('Adding "Payment Method" condition to Checkout pages may increase load time on the storefront.')
236+
);
237+
}
238+
}
239+
}
213240
}

app/code/Magento/SalesRule/Model/Quote/Discount.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public function collect(
9595

9696
$store = $this->storeManager->getStore($quote->getStoreId());
9797
$address = $shippingAssignment->getShipping()->getAddress();
98+
99+
if ($quote->getPayment()->getMethod()) {
100+
$address->setPaymentMethod($quote->getPayment()->getMethod());
101+
}
102+
98103
$this->calculator->reset($address);
99104

100105
$items = $shippingAssignment->getItems();

app/code/Magento/SalesRule/Model/Rule/Condition/Address.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public function loadAttributeOptions()
6565
'base_subtotal' => __('Subtotal'),
6666
'total_qty' => __('Total Items Quantity'),
6767
'weight' => __('Total Weight'),
68+
'payment_method' => __('Payment Method'),
6869
'shipping_method' => __('Shipping Method'),
6970
'postcode' => __('Shipping Postcode'),
7071
'region' => __('Shipping Region'),

app/code/Magento/SalesRule/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,4 @@ Apply,Apply
164164
"Apply to Shipping Amount","Apply to Shipping Amount"
165165
"Discard subsequent rules","Discard subsequent rules"
166166
"Default Rule Label for All Store Views","Default Rule Label for All Store Views"
167+
"Adding ""Payment Method"" condition to Checkout pages may increase load time on the storefront.","Adding ""Payment Method"" condition to Checkout pages may increase load time on the storefront."
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
var config = {
7+
config: {
8+
mixins: {
9+
'Magento_Checkout/js/action/select-payment-method': {
10+
'Magento_SalesRule/js/action/select-payment-method-mixin': true
11+
}
12+
}
13+
}
14+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
define([
6+
'mage/utils/wrapper',
7+
'Magento_Checkout/js/model/quote',
8+
'Magento_SalesRule/js/model/payment/discount-messages',
9+
'Magento_Checkout/js/action/set-payment-information',
10+
'Magento_Checkout/js/action/get-totals'
11+
], function (wrapper, quote, messageContainer, setPaymentInformationAction, getTotalsAction) {
12+
'use strict';
13+
14+
return function (selectPaymentMethodAction) {
15+
16+
return wrapper.wrap(selectPaymentMethodAction, function (originalSelectPaymentMethodAction, paymentMethod) {
17+
18+
originalSelectPaymentMethodAction(paymentMethod);
19+
20+
setPaymentInformationAction(
21+
messageContainer,
22+
{
23+
method: paymentMethod.method
24+
}
25+
);
26+
27+
getTotalsAction([]);
28+
});
29+
30+
};
31+
32+
});

app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ define([
1818
'Magento_Checkout/js/action/get-payment-information',
1919
'Magento_Checkout/js/model/totals',
2020
'Magento_Checkout/js/model/full-screen-loader',
21-
'Magento_Checkout/js/action/recollect-shipping-rates'
21+
'Magento_Checkout/js/action/recollect-shipping-rates',
22+
'Magento_Checkout/js/action/set-payment-information'
2223
], function (ko, $, quote, urlManager, errorProcessor, messageContainer, storage, $t, getPaymentInformationAction,
23-
totals, fullScreenLoader, recollectShippingRates
24+
totals, fullScreenLoader, recollectShippingRates, setPaymentInformationAction
2425
) {
2526
'use strict';
2627

@@ -49,6 +50,15 @@ define([
4950
});
5051
fullScreenLoader.startLoader();
5152

53+
if (quote.paymentMethod()) {
54+
setPaymentInformationAction(
55+
messageContainer,
56+
{
57+
method: quote.paymentMethod().method
58+
}
59+
);
60+
}
61+
5262
return storage.put(
5363
url,
5464
data,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\SalesRule\Model\Rule\Condition;
7+
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
use PHPUnit\Framework\TestCase;
10+
11+
/**
12+
* Test for \Magento\SalesRule\Model\Rule\Condition\Address.
13+
*/
14+
class AddressTest extends TestCase
15+
{
16+
use ConditionHelper;
17+
18+
/**
19+
* @var \Magento\Framework\ObjectManagerInterface
20+
*/
21+
private $objectManager;
22+
23+
/**
24+
* @inheritDoc
25+
*/
26+
protected function setUp()
27+
{
28+
$this->objectManager = Bootstrap::getObjectManager();
29+
}
30+
31+
/**
32+
* Tests cart price rule validation.
33+
*
34+
* @magentoDbIsolation enabled
35+
* @magentoAppIsolation enabled
36+
* @magentoConfigFixture default_store payment/checkmo/active 1
37+
* @magentoDataFixture Magento/SalesRule/_files/rules_payment_method.php
38+
* @magentoDataFixture Magento/Checkout/_files/quote_with_payment_saved.php
39+
*/
40+
public function testValidateRule()
41+
{
42+
$quote = $this->getQuote('test_order_1_with_payment');
43+
$rule = $this->getSalesRule('50% Off on Checkmo Payment Method');
44+
45+
$this->assertTrue(
46+
$rule->validate($quote->getBillingAddress()),
47+
'Cart price rule validation failed.'
48+
);
49+
}
50+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\SalesRule\Model\Rule\Condition;
7+
8+
use Magento\Framework\Api\SearchCriteriaBuilder;
9+
use Magento\Quote\Api\CartRepositoryInterface;
10+
use Magento\Quote\Api\Data\CartInterface;
11+
use Magento\SalesRule\Api\RuleRepositoryInterface;
12+
13+
/**
14+
* Helper class for testing cart price rule conditions.
15+
*/
16+
trait ConditionHelper
17+
{
18+
/**
19+
* Gets quote by reserved order id.
20+
*
21+
* @param string $reservedOrderId
22+
* @return CartInterface
23+
*/
24+
private function getQuote($reservedOrderId)
25+
{
26+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
27+
$searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
28+
$searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId)
29+
->create();
30+
31+
/** @var CartRepositoryInterface $quoteRepository */
32+
$quoteRepository = $this->objectManager->get(CartRepositoryInterface::class);
33+
$items = $quoteRepository->getList($searchCriteria)->getItems();
34+
return array_pop($items);
35+
}
36+
37+
/**
38+
* Gets rule by name.
39+
*
40+
* @param string $name
41+
* @return \Magento\SalesRule\Model\Rule
42+
* @throws \Magento\Framework\Exception\InputException
43+
* @throws \Magento\Framework\Exception\NoSuchEntityException
44+
*/
45+
private function getSalesRule(string $name): \Magento\SalesRule\Model\Rule
46+
{
47+
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
48+
$searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class);
49+
$searchCriteria = $searchCriteriaBuilder->addFilter('name', $name)
50+
->create();
51+
52+
/** @var CartRepositoryInterface $quoteRepository */
53+
$ruleRepository = $this->objectManager->get(RuleRepositoryInterface::class);
54+
$items = $ruleRepository->getList($searchCriteria)->getItems();
55+
56+
$rule = array_pop($items);
57+
/** @var \Magento\SalesRule\Model\Converter\ToModel $converter */
58+
$converter = $this->objectManager->get(\Magento\SalesRule\Model\Converter\ToModel::class);
59+
60+
return $converter->toModel($rule);
61+
}
62+
}

0 commit comments

Comments
 (0)