Browse Source

feat: ✨ Enhance coupon validation and application

IceToast 2 years ago
parent
commit
fc84e7d1db
3 changed files with 55 additions and 25 deletions
  1. 2 18
      app/Listeners/CouponUsed.php
  2. 7 5
      app/Models/Coupon.php
  3. 46 2
      app/Traits/Coupon.php

+ 2 - 18
app/Listeners/CouponUsed.php

@@ -30,11 +30,6 @@ class CouponUsed
      */
     public function handle(CouponUsedEvent $event)
     {
-        // Always check the authenticity of the coupon.
-        if (!$this->isValidCoupon($event)) {
-            return;
-        }
-
         // Automatically increments the coupon usage.
         $this->incrementUses($event);
 
@@ -60,18 +55,7 @@ class CouponUsed
      */
     private function incrementUses(CouponUsedEvent $event)
     {
-        $event->coupon->where('code', $event->coupon->code)->increment('uses');
-    }
-
-    /**
-     * It checks that the coupon received from the request really exists.
-     *
-     * @param \App\Events\CouponUsedEvent  $event
-     *
-     * @return bool
-     */
-    private function isValidCoupon(CouponUsedEvent $event): bool
-    {
-        return $event->coupon->code === $event->couponCode ? true : false;
+        $event->coupon->increment('uses');
+        $event->coupon->save();
     }
 }

+ 7 - 5
app/Models/Coupon.php

@@ -2,11 +2,13 @@
 
 namespace App\Models;
 
+use App\Settings\CouponSettings;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Spatie\Activitylog\LogOptions;
 use Spatie\Activitylog\Traits\LogsActivity;
 use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
 class Coupon extends Model
 {
@@ -75,16 +77,16 @@ class Coupon extends Model
     /**
      * Check if a user has already exceeded the uses of a coupon.
      *
-     * @param Request $request The request being made.
-     * @param CouponSettings $coupon_settings The instance of the coupon settings.
+     * @param User $user The request being made.
      *
      * @return bool
      */
-    public function isLimitsUsesReached($requestUser, $coupon_settings): bool
+    public function isMaxUsesReached($user): bool
     {
-        $coupon_uses = $requestUser->coupons()->where('id', $this->id)->count();
+        $coupon_settings = new CouponSettings;
+        $coupon_uses = $user->coupons()->where('id', $this->id)->count();
 
-        return $coupon_uses >= $coupon_settings->max_uses_per_user ? true : false;
+        return $coupon_uses >= $coupon_settings->max_uses_per_user;
     }
 
     /**

+ 46 - 2
app/Traits/Coupon.php

@@ -5,7 +5,7 @@ namespace App\Traits;
 use App\Settings\CouponSettings;
 use App\Models\Coupon as CouponModel;
 use App\Models\ShopProduct;
-use Illuminate\Http\Request;
+use App\Models\User;
 use Illuminate\Http\JsonResponse;
 use stdClass;
 
@@ -40,7 +40,7 @@ trait Coupon
                 return $response;
             }
 
-            if ($coupon->isLimitsUsesReached($requestUser, $coupon_settings)) {
+            if ($coupon->isMaxUsesReached($requestUser, $coupon_settings)) {
                 $response = response()->json([
                     'isValid' => false,
                     'error' => __('You have reached the maximum uses of this coupon.')
@@ -69,6 +69,32 @@ trait Coupon
         return $response;
     }
 
+    public function isCouponValid(string $couponCode, User $user, string $productId): bool
+    {
+        if (is_null($couponCode)) return false;
+
+        $coupon = CouponModel::where('code', $couponCode)->first();
+        $shopProduct = ShopProduct::findOrFail($productId);
+
+        if ($coupon->getStatus() == 'USES_LIMIT_REACHED') {
+            return false;
+        }
+
+        if ($coupon->getStatus() == 'EXPIRED') {
+            return false;
+        }
+
+        if ($coupon->isMaxUsesReached($user)) {
+            return false;
+        }
+
+        if ($coupon->type === 'amount' && $coupon->value >= $shopProduct->price) {
+            return false;
+        }
+
+        return true;
+    }
+
     public function calcDiscount($productPrice, stdClass $data)
     {
 
@@ -89,4 +115,22 @@ trait Coupon
 
         return $productPrice;
     }
+
+    public function applyCoupon(string $couponCode, float $price)
+    {
+        $coupon = CouponModel::where('code', $couponCode)->first();
+
+        if ($coupon->type === 'percentage') {
+            return $price - ($price * $coupon->value / 100);
+        }
+
+        if ($coupon->type === 'amount') {
+            // There is no discount if the value of the coupon is greater than or equal to the value of the product.
+            if ($coupon->value >= $price) {
+                return $price;
+            }
+        }
+
+        return $price - $coupon->value;
+    }
 }