Skip to content

Commit

Permalink
Merge branch 'multicoupon' of github.com:magento-lynx/magento2ce into…
Browse files Browse the repository at this point in the history
… multicoupon-delivery
  • Loading branch information
sivaschenko committed Feb 19, 2024
2 parents fd9a4be + 575c037 commit b07a843
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 62 deletions.
5 changes: 4 additions & 1 deletion app/code/Magento/SalesGraphQl/Model/Formatter/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Magento\SalesGraphQl\Model\Formatter;

use Magento\Framework\Exception\LocalizedException;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\SalesGraphQl\Model\Order\OrderAddress;
use Magento\SalesGraphQl\Model\Order\OrderPayments;
Expand Down Expand Up @@ -43,13 +44,14 @@ public function __construct(
*
* @param OrderInterface $orderModel
* @return array
* @throws LocalizedException
*/
public function format(OrderInterface $orderModel): array
{
return [
'created_at' => $orderModel->getCreatedAt(),
'grand_total' => $orderModel->getGrandTotal(),
'id' => base64_encode($orderModel->getEntityId()),
'id' => base64_encode((string)$orderModel->getEntityId()),
'increment_id' => $orderModel->getIncrementId(),
'number' => $orderModel->getIncrementId(),
'order_date' => $orderModel->getCreatedAt(),
Expand All @@ -59,6 +61,7 @@ public function format(OrderInterface $orderModel): array
'shipping_address' => $this->orderAddress->getOrderShippingAddress($orderModel),
'billing_address' => $this->orderAddress->getOrderBillingAddress($orderModel),
'payment_methods' => $this->orderPayments->getOrderPaymentMethod($orderModel),
'applied_coupons' => $orderModel->getCouponCode() ? ['code' => $orderModel->getCouponCode()] : [],
'model' => $orderModel,
];
}
Expand Down
1 change: 1 addition & 0 deletions app/code/Magento/SalesGraphQl/etc/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type CustomerOrder @doc(description: "Contains details about each of the custome
created_at: String @deprecated(reason: "Use the `order_date` field instead.")
grand_total: Float @deprecated(reason: "Use the `totals.grand_total` field instead.")
token: String! @doc(description: "The token that can be used to retrieve the order using order query.") @resolver(class: "Magento\\SalesGraphQl\\Model\\Resolver\\Token")
applied_coupons: [AppliedCoupon!]! @doc(description: "Coupons applied to the order.")
}

type OrderAddress @doc(description: "Contains detailed information about an order's billing and shipping addresses."){
Expand Down
86 changes: 40 additions & 46 deletions app/code/Magento/SalesRule/Model/Coupon/Usage/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

namespace Magento\SalesRule\Model\Coupon\Usage;

use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Model\Coupon;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
use Magento\SalesRule\Model\Rule\CustomerFactory;
use Magento\SalesRule\Model\RuleFactory;
Expand All @@ -18,42 +19,20 @@
*/
class Processor
{
/**
* @var RuleFactory
*/
private $ruleFactory;

/**
* @var CustomerFactory
*/
private $ruleCustomerFactory;

/**
* @var CouponFactory
*/
private $couponFactory;

/**
* @var Usage
*/
private $couponUsage;

/**
* @param RuleFactory $ruleFactory
* @param CustomerFactory $ruleCustomerFactory
* @param CouponFactory $couponFactory
* @param Usage $couponUsage
* @param CouponRepositoryInterface $couponRepository
* @param SearchCriteriaBuilder $criteriaBuilder
*/
public function __construct(
RuleFactory $ruleFactory,
CustomerFactory $ruleCustomerFactory,
CouponFactory $couponFactory,
Usage $couponUsage
private readonly RuleFactory $ruleFactory,
private readonly CustomerFactory $ruleCustomerFactory,
private readonly Usage $couponUsage,
private readonly CouponRepositoryInterface $couponRepository,
private readonly SearchCriteriaBuilder $criteriaBuilder
) {
$this->ruleFactory = $ruleFactory;
$this->ruleCustomerFactory = $ruleCustomerFactory;
$this->couponFactory = $couponFactory;
$this->couponUsage = $couponUsage;
}

/**
Expand All @@ -79,16 +58,18 @@ public function process(UpdateInfo $updateInfo): void
*/
public function updateCouponUsages(UpdateInfo $updateInfo): void
{
$coupon = $this->retrieveCoupon($updateInfo);
if (!$coupon) {
$isIncrement = $updateInfo->isIncrement();
$coupons = $this->retrieveCoupons($updateInfo);

if ($updateInfo->isCouponAlreadyApplied()) {
return;
}

$isIncrement = $updateInfo->isIncrement();
if (!$updateInfo->isCouponAlreadyApplied()
&& ($updateInfo->isIncrement() || $coupon->getTimesUsed() > 0)) {
$coupon->setTimesUsed($coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
$coupon->save();
foreach ($coupons as $coupon) {
if ($updateInfo->isIncrement() || $coupon->getTimesUsed() > 0) {
$coupon->setTimesUsed($coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
$coupon->save();
}
}
}

Expand Down Expand Up @@ -129,11 +110,16 @@ public function updateCustomerRulesUsages(UpdateInfo $updateInfo): void

$isIncrement = $updateInfo->isIncrement();
foreach ($updateInfo->getAppliedRuleIds() as $ruleId) {
$rule = $this->ruleFactory->create();
$rule->load($ruleId);
if (!$rule->getId()) {
continue;
}
$this->updateCustomerRuleUsages($isIncrement, $ruleId, $customerId);
}

$coupon = $this->retrieveCoupon($updateInfo);
if ($coupon) {
$coupons = $this->retrieveCoupons($updateInfo);
foreach ($coupons as $coupon) {
$this->couponUsage->updateCustomerCouponTimesUsed($customerId, $coupon->getId(), $isIncrement);
}
}
Expand Down Expand Up @@ -167,17 +153,25 @@ private function updateCustomerRuleUsages(bool $isIncrement, int $ruleId, int $c
* Retrieve coupon from update info
*
* @param UpdateInfo $updateInfo
* @return Coupon|null
* @return Coupon[]
*/
private function retrieveCoupon(UpdateInfo $updateInfo): ?Coupon
private function retrieveCoupons(UpdateInfo $updateInfo): array
{
if (!$updateInfo->getCouponCode()) {
return null;
if (!$updateInfo->getCouponCode() && empty($updateInfo->getCouponCodes())) {
return [];
}

$coupon = $this->couponFactory->create();
$coupon->loadByCode($updateInfo->getCouponCode());
$coupons = $updateInfo->getCouponCodes();
if ($updateInfo->getCouponCode() && !in_array($updateInfo->getCouponCode(), $coupons)) {
array_unshift($coupons, $updateInfo->getCouponCode());
}

return $coupon->getId() ? $coupon : null;
return $this->couponRepository->getList(
$this->criteriaBuilder->addFilter(
'code',
$coupons,
'in'
)->create()
)->getItems();
}
}
22 changes: 22 additions & 0 deletions app/code/Magento/SalesRule/Model/Coupon/Usage/UpdateInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class UpdateInfo extends DataObject
private const CUSTOMER_ID_KEY = 'customer_id';
private const IS_INCREMENT_KEY = 'is_increment';
private const IS_COUPON_ALREADY_APPLIED = 'is_coupon_already_applied';
private const COUPON_CODES = 'coupon_codes';

/**
* Get applied rule ids
Expand Down Expand Up @@ -62,6 +63,27 @@ public function setCouponCode(string $value): void
$this->setData(self::COUPON_CODE_KEY, $value);
}

/**
* Get coupon code
*
* @return string[]
*/
public function getCouponCodes(): array
{
return $this->getData(self::COUPON_CODES) ?? [];
}

/**
* Set coupon code
*
* @param string[] $value
* @return void
*/
public function setCouponCodes(array $value): void
{
$this->setData(self::COUPON_CODES, $value);
}

/**
* Get customer id
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

namespace Magento\SalesRule\Test\Unit\Model\Coupon\Usage;

use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Api\Data\CouponSearchResultInterface;
use Magento\SalesRule\Model\Coupon;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\Coupon\Usage\Processor;
use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
Expand All @@ -19,6 +22,9 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ProcessorTest extends TestCase
{
/**
Expand All @@ -36,11 +42,6 @@ class ProcessorTest extends TestCase
*/
private $ruleCustomerFactoryMock;

/**
* @var CouponFactory|MockObject
*/
private $couponFactoryMock;

/**
* @var Usage|MockObject
*/
Expand All @@ -51,22 +52,37 @@ class ProcessorTest extends TestCase
*/
private $updateInfoMock;

/**
* @var CouponRepositoryInterface|CouponRepositoryInterface&MockObject|MockObject
*/
private $couponRepository;

/**
* @var SearchCriteriaBuilder|SearchCriteriaBuilder&MockObject|MockObject
*/
private $criteriaBuilder;

/**
* @inheritDoc
*/
protected function setUp(): void
{
$this->ruleFactoryMock = $this->createMock(RuleFactory::class);
$this->ruleCustomerFactoryMock = $this->createMock(CustomerFactory::class);
$this->couponFactoryMock = $this->createMock(CouponFactory::class);
$this->couponUsageMock = $this->createMock(Usage::class);
$this->updateInfoMock = $this->createMock(UpdateInfo::class);
$this->couponRepository = $this->createMock(CouponRepositoryInterface::class);
$this->criteriaBuilder = $this->createMock(SearchCriteriaBuilder::class);
$this->criteriaBuilder->method('addFilter')->willReturnSelf();
$searchCriteria = $this->createMock(SearchCriteriaInterface::class);
$this->criteriaBuilder->method('create')->willReturn($searchCriteria);

$this->processor = new Processor(
$this->ruleFactoryMock,
$this->ruleCustomerFactoryMock,
$this->couponFactoryMock,
$this->couponUsageMock
$this->couponUsageMock,
$this->couponRepository,
$this->criteriaBuilder
);
}

Expand All @@ -92,8 +108,10 @@ public function testProcess($isIncrement, $timesUsed): void
$this->updateInfoMock->expects($this->atLeastOnce())->method('isIncrement')->willReturn($isIncrement);

$couponMock = $this->createMock(Coupon::class);
$this->couponFactoryMock->expects($this->exactly(2))->method('create')->willReturn($couponMock);
$couponMock->expects($this->exactly(2))->method('loadByCode')->with($couponCode)->willReturnSelf();
$searchResult = $this->createMock(CouponSearchResultInterface::class);
$searchResult->method('getItems')
->willReturn([$couponMock]);
$this->couponRepository->method('getList')->willReturn($searchResult);
$couponMock->expects($this->atLeastOnce())->method('getId')->willReturn($couponId);
$couponMock->expects($this->atLeastOnce())->method('getTimesUsed')->willReturn($timesUsed);
$couponMock->expects($this->any())->method('setTimesUsed')->with($setTimesUsed)->willReturnSelf();
Expand Down Expand Up @@ -127,12 +145,12 @@ public function testProcess($isIncrement, $timesUsed): void
->addMethods(['getTimesUsed', 'setTimesUsed'])
->disableOriginalConstructor()
->getMock();
$ruleMock->expects($this->once())->method('load')->willReturnSelf();
$ruleMock->expects($this->once())->method('getId')->willReturn(true);
$ruleMock->expects($this->once())->method('loadCouponCode')->willReturnSelf();
$ruleMock->expects($this->atLeastOnce())->method('load')->willReturnSelf();
$ruleMock->expects($this->atLeastOnce())->method('getId')->willReturn(true);
$ruleMock->expects($this->atLeastOnce())->method('loadCouponCode')->willReturnSelf();
$ruleMock->expects($this->any())->method('getTimesUsed')->willReturn($timesUsed);
$ruleMock->expects($this->any())->method('setTimesUsed')->willReturn($setTimesUsed);
$this->ruleFactoryMock->expects($this->once())->method('create')->willReturn($ruleMock);
$this->ruleFactoryMock->expects($this->atLeastOnce())->method('create')->willReturn($ruleMock);

$this->processor->process($this->updateInfoMock);
}
Expand Down

0 comments on commit b07a843

Please sign in to comment.