diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php
index 4a28a22..7ab9377 100644
--- a/src/include/class-wc-retailcrm-base.php
+++ b/src/include/class-wc-retailcrm-base.php
@@ -114,11 +114,12 @@ if (!class_exists('WC_Retailcrm_Base')) {
// Add coupon hooks for loyalty program
add_action('woocommerce_cart_coupon', [$this, 'coupon_info'], 11, 1);
//Remove coupons when cart changes
- add_action('woocommerce_add_to_cart', [$this, 'delete_loyalty_coupon'], 11, 1);
- add_action('woocommerce_after_cart_item_quantity_update', [$this, 'delete_loyalty_coupon'], 11, 1);
- add_action('woocommerce_cart_item_removed', [$this, 'delete_loyalty_coupon'], 11, 1);
+ add_action('woocommerce_add_to_cart', [$this, 'refresh_loyalty_coupon'], 11, 1);
+ add_action('woocommerce_after_cart_item_quantity_update', [$this, 'refresh_loyalty_coupon'], 11, 1);
+ add_action('woocommerce_cart_item_removed', [$this, 'refresh_loyalty_coupon'], 11, 1);
add_action('woocommerce_before_cart_empted', [$this, 'delete_loyalty_coupon'], 11, 1);
- add_action('woocommerce_removed_coupon', [$this, 'removed_loyalty_coupon'], 11, 1);
+ add_action('woocommerce_removed_coupon', [$this, 'removed_coupon'], 11, 1);
+ add_action('woocommerce_applied_coupon', [$this, 'applied_coupon'], 11, 1);
}
// Subscribed hooks
@@ -691,86 +692,21 @@ if (!class_exists('WC_Retailcrm_Base')) {
public function coupon_info()
{
- global $woocommerce;
-
try {
- $site = $this->apiClient->getSingleSiteForKey();
- $cartItems = $woocommerce->cart->get_cart();
- $customerId = $woocommerce->customer->get_id();
+ $result = $this->loyalty->createLoyaltyCoupon();
- $resultString = '';
-
- if (!$customerId || !$cartItems) {
- return;
+ if ($result) {
+ echo $result;
}
+ } catch (Throwable $exception) {
+ writeBaseLogs($exception->getMessage());
+ }
+ }
- $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;
- }
-
- $couponsLp = [];
- // Check exists used loyalty coupons
- foreach ($woocommerce->cart->get_coupons() as $code => $coupon) {
- if (preg_match('/^pl\d+$/m', $code) === 1) {
- $couponsLp[] = $code;
- }
- }
-
- //If one loyalty coupon is used, not generate a new one
- // if more than 1 loyalty coupon is used, delete all coupons
- if (count($couponsLp) === 1) {
- return;
- }
-
- if (count($couponsLp) > 1) {
- foreach ($couponsLp as $code) {
- $woocommerce->cart->remove_coupon($code);
-
- $coupon = new WC_Coupon($code);
-
- $coupon->delete(true);
- }
- }
-
- //Check the existence of loyalty coupons and delete them
- $coupons = $this->loyalty->getCouponLoyalty($woocommerce->customer->get_email());
- $loyaltyInfo = $this->loyalty->getLoyaltyAccounts($customerId);
-
- if (!isset($loyaltyInfo['loyaltyAccounts'][0])) {
- return;
- }
-
- if ($loyaltyInfo['loyaltyAccounts'][0]['level']['type'] === 'discount') {
- $resultString .= '
' . 'Предоставляется скидка в ' . $lpDiscountSum . $loyaltyInfo['loyaltyAccounts'][0]['loyalty']['currency'] . '
';
- } else {
- $resultString .= '' . 'Возможно списать ' . $lpDiscountSum . ' бонусов' . '
';
- }
-
- foreach ($coupons as $item) {
- $coupon = new WC_Coupon($item['code']);
-
- $coupon->delete(true);
- }
-
- //Generate new coupon
- $coupon = new WC_Coupon();
-
- //$coupon->set_individual_use(true); // запрещает использование других купонов одноврeменно с этим
- $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 $resultString . '' . 'Your coupon: ' . $coupon->get_code() . '
';
+ public function refresh_loyalty_coupon()
+ {
+ try {
+ $this->loyalty->createLoyaltyCoupon(true);
} catch (Throwable $exception) {
writeBaseLogs($exception->getMessage());
}
@@ -778,30 +714,33 @@ if (!class_exists('WC_Retailcrm_Base')) {
public function delete_loyalty_coupon()
{
- global $woocommerce;
-
try {
- foreach ($woocommerce->cart->get_coupons() as $code => $coupon) {
- if (preg_match('/^pl\d+$/m', $code) === 1) {
- $woocommerce->cart->remove_coupon($code);
-
- $coupon = new WC_Coupon($code);
-
- $coupon->delete(true);
- }
- }
+ $this->loyalty->deleteAppliedLoyaltyCoupon();
} catch (Throwable $exception) {
writeBaseLogs($exception->getMessage());
}
}
- public function removed_loyalty_coupon($couponCode)
+ public function removed_coupon($couponCode)
{
try {
if (preg_match('/^pl\d+$/m', $couponCode) === 1) {
$coupon = new WC_Coupon($couponCode);
$coupon->delete(true);
+ } else {
+ $this->loyalty->createLoyaltyCoupon(true);
+ }
+ } catch (Throwable $exception) {
+ writeBaseLogs($exception->getMessage());
+ }
+ }
+
+ public function applied_coupon($couponCode)
+ {
+ try {
+ if (preg_match('/^pl\d+$/m', $couponCode) !== 1) {
+ $this->loyalty->createLoyaltyCoupon(true);
}
} catch (Throwable $exception) {
writeBaseLogs($exception->getMessage());
diff --git a/src/include/class-wc-retailcrm-loyalty.php b/src/include/class-wc-retailcrm-loyalty.php
index 2fa93e4..0132728 100644
--- a/src/include/class-wc-retailcrm-loyalty.php
+++ b/src/include/class-wc-retailcrm-loyalty.php
@@ -105,7 +105,7 @@ if (!class_exists('WC_Retailcrm_Loyalty')) :
}
}
- public function getDiscountLp($cartItems, $site, $customerId)
+ private function getDiscountLp($cartItems, $site, $customerId)
{
$order = [
'site' => $site,
@@ -121,7 +121,8 @@ if (!class_exists('WC_Retailcrm_Loyalty')) :
$order['items'][] = [
'offer' => $useXmlId ? ['xmlId' => $product->get_sku()] : ['externalId' => $product->get_id()],
'quantity' => $item['quantity'],
- 'initialPrice' => wc_get_price_including_tax($product)
+ 'initialPrice' => wc_get_price_including_tax($product),
+ 'discountManualAmount' => ($item['line_subtotal'] - $item['line_total']) / $item['quantity']
];
}
@@ -138,13 +139,13 @@ if (!class_exists('WC_Retailcrm_Loyalty')) :
continue;
}
- $discount = $calculate['discount'] !== 0 ? $calculate['discount'] : $calculate['maxChargeBonuses'];
+ $discount = /*$calculate['discount'] !== 0 ? $calculate['discount'] :*/ $calculate['maxChargeBonuses'];
}
return $discount;
}
- public function getLoyaltyAccounts(int $userId)
+ private function getLoyaltyAccounts(int $userId)
{
$response = $this->apiClient->customersGet($userId);
@@ -163,6 +164,116 @@ if (!class_exists('WC_Retailcrm_Loyalty')) :
return $response;
}
+ public function createLoyaltyCoupon($refreshCoupon = false)
+ {
+ global $woocommerce;
+
+ $site = $this->apiClient->getSingleSiteForKey();
+ $cartItems = $woocommerce->cart->get_cart();
+ $customerId = $woocommerce->customer ? $woocommerce->customer->get_id() : null;
+
+ $resultString = '';
+
+ if (!$customerId || !$cartItems) {
+ return null;
+ }
+
+ $couponsLp = [];
+ // Check exists used loyalty coupons
+ foreach ($woocommerce->cart->get_coupons() as $code => $coupon) {
+ if (preg_match('/^pl\d+$/m', $code) === 1) {
+ $couponsLp[] = $code;
+ }
+ }
+
+ // if you need to refresh coupon that does not exist
+ if (count($couponsLp) === 0 && $refreshCoupon) {
+ return null;
+ }
+
+ //If one loyalty coupon is used, not generate a new one
+ if (count($couponsLp) === 1 && !$refreshCoupon) {
+ return null;
+ }
+
+ // if more than 1 loyalty coupon is used, delete all coupons
+ if (count($couponsLp) > 1 || $refreshCoupon) {
+ foreach ($couponsLp as $code) {
+ $woocommerce->cart->remove_coupon($code);
+
+ $coupon = new WC_Coupon($code);
+
+ $coupon->delete(true);
+ }
+ }
+
+ $validator = new WC_Retailcrm_Loyalty_Validator($this->apiClient, $this->settings['corporate_enabled'] ?? WC_Retailcrm_Base::NO);
+
+ if (!$validator->checkAccount($customerId)) {
+ return null;
+ }
+
+ $lpDiscountSum = $this->getDiscountLp($woocommerce->cart->get_cart(), $site, $customerId);
+
+ if ($lpDiscountSum === 0) {
+ return null;
+ }
+
+ //Check the existence of loyalty coupons and delete them
+ $coupons = $this->getCouponLoyalty($woocommerce->customer->get_email());
+
+ foreach ($coupons as $item) {
+ $coupon = new WC_Coupon($item['code']);
+
+ $coupon->delete(true);
+ }
+
+ //Generate new coupon
+ $coupon = new WC_Coupon();
+
+ //$coupon->set_individual_use(true); // запрещает использование других купонов одноврeменно с этим
+ $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();
+
+ if ($refreshCoupon) {
+ $woocommerce->cart->apply_coupon($coupon->get_code());
+
+ return $resultString;
+ }
+
+ $loyaltyInfo = $this->getLoyaltyAccounts($customerId);
+
+ if (!isset($loyaltyInfo['loyaltyAccounts'][0])) {
+ return null;
+ }
+
+ if ($loyaltyInfo['loyaltyAccounts'][0]['level']['type'] === 'discount') {
+ $resultString .= '' . 'Предоставляется скидка в ' . $lpDiscountSum . $loyaltyInfo['loyaltyAccounts'][0]['loyalty']['currency'] . '
';
+ } else {
+ $resultString .= '' . 'Возможно списать ' . $lpDiscountSum . ' бонусов' . '
';
+ }
+
+ return $resultString . '' . 'Your coupon: ' . $coupon->get_code() . '
';
+ }
+
+ public function deleteAppliedLoyaltyCoupon()
+ {
+ global $woocommerce;
+
+ foreach ($woocommerce->cart->get_coupons() as $code => $coupon) {
+ if (preg_match('/^pl\d+$/m', $code) === 1) {
+ $woocommerce->cart->remove_coupon($code);
+
+ $coupon = new WC_Coupon($code);
+
+ $coupon->delete(true);
+ }
+ }
+ }
+
public function getCouponLoyalty($email)
{
global $wpdb;
diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php
index 6d657aa..516ad4c 100644
--- a/src/include/class-wc-retailcrm-orders.php
+++ b/src/include/class-wc-retailcrm-orders.php
@@ -87,28 +87,32 @@ if (!class_exists('WC_Retailcrm_Orders')) :
$this->order_payment->resetData();
$wcOrder = wc_get_order($orderId);
- $coupons = $wcOrder->get_coupons();
- $discountLp = 0;
+ $privilegeType = 'none';
- foreach ($coupons as $coupon) {
- $code = $coupon->get_code();
+ if (isset($this->retailcrm_settings['loyalty'])
+ && $this->retailcrm_settings['loyalty'] === WC_Retailcrm_Base::YES
+ ) {
+ $discountLp = $this->deleteLoyaltyCoupon($wcOrder);
+ $wcUser = $wcOrder->get_user();
- if (preg_match('/^pl\d+$/m', $code) !== 1) {
- continue;
+ if (
+ (
+ !$wcUser
+ || (
+ isset($this->retailcrm_settings['corporate_enabled'])
+ && $this->retailcrm_settings['corporate_enabled'] === WC_Retailcrm_Base::YES
+ && !empty($wcUser->get_shipping_company())
+ )
+ ) && $discountLp > 0
+ ) {
+ wp_die();
}
- $discountLp = $coupon->get_discount();
- $wcOrder->remove_coupon($code);
- $objectCoupon = new WC_Coupon($code);
- $objectCoupon->delete(true);
-
- break;
+ $privilegeType = 'loyalty_level';
}
- $wcOrder->recalculate_coupons();
-
$this->processOrder($wcOrder);
- $this->order['privilegeType'] = 'loyalty_level';
+ $this->order['privilegeType'] = $privilegeType;
$response = $this->retailcrm->ordersCreate($this->order);
@@ -119,36 +123,9 @@ if (!class_exists('WC_Retailcrm_Orders')) :
return $response->getErrorString();
}
- $response = $this->retailcrm->applyBonusToOrder('woo', ['externalId' => $this->order['externalId']], (float) $discountLp);
-
- if (!$response instanceof WC_Retailcrm_Response || !$response->isSuccessful()) {
- return $response->getErrorString();
+ if (isset($discountLp) && $discountLp > 0) {
+ $this->applyLoyaltyDiscount($wcOrder, $discountLp);
}
-
- $wcItems = $wcOrder->get_items();
-
- foreach ($response['order']['items'] as $item) {
- $externalId = $item['externalIds'][0]['value'];
- $externalId = preg_replace('/^\d+\_/m', '', $externalId);
-
- if (isset($wcItems[(int) $externalId])) {
-
- $discountLoyaltyTotal = 0;
-
- foreach ($item['discounts'] as $discount) {
- if ($discount['type'] === 'bonus_charge') {
- $discountLoyaltyTotal += $discount['amount'];
- }
- }
-
- $wcItem = $wcItems[(int) $externalId];
- $wcItem->set_total($wcItem->get_total() - $discountLoyaltyTotal);
- $wcItem->calculate_taxes();
- $wcItem->save();
- }
- }
-
- $wcOrder->calculate_totals();
} catch (Throwable $exception) {
writeBaseLogs(
sprintf(
@@ -689,5 +666,63 @@ if (!class_exists('WC_Retailcrm_Orders')) :
return $customerWasChanged;
}
+
+ private function deleteLoyaltyCoupon(&$wcOrder)
+ {
+ $discountLp = 0;
+ $coupons = $wcOrder->get_coupons();
+
+ foreach ($coupons as $coupon) {
+ $code = $coupon->get_code();
+
+ if (preg_match('/^pl\d+$/m', $code) !== 1) {
+ continue;
+ }
+
+ $discountLp = $coupon->get_discount();
+ $wcOrder->remove_coupon($code);
+ $objectCoupon = new WC_Coupon($code);
+ $objectCoupon->delete(true);
+
+ $wcOrder->recalculate_coupons();
+ break;
+ }
+
+ return $discountLp;
+ }
+
+ private function applyLoyaltyDiscount(&$wcOrder, $discountLp)
+ {
+ $response = $this->retailcrm->applyBonusToOrder('woo', ['externalId' => $this->order['externalId']], (float) $discountLp);
+
+ if (!$response instanceof WC_Retailcrm_Response || !$response->isSuccessful()) {
+ return $response->getErrorString();
+ }
+
+ $wcItems = $wcOrder->get_items();
+
+ foreach ($response['order']['items'] as $item) {
+ $externalId = $item['externalIds'][0]['value'];
+ $externalId = preg_replace('/^\d+\_/m', '', $externalId);
+
+ if (isset($wcItems[(int) $externalId])) {
+
+ $discountLoyaltyTotal = 0;
+
+ foreach ($item['discounts'] as $discount) {
+ if ($discount['type'] === 'bonus_charge') {
+ $discountLoyaltyTotal += $discount['amount'];
+ }
+ }
+
+ $wcItem = $wcItems[(int) $externalId];
+ $wcItem->set_total($wcItem->get_total() - $discountLoyaltyTotal);
+ $wcItem->calculate_taxes();
+ $wcItem->save();
+ }
+ }
+
+ $wcOrder->calculate_totals();
+ }
}
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 6c512b0..a65d608 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 === 'yes' && !empty($customer->get_shipping_company())) {
+ if ($this->isActiveCorp === WC_Retailcrm_Base::YES && !empty($customer->get_shipping_company())) {
throw new ValidatorException($this->isCorporateUser, 400);
}