Skip to content

Commit b17c043

Browse files
committed
ACP2E-1053: Generate coupon codes ignores Code Length
- Added the validation based on the coupon code probability calculation.
1 parent 9aa35fd commit b17c043

File tree

5 files changed

+109
-1
lines changed

5 files changed

+109
-1
lines changed

app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\SalesRule\Model\CouponGenerator;
1111
use Magento\Framework\MessageQueue\PublisherInterface;
1212
use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
13+
use Magento\SalesRule\Model\Quote\ValidateCouponLengthWithQuantityInterface;
1314

1415
/**
1516
* Generate promo quote
@@ -33,6 +34,11 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote imple
3334
*/
3435
private $generationSpecFactory;
3536

37+
/**
38+
* @var ValidateCouponLengthWithQuantityInterface
39+
*/
40+
private $validateCouponLengthWithQuantity;
41+
3642
/**
3743
* Generate constructor.
3844
* @param \Magento\Backend\App\Action\Context $context
@@ -42,6 +48,7 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote imple
4248
* @param CouponGenerator|null $couponGenerator
4349
* @param PublisherInterface|null $publisher
4450
* @param CouponGenerationSpecInterfaceFactory|null $generationSpecFactory
51+
* @param ValidateCouponLengthWithQuantityInterface|null $validateCouponLengthWithQuantity
4552
*/
4653
public function __construct(
4754
\Magento\Backend\App\Action\Context $context,
@@ -50,7 +57,8 @@ public function __construct(
5057
\Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
5158
CouponGenerator $couponGenerator = null,
5259
PublisherInterface $publisher = null,
53-
CouponGenerationSpecInterfaceFactory $generationSpecFactory = null
60+
CouponGenerationSpecInterfaceFactory $generationSpecFactory = null,
61+
ValidateCouponLengthWithQuantityInterface $validateCouponLengthWithQuantity = null
5462
) {
5563
parent::__construct($context, $coreRegistry, $fileFactory, $dateFilter);
5664
$this->couponGenerator = $couponGenerator ?:
@@ -61,6 +69,10 @@ public function __construct(
6169
\Magento\Framework\App\ObjectManager::getInstance()->get(
6270
CouponGenerationSpecInterfaceFactory::class
6371
);
72+
$this->validateCouponLengthWithQuantity = $validateCouponLengthWithQuantity ?:
73+
\Magento\Framework\App\ObjectManager::getInstance()->get(
74+
ValidateCouponLengthWithQuantityInterface::class
75+
);
6476
}
6577

6678
/**
@@ -86,6 +98,25 @@ public function execute()
8698
&& !$rule->getUseAutoGeneration()) {
8799
$result['error'] =
88100
__('The rule coupon settings changed. Please save the rule before using auto-generation.');
101+
} elseif (
102+
(int)$this->getRequest()->getParams()['length'] !==
103+
$this->validateCouponLengthWithQuantity->validateCouponCodeLengthWithQuantity(
104+
$this->getRequest()->getParams()
105+
)
106+
) {
107+
$minimumLength = $this->validateCouponLengthWithQuantity->validateCouponCodeLengthWithQuantity(
108+
$this->getRequest()->getParams()
109+
);
110+
$quantity = $this->getRequest()->getParams()['qty'];
111+
$this->messageManager->addErrorMessage(
112+
__(
113+
'When coupon quantity exceeds %1, the coupon code length must be minimum %2',
114+
$quantity,
115+
$minimumLength
116+
)
117+
);
118+
$this->_view->getLayout()->initMessages();
119+
$result['messages'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml();
89120
} else {
90121
try {
91122
$data = $this->getRequest()->getParams();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\SalesRule\Model\Quote;
10+
11+
use Magento\SalesRule\Model\Coupon\Massgenerator;
12+
use Magento\SalesRule\Helper\Coupon;
13+
14+
/**
15+
* Validate the coupon code length and quantity.
16+
*/
17+
class ValidateCouponLengthWithQuantity implements ValidateCouponLengthWithQuantityInterface
18+
{
19+
/**
20+
* Sales rule coupon
21+
*
22+
* @var Coupon
23+
*/
24+
protected Coupon $salesRuleCoupon;
25+
26+
/**
27+
* @param Coupon $salesRuleCoupon
28+
*/
29+
public function __construct(
30+
Coupon $salesRuleCoupon
31+
) {
32+
$this->salesRuleCoupon = $salesRuleCoupon;
33+
}
34+
35+
public function validateCouponCodeLengthWithQuantity(array $couponCodeDataArray): int
36+
{
37+
$maxProbability = Massgenerator::MAX_PROBABILITY_OF_GUESSING;
38+
$chars = count($this->salesRuleCoupon->getCharset($couponCodeDataArray['format']));
39+
$size = $couponCodeDataArray['qty'];
40+
$length = (int)$couponCodeDataArray['length'];
41+
$maxCodes = pow($chars, $length);
42+
$probability = $size / $maxCodes;
43+
44+
if ($probability > $maxProbability) {
45+
do {
46+
$length++;
47+
$maxCodes = pow($chars, $length);
48+
$probability = $size / $maxCodes;
49+
} while ($probability > $maxProbability);
50+
}
51+
return $length;
52+
}
53+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\SalesRule\Model\Quote;
7+
8+
/**
9+
* Validate the coupon code length and quantity.
10+
*/
11+
interface ValidateCouponLengthWithQuantityInterface
12+
{
13+
/**
14+
* Validate coupon code length with quantity
15+
*
16+
* @param array $couponCodeDataArray
17+
* @return int
18+
*/
19+
public function validateCouponCodeLengthWithQuantity(array $couponCodeDataArray): int;
20+
}

app/code/Magento/SalesRule/etc/adminhtml/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@
2222
<preference
2323
for="Magento\SalesRule\Model\Spi\CodeLimitManagerInterface"
2424
type="Magento\SalesRule\Model\Coupon\AdminCodeLimitManager" />
25+
<preference
26+
for="Magento\SalesRule\Model\Quote\ValidateCouponLengthWithQuantityInterface"
27+
type="Magento\SalesRule\Model\Quote\ValidateCouponLengthWithQuantity" />
2528
</config>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,4 @@ Apply,Apply
167167
"Rule is not saved with auto generate option enabled. Please save the rule and try again.", "Rule is not saved with auto generate option enabled. Please save the rule and try again."
168168
"Trigger recollect totals for quotes by rule ID %1","Trigger recollect totals for quotes by rule ID %1"
169169
"Sorry, something went wrong while triggering recollect totals for affected quotes. Please see log for details.","Sorry, something went wrong while triggering recollect totals for affected quotes. Please see log for details."
170+
"When coupon quantity exceeds %1, the coupon code length must be minimum %2", "When coupon quantity exceeds %1, the coupon code length must be minimum %2"

0 commit comments

Comments
 (0)