Skip to content

Commit

Permalink
🔃 [Magento Community Engineering] Community Contributions - 2.3-devel…
Browse files Browse the repository at this point in the history
…op expedited

Accepted Community Pull Requests:
 - #23387: #23386: Copy Service does not work properly for Entities which extends Data Object and implements ExtensibleDataInterface. (by @swnsma)
 - #20579: #12817: [Forwardport] Coupon code with canceled order. (by @p-bystritsky)


Fixed GitHub Issues:
 - #23386: Copy Service does not works properly for Entities which extends Data Object and implements ExtensibleDataInterface (reported by @swnsma) has been fixed in #23387 by @swnsma in 2.3-develop branch
   Related commits:
     1. 9852b08
     2. d70edfc
     3. 661874a
     4. 731a4fc

 - #12817: Coupon code with canceled order (reported by @AleksLi) has been fixed in #20579 by @p-bystritsky in 2.3-develop branch
   Related commits:
     1. 757856f
     2. 378f03c
     3. f02b0fa
     4. 53abf95
     5. 8f41977
     6. 6f3362f
  • Loading branch information
magento-engcom-team authored Jul 14, 2019
2 parents d200ae8 + 95e4a00 commit c63b388
Show file tree
Hide file tree
Showing 16 changed files with 822 additions and 402 deletions.
153 changes: 153 additions & 0 deletions app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\SalesRule\Model\Coupon;

use Magento\Sales\Model\Order;
use Magento\SalesRule\Model\Coupon;
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
use Magento\SalesRule\Model\Rule\CustomerFactory;
use Magento\SalesRule\Model\RuleFactory;

/**
* Updates the coupon usages.
*/
class UpdateCouponUsages
{
/**
* @var RuleFactory
*/
private $ruleFactory;

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

/**
* @var Coupon
*/
private $coupon;

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

/**
* @param RuleFactory $ruleFactory
* @param CustomerFactory $ruleCustomerFactory
* @param Coupon $coupon
* @param Usage $couponUsage
*/
public function __construct(
RuleFactory $ruleFactory,
CustomerFactory $ruleCustomerFactory,
Coupon $coupon,
Usage $couponUsage
) {
$this->ruleFactory = $ruleFactory;
$this->ruleCustomerFactory = $ruleCustomerFactory;
$this->coupon = $coupon;
$this->couponUsage = $couponUsage;
}

/**
* Executes the current command.
*
* @param Order $subject
* @param bool $increment
* @return Order
*/
public function execute(Order $subject, bool $increment): Order
{
if (!$subject || !$subject->getAppliedRuleIds()) {
return $subject;
}
// lookup rule ids
$ruleIds = explode(',', $subject->getAppliedRuleIds());
$ruleIds = array_unique($ruleIds);
$customerId = (int)$subject->getCustomerId();
// use each rule (and apply to customer, if applicable)
foreach ($ruleIds as $ruleId) {
if (!$ruleId) {
continue;
}
$this->updateRuleUsages($increment, (int)$ruleId, $customerId);
}
$this->updateCouponUsages($subject, $increment, $customerId);

return $subject;
}

/**
* Update the number of rule usages.
*
* @param bool $increment
* @param int $ruleId
* @param int $customerId
*/
private function updateRuleUsages(bool $increment, int $ruleId, int $customerId)
{
/** @var \Magento\SalesRule\Model\Rule $rule */
$rule = $this->ruleFactory->create();
$rule->load($ruleId);
if ($rule->getId()) {
$rule->loadCouponCode();
if ($increment || $rule->getTimesUsed() > 0) {
$rule->setTimesUsed($rule->getTimesUsed() + ($increment ? 1 : -1));
$rule->save();
}
if ($customerId) {
$this->updateCustomerRuleUsages($increment, $ruleId, $customerId);
}
}
}

/**
* Update the number of rule usages per customer.
*
* @param bool $increment
* @param int $ruleId
* @param int $customerId
*/
private function updateCustomerRuleUsages(bool $increment, int $ruleId, int $customerId): void
{
/** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */
$ruleCustomer = $this->ruleCustomerFactory->create();
$ruleCustomer->loadByCustomerRule($customerId, $ruleId);
if ($ruleCustomer->getId()) {
if ($increment || $ruleCustomer->getTimesUsed() > 0) {
$ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + ($increment ? 1 : -1));
}
} elseif ($increment) {
$ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(1);
}
$ruleCustomer->save();
}

/**
* Update the number of coupon usages.
*
* @param Order $subject
* @param bool $increment
* @param int $customerId
*/
private function updateCouponUsages(Order $subject, bool $increment, int $customerId): void
{
$this->coupon->load($subject->getCouponCode(), 'code');
if ($this->coupon->getId()) {
if ($increment || $this->coupon->getTimesUsed() > 0) {
$this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($increment ? 1 : -1));
$this->coupon->save();
}
if ($customerId) {
$this->couponUsage->updateCustomerCouponTimesUsed($customerId, $this->coupon->getId(), $increment);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ protected function _construct()
*
* @param int $customerId
* @param mixed $couponId
* @param bool $increment
* @return void
*/
public function updateCustomerCouponTimesUsed($customerId, $couponId)
public function updateCustomerCouponTimesUsed($customerId, $couponId, $increment = true): void
{
$connection = $this->getConnection();
$select = $connection->select();
Expand All @@ -44,13 +45,13 @@ public function updateCustomerCouponTimesUsed($customerId, $couponId)

$timesUsed = $connection->fetchOne($select, [':coupon_id' => $couponId, ':customer_id' => $customerId]);

if ($timesUsed > 0) {
if ($timesUsed !== false) {
$this->getConnection()->update(
$this->getMainTable(),
['times_used' => $timesUsed + 1],
['times_used' => $timesUsed + ($increment ? 1 : -1)],
['coupon_id = ?' => $couponId, 'customer_id = ?' => $customerId]
);
} else {
} elseif ($increment) {
$this->getConnection()->insert(
$this->getMainTable(),
['coupon_id' => $couponId, 'customer_id' => $customerId, 'times_used' => 1]
Expand Down
110 changes: 0 additions & 110 deletions app/code/Magento/SalesRule/Observer/SalesOrderAfterPlaceObserver.php

This file was deleted.

49 changes: 49 additions & 0 deletions app/code/Magento/SalesRule/Plugin/CouponUsagesDecrement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\SalesRule\Plugin;

use Magento\Sales\Model\Order;
use Magento\SalesRule\Model\Coupon\UpdateCouponUsages;

/**
* Decrements number of coupon usages after cancelling order.
*/
class CouponUsagesDecrement
{
/**
* @var UpdateCouponUsages
*/
private $updateCouponUsages;

/**
* @param UpdateCouponUsages $updateCouponUsages
*/
public function __construct(
UpdateCouponUsages $updateCouponUsages
) {
$this->updateCouponUsages = $updateCouponUsages;
}

/**
* Decrements number of coupon usages after cancelling order.
*
* @param Order $subject
* @param callable $proceed
* @return Order
*/
public function aroundCancel(Order $subject, callable $proceed): Order
{
$canCancel = $subject->canCancel();
$returnValue = $proceed();
if ($canCancel) {
$returnValue = $this->updateCouponUsages->execute($returnValue, false);
}

return $returnValue;
}
}
46 changes: 46 additions & 0 deletions app/code/Magento/SalesRule/Plugin/CouponUsagesIncrement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\SalesRule\Plugin;

use Magento\Sales\Model\Order;
use Magento\SalesRule\Model\Coupon\UpdateCouponUsages;

/**
* Increments number of coupon usages after placing order.
*/
class CouponUsagesIncrement
{
/**
* @var UpdateCouponUsages
*/
private $updateCouponUsages;

/**
* @param UpdateCouponUsages $updateCouponUsages
*/
public function __construct(
UpdateCouponUsages $updateCouponUsages
) {
$this->updateCouponUsages = $updateCouponUsages;
}

/**
* Increments number of coupon usages after placing order.
*
* @param Order $subject
* @param Order $result
* @return Order
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterPlace(Order $subject, Order $result): Order
{
$this->updateCouponUsages->execute($subject, true);

return $subject;
}
}
Loading

0 comments on commit c63b388

Please sign in to comment.