diff --git a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php index 73d632df..1586804b 100644 --- a/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php +++ b/app/Extensions/PaymentGateways/PayPal/PayPalExtension.php @@ -11,6 +11,7 @@ use App\Models\Payment; use App\Models\ShopProduct; use App\Models\User; use App\Models\Coupon; +use App\Traits\Coupon as CouponTrait; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Redirect; @@ -28,6 +29,8 @@ use PayPalHttp\HttpException; */ class PayPalExtension extends AbstractExtension { + use CouponTrait; + public static function getConfig(): array { return [ @@ -36,23 +39,27 @@ class PayPalExtension extends AbstractExtension ]; } - static function PaypalPay(Request $request): void + public function PaypalPay(Request $request): void { /** @var User $user */ $user = Auth::user(); $shopProduct = ShopProduct::findOrFail($request->shopProduct); $discount = PartnerDiscount::getDiscount(); - $discountPrice = $request->get('discountPrice'); + $couponCode = $request->input('couponCode'); + $isValidCoupon = $this->validateCoupon($request->user(), $couponCode, $request->shopProduct); - dd($discountPrice); + if (is_string($shopProduct->price)) { + $shopProduct->price = floatval($shopProduct->price); + } + + $price = $shopProduct->price; + + if ($isValidCoupon->getStatusCode() == 200) { + $price = $this->calcDiscount($price, $isValidCoupon->getData()); + } // Partner Discount. - $price = $shopProduct->price - ($shopProduct->price * $discount / 100); - - // Coupon Discount. - // if ($discountPrice) { - // $price = $price - ($price * floatval($coupon_percentage) / 100); - // } + $price = $price - ($price * $discount / 100); // create a new payment $payment = Payment::create([ @@ -78,17 +85,15 @@ class PayPalExtension extends AbstractExtension [ "reference_id" => uniqid(), "description" => $shopProduct->display . ($discount ? (" (" . __('Discount') . " " . $discount . '%)') : ""), - "amount" => [ - "value" => $shopProduct->getTotalPrice(), + "amount" => [ + "value" => $shopProduct->getTotalPrice(), 'currency_code' => strtoupper($shopProduct->currency_code), 'breakdown' => [ - 'item_total' => - [ + 'item_total' => [ 'currency_code' => strtoupper($shopProduct->currency_code), 'value' => number_format($price, 2), ], - 'tax_total' => - [ + 'tax_total' => [ 'currency_code' => strtoupper($shopProduct->currency_code), 'value' => $shopProduct->getTaxValue(), ] @@ -98,7 +103,7 @@ class PayPalExtension extends AbstractExtension ], "application_context" => [ "cancel_url" => route('payment.Cancel'), - "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $coupon_code]), + "return_url" => route('payment.PayPalSuccess', ['payment' => $payment->id, 'couponCode' => $couponCode]), 'brand_name' => config('app.name', 'CtrlPanel.GG'), 'shipping_preference' => 'NO_SHIPPING' ] @@ -138,7 +143,7 @@ class PayPalExtension extends AbstractExtension $payment = Payment::findOrFail($laravelRequest->payment); $shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id); - $coupon_code = $laravelRequest->input('couponCode'); + $coupon_code = $laravelRequest->input('couponCode'); $request = new OrdersCaptureRequest($laravelRequest->input('token')); $request->prefer('return=representation'); @@ -153,11 +158,11 @@ class PayPalExtension extends AbstractExtension 'payment_id' => $response->result->id, ]); - // increase the use of the coupon when the payment is confirmed. - if ($coupon_code) { - $coupon = new Coupon; - $coupon->incrementUses($coupon_code); - } + // increase the use of the coupon when the payment is confirmed. + if ($coupon_code) { + $coupon = new Coupon; + $coupon->incrementUses($coupon_code); + } event(new UserUpdateCreditsEvent($user)); event(new PaymentEvent($user, $payment, $shopProduct)); diff --git a/app/Extensions/PaymentGateways/PayPal/web_routes.php b/app/Extensions/PaymentGateways/PayPal/web_routes.php index 95ef6ef2..17d1ed02 100644 --- a/app/Extensions/PaymentGateways/PayPal/web_routes.php +++ b/app/Extensions/PaymentGateways/PayPal/web_routes.php @@ -4,8 +4,8 @@ use Illuminate\Support\Facades\Route; use App\Extensions\PaymentGateways\PayPal\PayPalExtension; Route::middleware(['web', 'auth'])->group(function () { - Route::get('payment/PayPalPay/{shopProduct}', function () { - PayPalExtension::PaypalPay(request()); + Route::get('payment/PayPalPay/{shopProduct}', function (PayPalExtension $payPalExtension) { + $payPalExtension->PaypalPay(request()); })->name('payment.PayPalPay'); Route::get( diff --git a/app/Http/Controllers/Admin/CouponController.php b/app/Http/Controllers/Admin/CouponController.php index 44c3d618..396e2936 100644 --- a/app/Http/Controllers/Admin/CouponController.php +++ b/app/Http/Controllers/Admin/CouponController.php @@ -154,6 +154,6 @@ class CouponController extends Controller public function redeem(Request $request) { - return $this->validateCoupon($request); + return $this->validateCoupon($request->user(), $request->input('couponCode'), $request->input('productId')); } } diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php index 7c85d44e..5ab740d9 100644 --- a/app/Http/Controllers/Admin/PaymentController.php +++ b/app/Http/Controllers/Admin/PaymentController.php @@ -130,7 +130,6 @@ class PaymentController extends Controller { $product = ShopProduct::find($request->product_id); $paymentGateway = $request->payment_method; - $coupon_data = null; $coupon_code = $request->coupon_code; // on free products, we don't need to use a payment gateway @@ -140,18 +139,9 @@ class PaymentController extends Controller } if ($coupon_code) { - $isValidCoupon = $this->validateCoupon($request); - - if ($isValidCoupon->getStatusCode() == 200) { - $coupon_data = $isValidCoupon; - $discountPrice = $this->calcDiscount($product, $isValidCoupon->getData()); - } - } - - if ($coupon_data) { return redirect()->route('payment.' . $paymentGateway . 'Pay', [ 'shopProduct' => $product->id, - 'discountPrice' => $discountPrice + 'couponCode' => $coupon_code ]); } @@ -166,11 +156,6 @@ class PaymentController extends Controller return redirect()->route('store.index')->with('info', 'Payment was Canceled'); } - protected function getCouponDiscount(float $productPrice, string $discount) - { - return $productPrice - ($productPrice * $discount / 100); - } - /** * @return JsonResponse|mixed * diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php index 9b849751..d7f0efb3 100644 --- a/app/Models/Coupon.php +++ b/app/Models/Coupon.php @@ -40,7 +40,7 @@ class Coupon extends Model return 'USES_LIMIT_REACHED'; } - if (! is_null($this->expires_at)) { + if (!is_null($this->expires_at)) { $expires_at = Carbon::createFromTimeString($this->expires_at)->timestamp; if ($expires_at <= Carbon::now()->timestamp) { @@ -59,9 +59,9 @@ class Coupon extends Model * * @return bool */ - public function isLimitsUsesReached($request, $coupon_settings): bool + public function isLimitsUsesReached($requestUser, $coupon_settings): bool { - $coupon_uses = $request->user()->coupons()->where('id', $this->id)->count(); + $coupon_uses = $requestUser->coupons()->where('id', $this->id)->count(); return $coupon_uses >= $coupon_settings->max_uses_per_user ? true : false; } diff --git a/app/Traits/Coupon.php b/app/Traits/Coupon.php index 319fd890..be4da4ad 100644 --- a/app/Traits/Coupon.php +++ b/app/Traits/Coupon.php @@ -11,9 +11,10 @@ use stdClass; trait Coupon { - public function validateCoupon(Request $request): JsonResponse + public function validateCoupon($requestUser, $couponCode, $productId): JsonResponse { - $coupon = CouponModel::where('code', $request->input('coupon_code'))->first(); + $coupon = CouponModel::where('code', $couponCode)->first(); + $shopProduct = ShopProduct::findOrFail($productId); $coupon_settings = new CouponSettings; $response = response()->json([ 'isValid' => false, @@ -21,6 +22,14 @@ trait Coupon ], 404); if (!is_null($coupon)) { + if (is_string($coupon->value)) { + $coupon->value = floatval($coupon->value); + } + + if (is_string($shopProduct->price)) { + $shopProduct->price = floatval($shopProduct->price); + } + if ($coupon->getStatus() == 'USES_LIMIT_REACHED') { $response = response()->json([ 'isValid' => false, @@ -39,7 +48,7 @@ trait Coupon return $response; } - if ($coupon->isLimitsUsesReached($request, $coupon_settings)) { + if ($coupon->isLimitsUsesReached($requestUser, $coupon_settings)) { $response = response()->json([ 'isValid' => false, 'error' => __('You have reached the maximum uses of this coupon.') @@ -48,6 +57,15 @@ trait Coupon return $response; } + if ($coupon->type === 'amount' && $coupon->value >= $shopProduct->price) { + $response = response()->json([ + 'isValid' => false, + 'error' => __('The coupon you are trying to use would give you 100% off, so it cannot be used for this product, sorry.') + ], 422); + + return $response; + } + $response = response()->json([ 'isValid' => true, 'couponCode' => $coupon->code, @@ -59,14 +77,12 @@ trait Coupon return $response; } - public function calcDiscount(ShopProduct $product, stdClass $data) + public function calcDiscount($productPrice, stdClass $data) { if ($data->isValid) { - $productPrice = $product->price; - if (is_string($productPrice)) { - $productPrice = floatval($product->price); + $productPrice = floatval($productPrice); } if ($data->couponType === 'percentage') { @@ -82,5 +98,7 @@ trait Coupon return $productPrice - $data->couponValue; } + + return $productPrice; } } diff --git a/database/migrations/2023_05_11_153719_create_coupons_table.php b/database/migrations/2023_05_11_153719_create_coupons_table.php index 48048f6a..db26a65b 100644 --- a/database/migrations/2023_05_11_153719_create_coupons_table.php +++ b/database/migrations/2023_05_11_153719_create_coupons_table.php @@ -17,10 +17,10 @@ return new class extends Migration $table->id(); $table->string('code')->unique(); $table->enum('type', ['percentage', 'amount']); - $table->integer('value'); + $table->decimal('value', 10); $table->integer('uses')->default(0); $table->integer('max_uses'); - $table->timestamp('expires_at'); + $table->timestamp('expires_at')->nullable(); $table->timestamps(); }); } diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php index 690e6c04..59ea53c1 100644 --- a/themes/default/views/store/checkout.blade.php +++ b/themes/default/views/store/checkout.blade.php @@ -185,6 +185,8 @@
{{ __('Coupon Discount') }} + +
@@ -199,8 +201,13 @@
{{ __('Total') }} + {{ $product->formatToCurrency($total) }} + id="total_price" + class="text-muted d-inline-block" + > + {{ $product->formatToCurrency($total) }} +