[Refactor] Move referral_code generation to trait | [Fix] Allow free products handling (#670)

This commit is contained in:
Dennis 2023-01-30 22:48:42 +01:00 committed by GitHub
commit d7ca83ef97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 104 deletions

View file

@ -4,6 +4,7 @@ namespace App\Console\Commands;
use App\Classes\Pterodactyl; use App\Classes\Pterodactyl;
use App\Models\User; use App\Models\User;
use App\Traits\Referral;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
@ -11,6 +12,8 @@ use Illuminate\Support\Str;
class MakeUserCommand extends Command class MakeUserCommand extends Command
{ {
use Referral;
/** /**
* The name and signature of the console command. * The name and signature of the console command.
* *
@ -38,18 +41,6 @@ class MakeUserCommand extends Command
$this->pterodactyl = $pterodactyl; $this->pterodactyl = $pterodactyl;
} }
/**
* @param $userid
* @return string
*/
public function generateCode(){
$random = STR::random(8);
if (User::where('referral_code', '=', $random)->doesntExist()) {
return $random;
} else {
$this->generateCode();
}
}
/** /**
* Execute the console command. * Execute the console command.
@ -97,7 +88,7 @@ class MakeUserCommand extends Command
'email' => $response['email'], 'email' => $response['email'],
'role' => 'admin', 'role' => 'admin',
'password' => Hash::make($password), 'password' => Hash::make($password),
'referral_code' => $this->generateCode(), 'referral_code' => $this->createReferralCode(),
'pterodactyl_id' => $response['id'], 'pterodactyl_id' => $response['id'],
]); ]);

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Events\PaymentEvent;
use App\Events\UserUpdateCreditsEvent; use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\PartnerDiscount; use App\Models\PartnerDiscount;
@ -38,21 +39,29 @@ class PaymentController extends Controller
*/ */
public function checkOut(ShopProduct $shopProduct) public function checkOut(ShopProduct $shopProduct)
{ {
$extensions = ExtensionHelper::getAllExtensionsByNamespace('PaymentGateways'); $discount = PartnerDiscount::getDiscount();
$price = $shopProduct->price - ($shopProduct->price * $discount / 100);
// build a paymentgateways array that contains the routes for the payment gateways and the image path for the payment gateway which lays in public/images/Extensions/PaymentGateways with the extensionname in lowercase
$paymentGateways = []; $paymentGateways = [];
foreach ($extensions as $extension) { if ($price > 0) {
$extensionName = basename($extension); $extensions = ExtensionHelper::getAllExtensionsByNamespace('PaymentGateways');
if (!ExtensionHelper::getExtensionConfig($extensionName, 'enabled')) continue; // skip if not enabled
$payment = new \stdClass(); // build a paymentgateways array that contains the routes for the payment gateways and the image path for the payment gateway which lays in public/images/Extensions/PaymentGateways with the extensionname in lowercase
$payment->name = ExtensionHelper::getExtensionConfig($extensionName, 'name'); foreach ($extensions as $extension) {
$payment->image = asset('images/Extensions/PaymentGateways/' . strtolower($extensionName) . '_logo.png'); $extensionName = basename($extension);
$paymentGateways[] = $payment; if (!ExtensionHelper::getExtensionConfig($extensionName, 'enabled')) continue; // skip if not enabled
$payment = new \stdClass();
$payment->name = ExtensionHelper::getExtensionConfig($extensionName, 'name');
$payment->image = asset('images/Extensions/PaymentGateways/' . strtolower($extensionName) . '_logo.png');
$paymentGateways[] = $payment;
}
} }
$discount = PartnerDiscount::getDiscount();
return view('store.checkout')->with([ return view('store.checkout')->with([
'product' => $shopProduct, 'product' => $shopProduct,
@ -63,6 +72,7 @@ class PaymentController extends Controller
'taxpercent' => $shopProduct->getTaxPercent(), 'taxpercent' => $shopProduct->getTaxPercent(),
'total' => $shopProduct->getTotalPrice(), 'total' => $shopProduct->getTotalPrice(),
'paymentGateways' => $paymentGateways, 'paymentGateways' => $paymentGateways,
'productIsFree' => $price <= 0,
]); ]);
} }
@ -71,29 +81,12 @@ class PaymentController extends Controller
* @param ShopProduct $shopProduct * @param ShopProduct $shopProduct
* @return RedirectResponse * @return RedirectResponse
*/ */
public function FreePay(ShopProduct $shopProduct) public function handleFreeProduct(ShopProduct $shopProduct)
{ {
//check if the product is really free or the discount is 100%
if ($shopProduct->getTotalPrice() > 0) return redirect()->route('home')->with('error', __('An error ocured. Please try again.'));
//give product
/** @var User $user */ /** @var User $user */
$user = Auth::user(); $user = Auth::user();
//not updating server limit //create a payment
//update User with bought item
if ($shopProduct->type == "Credits") {
$user->increment('credits', $shopProduct->quantity);
} elseif ($shopProduct->type == "Server slots") {
$user->increment('server_limit', $shopProduct->quantity);
}
//skipped the referral commission, because the user did not pay anything.
//not giving client role
//store payment
$payment = Payment::create([ $payment = Payment::create([
'user_id' => $user->id, 'user_id' => $user->id,
'payment_id' => uniqid(), 'payment_id' => uniqid(),
@ -110,6 +103,7 @@ class PaymentController extends Controller
]); ]);
event(new UserUpdateCreditsEvent($user)); event(new UserUpdateCreditsEvent($user));
event(new PaymentEvent($user, $payment, $shopProduct));
//not sending an invoice //not sending an invoice
@ -122,6 +116,12 @@ class PaymentController extends Controller
$product = ShopProduct::find($request->product_id); $product = ShopProduct::find($request->product_id);
$paymentGateway = $request->payment_method; $paymentGateway = $request->payment_method;
// on free products, we don't need to use a payment gateway
$realPrice = $product->price - ($product->price * PartnerDiscount::getDiscount() / 100);
if ($realPrice <= 0) {
return $this->handleFreeProduct($product);
}
return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]); return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]);
} }

View file

@ -8,6 +8,7 @@ use App\Http\Controllers\Controller;
use App\Models\DiscordUser; use App\Models\DiscordUser;
use App\Models\User; use App\Models\User;
use App\Notifications\ReferralNotification; use App\Notifications\ReferralNotification;
use App\Traits\Referral;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@ -27,6 +28,8 @@ use Spatie\QueryBuilder\QueryBuilder;
class UserController extends Controller class UserController extends Controller
{ {
use Referral;
const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'discordUser']; const ALLOWED_INCLUDES = ['servers', 'notifications', 'payments', 'vouchers', 'discordUser'];
const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended']; const ALLOWED_FILTERS = ['name', 'server_limit', 'email', 'pterodactyl_id', 'role', 'suspended'];
@ -92,7 +95,7 @@ class UserController extends Controller
//Update Users Password on Pterodactyl //Update Users Password on Pterodactyl
//Username,Mail,First and Lastname are required aswell //Username,Mail,First and Lastname are required aswell
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [ $response = Pterodactyl::client()->patch('/application/users/' . $user->pterodactyl_id, [
'username' => $request->name, 'username' => $request->name,
'first_name' => $request->name, 'first_name' => $request->name,
'last_name' => $request->name, 'last_name' => $request->name,
@ -229,7 +232,7 @@ class UserController extends Controller
$discordUser = DiscordUser::find($id); $discordUser = DiscordUser::find($id);
$user = $discordUser ? $discordUser->user : User::findOrFail($id); $user = $discordUser ? $discordUser->user : User::findOrFail($id);
if (! $user->isSuspended()) { if (!$user->isSuspended()) {
throw ValidationException::withMessages([ throw ValidationException::withMessages([
'error' => 'You cannot unsuspend an User who is not suspended.', 'error' => 'You cannot unsuspend an User who is not suspended.',
]); ]);
@ -240,21 +243,6 @@ class UserController extends Controller
return $user; return $user;
} }
/**
* Create a unique Referral Code for User
*
* @return string
*/
protected function createReferralCode()
{
$referralcode = STR::random(8);
if (User::where('referral_code', '=', $referralcode)->exists()) {
$this->createReferralCode();
}
return $referralcode;
}
/** /**
* @throws ValidationException * @throws ValidationException
*/ */
@ -267,7 +255,7 @@ class UserController extends Controller
]); ]);
// Prevent the creation of new users via API if this is enabled. // Prevent the creation of new users via API if this is enabled.
if (! config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) { if (!config('SETTINGS::SYSTEM:CREATION_OF_NEW_USERS', 'true')) {
throw ValidationException::withMessages([ throw ValidationException::withMessages([
'error' => 'The creation of new users has been blocked by the system administrator.', 'error' => 'The creation of new users has been blocked by the system administrator.',
]); ]);
@ -305,7 +293,7 @@ class UserController extends Controller
'pterodactyl_id' => $response->json()['attributes']['id'], 'pterodactyl_id' => $response->json()['attributes']['id'],
]); ]);
//INCREMENT REFERRAL-USER CREDITS //INCREMENT REFERRAL-USER CREDITS
if (! empty($request->input('referral_code'))) { if (!empty($request->input('referral_code'))) {
$ref_code = $request->input('referral_code'); $ref_code = $request->input('referral_code');
$new_user = $user->id; $new_user = $user->id;
if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) { if ($ref_user = User::query()->where('referral_code', '=', $ref_code)->first()) {

View file

@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
use App\Models\User; use App\Models\User;
use App\Notifications\ReferralNotification; use App\Notifications\ReferralNotification;
use App\Providers\RouteServiceProvider; use App\Providers\RouteServiceProvider;
use App\Traits\Referral;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
@ -30,7 +31,7 @@ class RegisterController extends Controller
| |
*/ */
use RegistersUsers; use RegistersUsers, Referral;
/** /**
* Where to redirect users after registration. * Where to redirect users after registration.
@ -87,21 +88,6 @@ class RegisterController extends Controller
return Validator::make($data, $validationRules); return Validator::make($data, $validationRules);
} }
/**
* Create a unique Referral Code for User
*
* @return string
*/
protected function createReferralCode()
{
$referralcode = STR::random(8);
if (User::where('referral_code', '=', $referralcode)->exists()) {
$this->createReferralCode();
}
return $referralcode;
}
/** /**
* Create a new user instance after a valid registration. * Create a new user instance after a valid registration.
* *

23
app/Traits/Referral.php Normal file
View file

@ -0,0 +1,23 @@
<?php
namespace App\Traits;
use App\Models\User;
use Illuminate\Support\Str;
trait Referral
{
public function createReferralCode()
{
$code = Str::random(8);
// check if code already exists
if (User::where('referral_code', $code)->exists()) {
// if exists, generate another code
return $this->generateReferralCode();
}
return $code;
}
}

View file

@ -1,6 +1,7 @@
<?php <?php
use App\Models\User; use App\Models\User;
use App\Traits\Referral;
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -9,16 +10,13 @@ use Illuminate\Support\Str;
return new class extends Migration return new class extends Migration
{ {
public function generateCode($userid) use Referral;
public function setReferralCode($userid)
{ {
$random = STR::random(8); $code = $this->createReferralCode();
if (User::where('referral_code', '=', $random)->doesntExist()) { DB::table('users')
DB::table('users') ->where('id', '=', $userid)
->where('id', '=', $userid) ->update(['referral_code' => $code]);
->update(['referral_code' => $random]);
} else {
$this->generateCode($userid);
}
} }
/** /**
@ -35,7 +33,7 @@ return new class extends Migration
$existing_user = User::where('referral_code', '')->orWhere('referral_code', null)->get(); $existing_user = User::where('referral_code', '')->orWhere('referral_code', null)->get();
foreach ($existing_user as $user) { foreach ($existing_user as $user) {
$this->generateCode($user->id); $this->setReferralCode($user->id);
} }
} }

View file

@ -77,22 +77,25 @@
<div class="row"> <div class="row">
<!-- accepted payments column --> <!-- accepted payments column -->
<div class="col-6"> <div class="col-6">
<p class="lead">{{ __('Payment Methods') }}:</p> @if (!$productIsFree)
<p class="lead">{{ __('Payment Methods') }}:</p>
<div class="d-flex flex-wrap flex-direction-row"> <div class="d-flex flex-wrap flex-direction-row">
@foreach ($paymentGateways as $gateway) @foreach ($paymentGateways as $gateway)
<div class="ml-2"> <div class="ml-2">
<label class="text-center" for="{{ $gateway->name }}"> <label class="text-center" for="{{ $gateway->name }}">
<img class="mb-3" height="50" src="{{ $gateway->image }}"></br> <img class="mb-3" height="50"
<input x-on:click="console.log(payment_method)" x-model="payment_method" src="{{ $gateway->image }}"></br>
type="radio" id="{{ $gateway->name }}" <input x-on:click="console.log(payment_method)"
value="{{ $gateway->name }}"> x-model="payment_method" type="radio"
</input> id="{{ $gateway->name }}" value="{{ $gateway->name }}">
</label> </input>
</div> </label>
@endforeach </div>
</div> @endforeach
</div>
@endif
</div> </div>
<!-- /.col --> <!-- /.col -->
@ -130,11 +133,15 @@
<!-- this row will not appear when printing --> <!-- this row will not appear when printing -->
<div class="row no-print"> <div class="row no-print">
<div class="col-12"> <div class="col-12">
<button :disabled="!payment_method || clicked" <button :disabled="(!payment_method || clicked) && {{ !$productIsFree }}"
:class="!payment_method || clicked ? 'disabled' : ''" :class="(!payment_method || clicked) && {{ !$productIsFree }} ? 'disabled' : ''"
class="btn btn-success float-right"><i class="far fa-credit-card mr-2" class="btn btn-success float-right"><i class="far fa-credit-card mr-2"
@click="clicked = true"></i> @click="clicked = true"></i>
{{ __('Submit Payment') }} @if ($productIsFree)
{{ __('Get for free') }}
@else
{{ __('Submit Payment') }}
@endif
</button> </button>
</div> </div>
</div> </div>