feat: Enhance coupon validation and application

This commit is contained in:
IceToast 2023-05-26 16:30:55 +02:00 committed by IceToast
parent c05b4d8820
commit fc84e7d1db
3 changed files with 55 additions and 25 deletions

View file

@ -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();
}
}

View file

@ -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;
}
/**

View file

@ -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;
}
}