diff --git a/src/include/class-wc-retailcrm-loyalty.php b/src/include/class-wc-retailcrm-loyalty.php index f6eb2fb..67ab5d7 100644 --- a/src/include/class-wc-retailcrm-loyalty.php +++ b/src/include/class-wc-retailcrm-loyalty.php @@ -432,24 +432,22 @@ if (!class_exists('WC_Retailcrm_Loyalty')) : $response = $this->apiClient->ordersGet($orderExternalId); - if (!$response instanceof WC_Retailcrm_Response || !$response->isSuccessful()) { - writeBaseLogs('Process order: Error when receiving an order from the crm. Order Id: ' . $orderExternalId); + if (!$response instanceof WC_Retailcrm_Response || !$response->isSuccessful() || !isset($response['order'])) { + writeBaseLogs('Process order: Error when receiving an order from the CRM. Order Id: ' . $orderExternalId); return []; } - if (isset($response['order'])) { - foreach ($response['order']['items'] as $item) { - $externalId = $item['externalIds'][0]['value']; - $externalId = preg_replace('/^\d+\_/m', '', $externalId); - $crmItems[$externalId] = $item; + foreach ($response['order']['items'] as $item) { + $externalId = $item['externalIds'][0]['value']; + $externalId = preg_replace('/^\d+\_/m', '', $externalId); + $crmItems[$externalId] = $item; - if (!$discountType) { - foreach ($item['discounts'] as $discount) { - if (in_array($discount['type'], ['bonus_charge', 'loyalty_level'])) { - $discountType = $discount['type']; - break; - } + if (!$discountType) { + foreach ($item['discounts'] as $discount) { + if (in_array($discount['type'], ['bonus_charge', 'loyalty_level'])) { + $discountType = $discount['type']; + break; } } } diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 9d0abb0..7bda5ae 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -102,22 +102,23 @@ if (!class_exists('WC_Retailcrm_Orders')) : $wcOrder = wc_get_order($orderId); if ($this->loyalty) { + $wcCustomer = null; $privilegeType = 'none'; $discountLp = $this->loyalty->deleteLoyaltyCouponInOrder($wcOrder); - $data = $wcOrder->get_data(); + $dataOrder = $wcOrder->get_data(); - if (isset($data['customer_id'])) { - $wcCustomer = new WC_Customer($data['customer_id']); + if (isset($dataOrder['customer_id'])) { + $wcCustomer = new WC_Customer($dataOrder['customer_id']) ?? null; } - if (!$this->loyalty->isValidOrder($wcCustomer ?? null, $wcOrder)) { + if (!$this->loyalty->isValidOrder($wcCustomer, $wcOrder)) { if ($discountLp > 0) { writeBaseLogs('The user does not meet the requirements for working with the loyalty program. Order Id: ' . $orderId); } $discountLp = 0; $privilegeType = 'none'; - } elseif ($this->loyalty->isValidUser($wcCustomer ?? null)) { + } elseif ($this->loyalty->isValidUser($wcCustomer)) { $privilegeType = 'loyalty_level'; } } diff --git a/src/include/order/class-wc-retailcrm-order-item.php b/src/include/order/class-wc-retailcrm-order-item.php index c25f955..53e593a 100644 --- a/src/include/order/class-wc-retailcrm-order-item.php +++ b/src/include/order/class-wc-retailcrm-order-item.php @@ -115,7 +115,7 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data * @param WC_Order_Item_Product $item * @param $price * @param int $decimalPlaces Price rounding from WC settings - * + * @param array|null $crmItem Current trade position in CRM * @return float|int */ private function calculateDiscount( @@ -135,6 +135,9 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data } } + /** + * The loyalty program discount is calculated within the CRM system. It must be deleted during transfer to avoid duplication. + */ $productPrice = ($item->get_total() / $item->get_quantity()) + ($loyaltyDiscount / $crmItem['quantity']); if ($this->cancelLoyalty) { @@ -171,10 +174,19 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data $this->cancelLoyalty = $cancelLoyalty; } + /** + * Checking whether the loyalty program discount needs to be canceled. (Changing the sales items in the order) + * + * @param array $wcItems + * @param array $crmItems + * + * @return bool + */ public function isCancelLoyalty($wcItems, $crmItems): bool { $loyaltyDiscount = 0; + /** If the number of sales items does not match */ if (count($wcItems) !== count($crmItems)) { $this->cancelLoyalty = true; @@ -182,12 +194,14 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data } foreach ($wcItems as $id => $item) { + /** If a trading position has been added/deleted */ if (!isset($crmItems[$id])) { $this->cancelLoyalty = true; return true; } + /** If the quantity of goods in a trade item does not match */ if ($item->get_quantity() !== $crmItems[$id]['quantity']) { $this->cancelLoyalty = true; @@ -202,6 +216,10 @@ class WC_Retailcrm_Order_Item extends WC_Retailcrm_Abstracts_Data } } + /** + *If the sum of the trade item including discounts and loyalty program discount exceeds the cost without discounts. + * (Occurs when recalculating an order, deleting/adding coupons) + */ if (($item->get_total() + $loyaltyDiscount) > $item->get_subtotal()) { $this->cancelLoyalty = true; diff --git a/tests/test-wc-retailcrm-loyalty.php b/tests/test-wc-retailcrm-loyalty.php index c511081..8e53969 100644 --- a/tests/test-wc-retailcrm-loyalty.php +++ b/tests/test-wc-retailcrm-loyalty.php @@ -330,6 +330,7 @@ class WC_Retailcrm_Loyalty_Test extends WC_Retailcrm_Test_Case_Helper { $products = DataLoyaltyRetailCrm::createProducts(); $user = DataLoyaltyRetailcrm::createUsers()[0]; + $discountLoyalty = 50; $wcOrder = wc_create_order([ 'status' => null, @@ -391,7 +392,7 @@ class WC_Retailcrm_Loyalty_Test extends WC_Retailcrm_Test_Case_Helper $this->setMockResponse($this->apiMock, 'applyBonusToOrder', $response); $this->loyalty = new WC_Retailcrm_Loyalty($this->apiMock, []); - $this->loyalty->applyLoyaltyDiscount($wcOrder, $createdCrmOrderResponse, 50); + $this->loyalty->applyLoyaltyDiscount($wcOrder, $createdCrmOrderResponse, $discountLoyalty); foreach ($wcOrder->get_items() as $id => $item) { $this->assertNotEquals($item->get_total(), $currentItemsPrice[$id]); @@ -456,7 +457,7 @@ class WC_Retailcrm_Loyalty_Test extends WC_Retailcrm_Test_Case_Helper ] ]; - $this->loyalty->applyLoyaltyDiscount($wcOrder, $createdCrmOrderResponse, 0); + $this->loyalty->applyLoyaltyDiscount($wcOrder, $createdCrmOrderResponse); foreach ($wcOrder->get_items() as $id => $item) { $this->assertNotEquals($item->get_total(), $currentItemsPrice[$id]);