Some improvements, and some not so much...
This commit is contained in:
parent
72f3decd3f
commit
8f7ad95506
8 changed files with 92 additions and 58 deletions
|
@ -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));
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -185,6 +185,8 @@
|
|||
<div id="coupon_discount_details" class="d-flex justify-content-between" style="display: none !important;">
|
||||
<span class="text-muted d-inline-block">
|
||||
{{ __('Coupon Discount') }}
|
||||
</span>
|
||||
<span id="coupon_discount_value" class="text-muted d-inline-block">
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
@ -199,8 +201,13 @@
|
|||
<hr class="text-white border-secondary">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="text-muted d-inline-block">{{ __('Total') }}</span>
|
||||
<input id="total_price_input" type="hidden" value="{{ $product->getTotalPrice() }}">
|
||||
<span
|
||||
class="text-muted d-inline-block">{{ $product->formatToCurrency($total) }}</span>
|
||||
id="total_price"
|
||||
class="text-muted d-inline-block"
|
||||
>
|
||||
{{ $product->formatToCurrency($total) }}
|
||||
</span>
|
||||
</div>
|
||||
<template x-if="payment_method">
|
||||
<div class="d-flex justify-content-between">
|
||||
|
@ -240,27 +247,46 @@
|
|||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
const productId = $("[name='product_id']").val()
|
||||
let hasCouponCodeValue = $('#coupon_code').val().trim() !== ''
|
||||
|
||||
$('#coupon_code').on('change', function(e) {
|
||||
hasCouponCodeValue = e.target.value !== ''
|
||||
})
|
||||
|
||||
function calcPriceWithCouponDiscount(couponValue, couponType) {
|
||||
let totalPrice = $('#total_price_input').val()
|
||||
|
||||
if (typeof totalPrice == 'string') {
|
||||
totalPrice = parseFloat(totalPrice)
|
||||
}
|
||||
|
||||
if (couponType === 'percentage') {
|
||||
totalPrice = totalPrice - (totalPrice * couponValue / 100)
|
||||
$('#coupon_discount_value').text("- " + couponValue + "%")
|
||||
} else if (couponType === 'amount') {
|
||||
totalPrice = totalPrice - couponValue
|
||||
$('#coupon_discount_value').text(totalPrice)
|
||||
}
|
||||
|
||||
$('#total_price').text(totalPrice)
|
||||
$('#total_price_input').val(totalPrice)
|
||||
}
|
||||
|
||||
function checkCoupon() {
|
||||
const couponCode = $('#coupon_code').val()
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('admin.coupon.redeem') }}",
|
||||
method: 'POST',
|
||||
data: { coupon_code: couponCode },
|
||||
data: { couponCode: couponCode, productId: productId },
|
||||
success: function(response) {
|
||||
if (response.isValid && response.couponCode) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
text: `The coupon '${response.couponCode}' was successfully inserted in your purchase.`,
|
||||
text: 'The coupon was successfully added to your purchase.',
|
||||
}).then(function(isConfirmed) {
|
||||
console.log('confirmou')
|
||||
|
||||
calcPriceWithCouponDiscount(response.couponValue, response.couponType)
|
||||
$('#submit_form_button').prop('disabled', false).removeClass('disabled')
|
||||
$('#send_coupon_code').prop('disabled', true)
|
||||
$('#coupon_discount_details').prop('disabled', false).show()
|
||||
|
|
Loading…
Reference in a new issue