From d60d7be6b218507abcbf56ab135573852472123d Mon Sep 17 00:00:00 2001 From: Ivan Chaplygin Date: Thu, 23 May 2024 18:03:02 +0300 Subject: [PATCH] ref #94823 Processing of discounts and their cancelation when changing trade positions --- .../api/class-wc-retailcrm-client-v5.php | 4 +- src/include/class-wc-retailcrm-loyalty.php | 2 +- src/include/class-wc-retailcrm-orders.php | 28 ++++++++++-- .../order/class-wc-retailcrm-order-item.php | 44 ++++++++++++++++++- 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/include/api/class-wc-retailcrm-client-v5.php b/src/include/api/class-wc-retailcrm-client-v5.php index 35b75b1..6e7623f 100644 --- a/src/include/api/class-wc-retailcrm-client-v5.php +++ b/src/include/api/class-wc-retailcrm-client-v5.php @@ -3011,12 +3011,12 @@ class WC_Retailcrm_Client_V5 ); } - public function cancelBonusOrder(string $site, array $order) + public function cancelBonusOrder(array $order) { return $this->client->makeRequest( "/orders/loyalty/cancel-bonus-operations", WC_Retailcrm_Request::METHOD_POST, - ['site' => $site, 'order' => json_encode($order)] + ['order' => json_encode($order)] ); } diff --git a/src/include/class-wc-retailcrm-loyalty.php b/src/include/class-wc-retailcrm-loyalty.php index c6da194..6d818cd 100644 --- a/src/include/class-wc-retailcrm-loyalty.php +++ b/src/include/class-wc-retailcrm-loyalty.php @@ -396,7 +396,7 @@ if (!class_exists('WC_Retailcrm_Loyalty')) : $wcItem = $wcItems[(int) $externalId]; $wcItem->set_total($wcItem->get_total() - $discountLoyaltyTotal); $wcItem->calculate_taxes(); - $wcItem->save(); + $wcItem->save();// TODO Возможно это не нужно вводить, т.к. calculate_totals автоматом пересчитает } } diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index aaafc03..deba2c8 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -44,6 +44,12 @@ if (!class_exists('WC_Retailcrm_Orders')) : /** @var array */ private $order = []; + /** @var bool */ + private $cancelBonus = false; + + /** @var float */ + private $appliedBonuses = 0; + /** @var array */ private $payment = []; @@ -305,7 +311,19 @@ if (!class_exists('WC_Retailcrm_Orders')) : $this->processOrder($wcOrder, true); - $response = $this->retailcrm->ordersEdit($this->order); + if ($this->cancelBonus) { + $this->cancelBonus = false; + $this->order_item->cancelBonus = false; + + $this->retailcrm->cancelBonusOrder(['externalId' => $this->order['externalId']]); + + $response = $this->retailcrm->ordersEdit($this->order); + + $wcOrder->calculate_totals(); + } else { + $response = $this->retailcrm->ordersEdit($this->order); + } + // Allows you to verify order changes and perform additional actions $response = apply_filters('retailcrm_order_update_after', $response, $wcOrder); @@ -450,6 +468,7 @@ if (!class_exists('WC_Retailcrm_Orders')) : $orderItems = []; $crmItems = []; // необходимо для обновления торговой позиции (определения кол-ва списываемых бонусов) $loyaltyDiscountType = null; // вид скидки + $wcItems = $order->get_items(); if ($this->loyalty && $update) { $response = $this->retailcrm->ordersGet($order->get_id()); @@ -460,6 +479,7 @@ if (!class_exists('WC_Retailcrm_Orders')) : $crmOrder = null; } else { $crmOrder = $response['order'] ?? null; + $this->appliedBonuses = $crmOrder['bonusesChargeTotal'] ?? 0; } } @@ -479,15 +499,15 @@ if (!class_exists('WC_Retailcrm_Orders')) : } } - unset($crmOrder); + $this->cancelBonus = $this->order_item->isCancelBonus($wcItems, $crmItems); } /** @var WC_Order_Item_Product $item */ - foreach ($order->get_items() as $id => $item) { + foreach ($wcItems as $id => $item) { $crmItem = $crmItems[$id] ?? null; $orderItems[] = $this->order_item->build($item, $crmItem)->getData(); - $this->order_item->resetData(); + $this->order_item->resetData($this->cancelBonus); } unset($crmItems, $crmItem); diff --git a/src/include/order/class-wc-retailcrm-order-item.php b/src/include/order/class-wc-retailcrm-order-item.php index 3dfe9db..a23cbe8 100644 --- a/src/include/order/class-wc-retailcrm-order-item.php +++ b/src/include/order/class-wc-retailcrm-order-item.php @@ -28,6 +28,9 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data */ protected $settings = []; + /** @var bool */ + public $cancelBonus = false; + /** * WC_Retailcrm_Order_Item constructor. * @@ -128,11 +131,21 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data foreach ($crmItem['discounts'] as $discount) { if (in_array($discount['type'], ['bonus_charge', 'loyalty_level'])) { $loyaltyDiscount += $discount['amount']; + break; } } - $productPrice = $item->get_total() ? $item->get_total() + $loyaltyDiscount / $item->get_quantity() : 0; + if ($item->get_total()) { + $productPrice = ($item->get_total() / $item->get_quantity()) + ($loyaltyDiscount / $crmItem['quantity']); + } else { + $productPrice = 0; + } + + if ($this->cancelBonus) { + $item->set_total($item->get_total() + $loyaltyDiscount); + $item->calculate_taxes(); + } } else { $productPrice = $item->get_total() ? $item->get_total() / $item->get_quantity() : 0; } @@ -146,7 +159,7 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data /** * Reset item data. */ - public function resetData() + public function resetData($cancelBonus) { $this->data = [ 'offer' => [], @@ -154,5 +167,32 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data 'initialPrice' => 0.00, 'quantity' => 0.00 ]; + + $this->cancelBonus = $cancelBonus; + } + + public function isCancelBonus($wcItems, $crmItems): bool + { + if (count($wcItems) !== count($crmItems)) { + $this->cancelBonus = true; + + return true; + } + + foreach ($wcItems as $id => $item) { + if (!isset($crmItems[$id])) { + $this->cancelBonus = true; + + return true; + } + + if ($item->get_quantity() !== $crmItems[$id]['quantity']) { + $this->cancelBonus = true; + + return true; + } + } + + return false; } }