| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- <?php
- namespace Longyi\RewardPoints\Services;
- use Longyi\RewardPoints\Repositories\RewardPointRepository;
- use Longyi\RewardPoints\Models\RewardPointCustomer;
- use Webkul\Checkout\Facades\Cart;
- use Webkul\Customer\Facades\Customer;
- class CartRewardPoints
- {
- /**
- * Session key for points used in cart
- */
- const POINTS_USED_KEY = 'reward_points_used';
-
- /**
- * @var RewardPointRepository
- */
- protected $rewardPointRepository;
-
- /**
- * CartRewardPoints constructor.
- */
- public function __construct()
- {
- $this->rewardPointRepository = app(RewardPointRepository::class);
- }
-
- /**
- * Get available points for current customer
- */
- public function getAvailablePoints()
- {
- if (!Customer::check()) {
- return 0;
- }
-
- return $this->rewardPointRepository->getCustomerPoints(Customer::getCustomerId());
- }
-
- /**
- * Get points used in current cart
- */
- public function getPointsUsed()
- {
- if (!session()->has(self::POINTS_USED_KEY)) {
- return 0;
- }
-
- return session()->get(self::POINTS_USED_KEY);
- }
-
- /**
- * Get discount amount from points
- */
- public function getDiscountAmount($points = null)
- {
- $pointsUsed = $points ?: $this->getPointsUsed();
-
- if ($pointsUsed <= 0) {
- return 0;
- }
-
- $pointValue = config('rewardpoints.general.point_value', 0.01);
-
- return $pointsUsed * $pointValue;
- }
-
- /**
- * Apply points to cart
- */
- public function applyPoints($points)
- {
- $cart = Cart::getCart();
-
- if (!$cart) {
- return false;
- }
-
- $availablePoints = $this->getAvailablePoints();
-
- if ($points <= 0) {
- $this->removePoints();
- return false;
- }
-
- if ($points > $availablePoints) {
- return false;
- }
-
- // Calculate maximum points that can be used based on cart total
- $maxPointsByAmount = $this->getMaxPointsByCartTotal();
-
- if ($points > $maxPointsByAmount) {
- return false;
- }
-
- // Save points to session
- session()->put(self::POINTS_USED_KEY, $points);
-
- // Recalculate cart
- Cart::collectTotals();
-
- return true;
- }
-
- /**
- * Remove points from cart
- */
- public function removePoints()
- {
- session()->forget(self::POINTS_USED_KEY);
- Cart::collectTotals();
-
- return true;
- }
-
- /**
- * Calculate discount based on points
- */
- public function calculateDiscount()
- {
- $pointsUsed = $this->getPointsUsed();
-
- if ($pointsUsed <= 0) {
- return 0;
- }
-
- $discountAmount = $this->getDiscountAmount($pointsUsed);
-
- return $discountAmount;
- }
-
- /**
- * Get maximum points that can be used based on cart total
- */
- protected function getMaxPointsByCartTotal()
- {
- $cart = Cart::getCart();
-
- if (!$cart) {
- return 0;
- }
-
- $cartTotal = $cart->grand_total;
-
- // Get maximum discount percentage (default: 100%)
- $maxDiscountPercentage = core()->getConfigData('rewardpoints.general.max_discount_percentage', 100);
-
- // Calculate maximum discount amount
- $maxDiscountAmount = ($cartTotal * $maxDiscountPercentage) / 100;
-
- // Convert discount amount to points
- $pointValue = core()->getConfigData('rewardpoints.general.point_value', 0.01);
- $maxPoints = $pointValue > 0 ? floor($maxDiscountAmount / $pointValue) : 0;
-
- return $maxPoints;
- }
-
- /**
- * Get discount details for cart
- */
- public function getDiscountDetails()
- {
- $pointsUsed = $this->getPointsUsed();
-
- if ($pointsUsed <= 0) {
- return null;
- }
-
- $discountAmount = $this->getDiscountAmount();
-
- return [
- 'points_used' => $pointsUsed,
- 'discount_amount' => $discountAmount,
- 'formatted_discount' => core()->formatPrice($discountAmount),
- 'available_points' => $this->getAvailablePoints(),
- 'points_remaining' => $this->getAvailablePoints() - $pointsUsed
- ];
- }
-
- /**
- * Process order points
- */
- public function processOrderPoints($order)
- {
- $pointsUsed = $this->getPointsUsed();
-
- if ($pointsUsed <= 0) {
- return false;
- }
-
- $customerId = $order->customer_id;
-
- if (!$customerId) {
- return false;
- }
-
- // Deduct points from customer
- $discountAmount = $this->getDiscountAmount($pointsUsed);
-
- $result = $this->rewardPointRepository->deductPoints(
- $customerId,
- $pointsUsed,
- 0,
- "Points redeemed for order #{$order->increment_id} (Discount: " . core()->formatPrice($discountAmount) . ")",
- $order->id
- );
-
- // Clear session
- $this->removePoints();
-
- return $result;
- }
-
- /**
- * Get points value in currency
- */
- public function getPointsValue($points)
- {
- $pointValue = core()->getConfigData('rewardpoints.general.point_value', 0.01);
- return $points * $pointValue;
- }
-
- /**
- * Get currency value in points
- */
- public function getPointsFromValue($value)
- {
- $pointValue = core()->getConfigData('rewardpoints.general.point_value', 0.01);
- return $pointValue > 0 ? floor($value / $pointValue) : 0;
- }
-
- /**
- * Validate if points can be applied to cart
- */
- public function validatePoints($points)
- {
- $cart = Cart::getCart();
-
- if (!$cart) {
- return 'Cart not found';
- }
-
- $availablePoints = $this->getAvailablePoints();
-
- if ($points <= 0) {
- return 'Points must be greater than 0';
- }
-
- if ($points > $availablePoints) {
- return "You only have {$availablePoints} points available";
- }
-
- $maxPoints = $this->getMaxPointsByCartTotal();
-
- if ($points > $maxPoints) {
- return "Maximum {$maxPoints} points can be used for this order";
- }
-
- return true;
- }
- }
|