Skip to content

Commit a18bfe0

Browse files
committed
Merge remote-tracking branch 'l3/MC-29335' into BUGFIX-11-23
2 parents 9e0a769 + db9a9c9 commit a18bfe0

File tree

13 files changed

+309
-12
lines changed

13 files changed

+309
-12
lines changed

app/code/Magento/Sales/Test/Mftf/Test/AdminCancelTheCreatedOrderWithZeroSubtotalCheckoutTest.xml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<field key="price">10.00</field>
3636
</createData>
3737

38-
<!-- Create a slaes rule with fixed discount -->
38+
<!-- Create a sales rule with fixed discount -->
3939
<createData entity="SalesRuleNoCouponWithFixedDiscount" stepKey="createSalesRule"/>
4040
</before>
4141
<after>
@@ -47,7 +47,6 @@
4747
<deleteData createDataKey="simpleProduct" stepKey="deleteSimpleProduct"/>
4848
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
4949
</after>
50-
5150
<!--Create new customer order-->
5251
<actionGroup ref="NavigateToNewOrderPageExistingCustomerActionGroup" stepKey="navigateToNewOrderWithExistingCustomer">
5352
<argument name="customer" value="$$simpleCustomer$$"/>
@@ -62,10 +61,20 @@
6261
<actionGroup ref="AdminSelectFlatRateShippingMethodActionGroup" stepKey="selectFlatRateShippingMethod"/>
6362
<actionGroup ref="AdminOrderClickSubmitOrderActionGroup" stepKey="submitOrder" />
6463

64+
<!-- Start the consumer -->
65+
<actionGroup ref="CliConsumerStartActionGroup" stepKey="startMessageQueue">
66+
<argument name="consumerName" value="{{SalesRuleConsumerData.consumerName}}"/>
67+
<argument name="maxMessages" value="{{SalesRuleConsumerData.messageLimit}}"/>
68+
</actionGroup>
69+
6570
<!--Verify order information-->
6671
<actionGroup ref="VerifyCreatedOrderInformationActionGroup" stepKey="verifyCreatedOrderInformation"/>
72+
<reloadPage stepKey="refreshPage"/>
6773
<grabTextFrom selector="|Order # (\d+)|" stepKey="orderId"/>
6874

75+
<!-- Refresh the page -->
76+
<reloadPage stepKey="refreshPageAgain"/>
77+
6978
<!-- Cancel the Order -->
7079
<actionGroup ref="CancelPendingOrderActionGroup" stepKey="cancelPendingOrder"/>
7180

app/code/Magento/SalesRule/Model/Coupon/Quote/UpdateCouponUsages.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,34 @@
88
namespace Magento\SalesRule\Model\Coupon\Quote;
99

1010
use Magento\Quote\Api\Data\CartInterface;
11-
use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
1211
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
1312
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
13+
use Magento\SalesRule\Model\Service\CouponUsagePublisher;
1414

1515
/**
1616
* Updates the coupon usages from quote
1717
*/
1818
class UpdateCouponUsages
1919
{
2020
/**
21-
* @var CouponUsageProcessor
21+
* @var UpdateInfoFactory
2222
*/
23-
private $couponUsageProcessor;
23+
private $updateInfoFactory;
2424

2525
/**
26-
* @var UpdateInfoFactory
26+
* @var CouponUsagePublisher
2727
*/
28-
private $updateInfoFactory;
28+
private $couponUsagePublisher;
2929

3030
/**
31-
* @param CouponUsageProcessor $couponUsageProcessor
31+
* @param CouponUsagePublisher $couponUsagePublisher
3232
* @param UpdateInfoFactory $updateInfoFactory
3333
*/
3434
public function __construct(
35-
CouponUsageProcessor $couponUsageProcessor,
35+
CouponUsagePublisher $couponUsagePublisher,
3636
UpdateInfoFactory $updateInfoFactory
3737
) {
38-
$this->couponUsageProcessor = $couponUsageProcessor;
38+
$this->couponUsagePublisher = $couponUsagePublisher;
3939
$this->updateInfoFactory = $updateInfoFactory;
4040
}
4141

@@ -59,6 +59,6 @@ public function execute(CartInterface $quote, bool $increment): void
5959
$updateInfo->setCustomerId((int)$quote->getCustomerId());
6060
$updateInfo->setIsIncrement($increment);
6161

62-
$this->couponUsageProcessor->process($updateInfo);
62+
$this->couponUsagePublisher->publish($updateInfo);
6363
}
6464
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Model;
9+
10+
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
11+
use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
12+
use Magento\AsynchronousOperations\Api\Data\OperationInterface;
13+
use Magento\Framework\Serialize\SerializerInterface;
14+
use Magento\Framework\EntityManager\EntityManager;
15+
use Magento\Framework\Exception\NotFoundException;
16+
use Psr\Log\LoggerInterface;
17+
18+
/**
19+
* Consumer for coupon usage update
20+
*/
21+
class CouponUsageConsumer
22+
{
23+
/**
24+
* @var SerializerInterface
25+
*/
26+
private $serializer;
27+
28+
/**
29+
* @var LoggerInterface
30+
*/
31+
private $logger;
32+
33+
/**
34+
* @var CouponUsageProcessor
35+
*/
36+
private $processor;
37+
38+
/**
39+
* @var EntityManager
40+
*/
41+
private $entityManager;
42+
43+
/**
44+
* @var UpdateInfoFactory
45+
*/
46+
private $updateInfoFactory;
47+
48+
/**
49+
* @param UpdateInfoFactory $updateInfoFactory
50+
* @param CouponUsageProcessor $processor
51+
* @param LoggerInterface $logger
52+
* @param SerializerInterface $serializer
53+
* @param EntityManager $entityManager
54+
*/
55+
public function __construct(
56+
UpdateInfoFactory $updateInfoFactory,
57+
CouponUsageProcessor $processor,
58+
LoggerInterface $logger,
59+
SerializerInterface $serializer,
60+
EntityManager $entityManager
61+
) {
62+
$this->updateInfoFactory = $updateInfoFactory;
63+
$this->processor = $processor;
64+
$this->logger = $logger;
65+
$this->serializer = $serializer;
66+
$this->entityManager = $entityManager;
67+
}
68+
69+
/**
70+
* Process coupon usage update
71+
*
72+
* @param OperationInterface $operation
73+
* @return void
74+
* @throws \Exception
75+
*/
76+
public function process(OperationInterface $operation): void
77+
{
78+
try {
79+
$serializedData = $operation->getSerializedData();
80+
$data = $this->serializer->unserialize($serializedData);
81+
$updateInfo = $this->updateInfoFactory->create();
82+
$updateInfo->setData($data);
83+
$this->processor->process($updateInfo);
84+
} catch (NotFoundException $e) {
85+
$this->logger->critical($e->getMessage());
86+
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;
87+
$errorCode = $e->getCode();
88+
$message = $e->getMessage();
89+
} catch (\Exception $e) {
90+
$this->logger->critical($e->getMessage());
91+
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;
92+
$errorCode = $e->getCode();
93+
$message = __('Sorry, something went wrong during rule usage update. Please see log for details.');
94+
}
95+
96+
$operation->setStatus($status ?? OperationInterface::STATUS_TYPE_COMPLETE)
97+
->setErrorCode($errorCode ?? null)
98+
->setResultMessage($message ?? null);
99+
100+
$this->entityManager->save($operation);
101+
}
102+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\SalesRule\Model\Service;
9+
10+
use Magento\Framework\Bulk\BulkManagementInterface;
11+
use Magento\AsynchronousOperations\Api\Data\OperationInterfaceFactory;
12+
use Magento\Framework\DataObject\IdentityGeneratorInterface;
13+
use Magento\Framework\Serialize\SerializerInterface;
14+
use Magento\Framework\Bulk\OperationInterface;
15+
use Magento\Authorization\Model\UserContextInterface;
16+
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
17+
18+
/**
19+
* Scheduler for coupon usage queue
20+
*/
21+
class CouponUsagePublisher
22+
{
23+
private const TOPIC_NAME = 'sales.rule.update.coupon.usage';
24+
25+
/**
26+
* @var BulkManagementInterface
27+
*/
28+
private $bulkManagement;
29+
30+
/**
31+
* @var OperationInterfaceFactory
32+
*/
33+
private $operationFactory;
34+
35+
/**
36+
* @var IdentityGeneratorInterface
37+
*/
38+
private $identityService;
39+
40+
/**
41+
* @var SerializerInterface
42+
*/
43+
private $serializer;
44+
45+
/**
46+
* @var UserContextInterface
47+
*/
48+
private $userContext;
49+
50+
/**
51+
* @param BulkManagementInterface $bulkManagement
52+
* @param OperationInterfaceFactory $operartionFactory
53+
* @param IdentityGeneratorInterface $identityService
54+
* @param SerializerInterface $serializer
55+
* @param UserContextInterface $userContext
56+
*/
57+
public function __construct(
58+
BulkManagementInterface $bulkManagement,
59+
OperationInterfaceFactory $operartionFactory,
60+
IdentityGeneratorInterface $identityService,
61+
SerializerInterface $serializer,
62+
UserContextInterface $userContext
63+
) {
64+
$this->bulkManagement = $bulkManagement;
65+
$this->operationFactory = $operartionFactory;
66+
$this->identityService = $identityService;
67+
$this->serializer = $serializer;
68+
$this->userContext = $userContext;
69+
}
70+
71+
/**
72+
* Publish sales rule usage info into the queue
73+
*
74+
* @param string $updateInfo
75+
* @return boolean
76+
*/
77+
public function publish(UpdateInfo $updateInfo): bool
78+
{
79+
$bulkUuid = $this->identityService->generateId();
80+
$bulkDescription = __('Rule processing: %1', implode(',', $updateInfo->getAppliedRuleIds()));
81+
82+
$data = [
83+
'data' => [
84+
'bulk_uuid' => $bulkUuid,
85+
'topic_name' => self::TOPIC_NAME,
86+
'serialized_data' => $this->serializer->serialize($updateInfo->getData()),
87+
'status' => OperationInterface::STATUS_TYPE_OPEN,
88+
]
89+
];
90+
$operation = $this->operationFactory->create($data);
91+
92+
return $this->bulkManagement->scheduleBulk(
93+
$bulkUuid,
94+
[$operation],
95+
$bulkDescription,
96+
$this->userContext->getUserId()
97+
);
98+
}
99+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
11+
<entity name="SalesRuleConsumerData">
12+
<data key="consumerName">sales.rule.update.coupon.usage</data>
13+
<data key="messageLimit">10</data>
14+
</entity>
15+
</entities>

app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@
102102
<click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder"/>
103103
<waitForElement selector="{{CheckoutSuccessMainSection.success}}" time="30" stepKey="waitForLoadSuccessPage"/>
104104

105+
<!-- Start the usage processing consumer -->
106+
<actionGroup ref="CliConsumerStartActionGroup" stepKey="startUsageProcessingMessageQueue1">
107+
<argument name="consumerName" value="{{SalesRuleConsumerData.consumerName}}"/>
108+
<argument name="maxMessages" value="{{SalesRuleConsumerData.messageLimit}}"/>
109+
</actionGroup>
110+
105111
<!-- Step: 9-10. Open the Product Page, add the product to Cart, go to Shopping Cart and Apply the same coupon code -->
106112
<amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.name$$)}}" stepKey="openProductPage1"/>
107113
<waitForPageLoad stepKey="waitForPageLoad3"/>
@@ -142,6 +148,12 @@
142148
<click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrder1"/>
143149
<waitForElement selector="{{CheckoutSuccessMainSection.success}}" time="30" stepKey="waitForLoadSuccessPage1"/>
144150

151+
<!-- Start the usage processing consumer -->
152+
<actionGroup ref="CliConsumerStartActionGroup" stepKey="startUsageProcessingMessageQueue2">
153+
<argument name="consumerName" value="{{SalesRuleConsumerData.consumerName}}"/>
154+
<argument name="maxMessages" value="{{SalesRuleConsumerData.messageLimit}}"/>
155+
</actionGroup>
156+
145157
<!-- Step; 15-16. Open the Product Page, add the product to Cart, go to Shopping Cart and Apply the same coupon code -->
146158
<amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.name$$)}}" stepKey="openProductPage3"/>
147159
<waitForPageLoad stepKey="waitForPageLoad5"/>

app/code/Magento/SalesRule/composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"require": {
88
"php": "~7.3.0||~7.4.0",
99
"magento/framework": "*",
10+
"magento/framework-bulk": "*",
1011
"magento/module-backend": "*",
1112
"magento/module-catalog": "*",
1213
"magento/module-catalog-rule": "*",
@@ -25,7 +26,8 @@
2526
"magento/module-widget": "*",
2627
"magento/module-captcha": "*",
2728
"magento/module-checkout": "*",
28-
"magento/module-authorization": "*"
29+
"magento/module-authorization": "*",
30+
"magento/module-asynchronous-operations": "*"
2931
},
3032
"suggest": {
3133
"magento/module-sales-rule-sample-data": "*"

app/code/Magento/SalesRule/etc/communication.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
<topic name="sales_rule.codegenerator" request="Magento\SalesRule\Api\Data\CouponGenerationSpecInterface">
1010
<handler name="codegeneratorProcessor" type="Magento\SalesRule\Model\Coupon\Consumer" method="process" />
1111
</topic>
12+
<topic name="sales.rule.update.coupon.usage" request="Magento\AsynchronousOperations\Api\Data\OperationInterface">
13+
<handler name="sales.rule.update.coupon.usage" type="Magento\SalesRule\Model\CouponUsageConsumer" method="process" />
14+
</topic>
1215
</config>

app/code/Magento/SalesRule/etc/queue.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
<broker topic="sales_rule.codegenerator" exchange="magento-db" type="db">
1010
<queue name="codegenerator" consumer="codegeneratorProcessor" consumerInstance="Magento\Framework\MessageQueue\Consumer" handler="Magento\SalesRule\Model\Coupon\Consumer::process"/>
1111
</broker>
12+
<broker topic="sales.rule.update.coupon.usage" exchange="magento-db" type="db">
13+
<queue name="sales.rule.update.coupon.usage" consumer="sales.rule.update.coupon.usage" consumerInstance="Magento\Framework\MessageQueue\Consumer" handler="Magento\SalesRule\Model\CouponUsageConsumer::process"/>
14+
</broker>
1215
</config>

app/code/Magento/SalesRule/etc/queue_consumer.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd">
99
<consumer name="codegeneratorProcessor" queue="codegenerator" connection="db" maxMessages="5000" consumerInstance="Magento\Framework\MessageQueue\Consumer" handler="Magento\SalesRule\Model\Coupon\Consumer::process" />
10+
<consumer name="sales.rule.update.coupon.usage" queue="sales.rule.update.coupon.usage" connection="db" maxMessages="5000" consumerInstance="Magento\Framework\MessageQueue\Consumer" handler="Magento\SalesRule\Model\CouponUsageConsumer::process" />
1011
</config>

0 commit comments

Comments
 (0)