diff --git a/src/include/api/class-wc-retailcrm-client-v5.php b/src/include/api/class-wc-retailcrm-client-v5.php index 485db22..35b75b1 100644 --- a/src/include/api/class-wc-retailcrm-client-v5.php +++ b/src/include/api/class-wc-retailcrm-client-v5.php @@ -2992,12 +2992,12 @@ class WC_Retailcrm_Client_V5 } /** Maximum discount calculation */ - public function calculateDiscountLoyalty(string $site, array $order, float $bonuses) + public function calculateDiscountLoyalty(string $site, array $order) { return $this->client->makeRequest( "/loyalty/calculate", WC_Retailcrm_Request::METHOD_POST, - ['site' => $site, 'order' => json_encode($order), 'bonuses' => $bonuses] + ['site' => $site, 'order' => json_encode($order)] ); } diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php index f7d29f5..2001c0c 100644 --- a/src/include/class-wc-retailcrm-base.php +++ b/src/include/class-wc-retailcrm-base.php @@ -110,6 +110,13 @@ if (!class_exists('WC_Retailcrm_Base')) { add_action('init', [$this, 'add_loyalty_endpoint'], 11, 1); add_action('woocommerce_account_menu_items', [$this, 'add_loyalty_item'], 11, 1); add_action('woocommerce_account_loyalty_endpoint', [$this, 'show_loyalty'], 11, 1); + + // Add coupon hooks for loyalty program + add_action('woocommerce_cart_coupon', [$this, 'coupon_info'], 11, 1); + add_action('woocommerce_add_to_cart', [$this, 'set_cart_loyalty'], 11, 1); + add_action('woocommerce_after_cart_item_quantity_update', [$this, 'set_cart_loyalty'], 11, 1); + add_action('woocommerce_cart_item_removed', [$this, 'set_cart_loyalty'], 11, 1); + add_action('woocommerce_cart_emptied', [$this, 'clear_cart_loyalty'], 11, 1); } // Subscribed hooks @@ -680,6 +687,65 @@ if (!class_exists('WC_Retailcrm_Base')) { wp_die(); } + public function coupon_info() + { + global $woocommerce; + + try { + $site = $this->apiClient->getSingleSiteForKey(); + $cartItems = $woocommerce->cart->get_cart(); + $customerId = $woocommerce->customer->get_id(); + + if (!$customerId || !$cartItems) { + return; + } + + $validator = new WC_Retailcrm_Loyalty_Validator($this->apiClient, $this->settings['corporate_enabled'] ?? static::NO); + + if (!$validator->checkAccount($customerId)) { + return; + } + + $lpDiscountSum = $this->loyalty->getDiscountLp($cartItems, $site, $customerId); + + if ($lpDiscountSum === 0) { + return; + } + + $coupon = new WC_Coupon(); + + //$coupon->set_individual_use(true); // запрещает использование других купонов одноврменно с этим + $coupon->set_usage_limit(0); + $coupon->set_amount($lpDiscountSum); + $coupon->set_email_restrictions($woocommerce->customer->get_email()); + $coupon->set_code('pl' . mt_rand()); + $coupon->save(); + + echo '
' . 'Your coupon: ' . $coupon->get_code() . '
'; + } catch (Throwable $exception) { + writeBaseLogs($exception->getMessage()); + } + } + + public function set_cart_loyalty() + { + global $woocommerce; + + try { + //$woocommerce->cart; + + foreach ($woocommerce->cart->get_coupons() as $code => $coupon) { + if (strpos($code, 'pl') !== false) { //заменить на регулярное выражение ^lp\d+$ + $woocommerce->cart->remove_coupon($code); + } + } + + return; + } catch (Throwable $exception) { + writeBaseLogs($exception->getMessage()); + } + } + /** * In this method we include CSS file * diff --git a/src/include/class-wc-retailcrm-loyalty.php b/src/include/class-wc-retailcrm-loyalty.php index 936ec3d..fef0e52 100644 --- a/src/include/class-wc-retailcrm-loyalty.php +++ b/src/include/class-wc-retailcrm-loyalty.php @@ -116,6 +116,45 @@ if (!class_exists('WC_Retailcrm_Loyalty')) : return false; } } + + public function getDiscountLp($cartItems, $site, $customerId) + { + $order = [ + 'site' => $site, + 'customer' => ['externalId' => $customerId], + 'privilegeType' => 'loyalty_level' + ]; + + $useXmlId = isset($this->settings['bind_by_sku']) && $this->settings['bind_by_sku'] === WC_Retailcrm_Base::YES; + + foreach ($cartItems as $item) { + $product = $item['data']; + + $order['items'][] = [ + 'offer' => $useXmlId ? ['xmlId' => $product->get_sku()] : ['externalId' => $product->get_id()], + 'quantity' => $item['quantity'], + 'initialPrice' => wc_get_price_including_tax($product) + ]; + } + + $response = $this->apiClient->calculateDiscountLoyalty($site, $order); + + if (!$response->isSuccessful() || !isset($response['calculations'])) { + return 0; + } + + $discount = 0; + + foreach ($response['calculations'] as $calculate) { + if ($calculate['privilegeType'] !== 'loyalty_level') { + continue; + } + + $discount = $calculate['discount'] !== 0 ? $calculate['discount'] : $calculate['maxChargeBonuses']; + } + + return $discount; + } } endif; diff --git a/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php index 6c46155..6c512b0 100644 --- a/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php +++ b/src/include/validators/loyalty-validator/class-wc-retailcrm-loyalty-validator.php @@ -56,7 +56,7 @@ if (!class_exists('WC_Retailcrm_Loyalty_Validator')) : $customer = new WC_Customer($userId); - if ($this->isActiveCorp && !empty($customer->get_shipping_company())) { + if ($this->isActiveCorp === 'yes' && !empty($customer->get_shipping_company())) { throw new ValidatorException($this->isCorporateUser, 400); }