Merge pull request #575 from ok236449/Partners-and-discounts

Partners and discounts
This commit is contained in:
Dennis 2023-01-02 13:09:18 +01:00 committed by GitHub
commit 8b8d73c3b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1060 additions and 96 deletions

View file

@ -40,6 +40,7 @@ class Misc
'enable_referral' => 'nullable|string',
'referral_reward' => 'nullable|numeric',
'referral_allowed' => 'nullable|string',
'always_give_commission' => 'nullable|string',
'referral_percentage' => 'nullable|numeric',
'referral_mode' => 'nullable|string',
'ticket_enabled' => 'nullable|string',
@ -87,6 +88,7 @@ class Misc
"SETTINGS::REFERRAL::REWARD" => "referral_reward",
"SETTINGS::REFERRAL::ALLOWED" => "referral_allowed",
"SETTINGS::REFERRAL:MODE" => "referral_mode",
"SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION" => "always_give_commission",
"SETTINGS::REFERRAL:PERCENTAGE" => "referral_percentage",
"SETTINGS::TICKET:ENABLED" => "ticket_enabled"

View file

@ -52,6 +52,19 @@ class OverViewController extends Controller
$counters['payments']['thisMonth']->timeEnd = Carbon::today()->toDateString();
$counters['payments']['lastMonth']->timeStart = Carbon::today()->startOfMonth()->subMonth()->toDateString();
$counters['payments']['lastMonth']->timeEnd = Carbon::today()->endOfMonth()->subMonth()->toDateString();
//Prepare subCollection 'taxPayments'
$counters->put('taxPayments', collect());
//Get and save taxPayments from last 2 years for later filtering and looping
$taxPayments = Payment::query()->where('created_at', '>=', Carbon::today()->startOfYear()->subYear())->where('status', 'paid')->get();
//Prepare collections and set a few variables
$counters['taxPayments']->put('thisYear', collect());
$counters['taxPayments']->put('lastYear', collect());
$counters['taxPayments']['thisYear']->timeStart = Carbon::today()->startOfYear()->toDateString();
$counters['taxPayments']['thisYear']->timeEnd = Carbon::today()->toDateString();
$counters['taxPayments']['lastYear']->timeStart = Carbon::today()->startOfYear()->subYear()->toDateString();
$counters['taxPayments']['lastYear']->timeEnd = Carbon::today()->endOfYear()->subYear()->toDateString();
//Fill out variables for each currency separately
foreach($payments->where('created_at', '>=', Carbon::today()->startOfMonth()) as $payment){
@ -76,6 +89,35 @@ class OverViewController extends Controller
}
$counters['payments']->total = Payment::query()->count();
foreach($taxPayments->where('created_at', '>=', Carbon::today()->startOfYear()->subYear()) as $taxPayment){
$paymentCurrency = $payment->currency_code;
if(!isset($counters['taxPayments']['thisYear'][$paymentCurrency])){
$counters['taxPayments']['thisYear']->put($paymentCurrency, collect());
$counters['taxPayments']['thisYear'][$paymentCurrency]->total = 0;
$counters['taxPayments']['thisYear'][$paymentCurrency]->count = 0;
$counters['taxPayments']['thisYear'][$paymentCurrency]->price = 0;
$counters['taxPayments']['thisYear'][$paymentCurrency]->taxes = 0;
}
$counters['taxPayments']['thisYear'][$paymentCurrency]->total += $taxPayment->total_price;
$counters['taxPayments']['thisYear'][$paymentCurrency]->count ++;
$counters['taxPayments']['thisYear'][$paymentCurrency]->price += $taxPayment->price;
$counters['taxPayments']['thisYear'][$paymentCurrency]->taxes += $taxPayment->tax_value;
}
foreach($taxPayments->where('created_at', '<', Carbon::today()->startOfYear()) as $taxPayment){
$paymentCurrency = $payment->currency_code;
if(!isset($counters['taxPayments']['lastYear'][$paymentCurrency])){
$counters['taxPayments']['lastYear']->put($paymentCurrency, collect());
$counters['taxPayments']['lastYear'][$paymentCurrency]->total = 0;
$counters['taxPayments']['lastYear'][$paymentCurrency]->count = 0;
$counters['taxPayments']['lastYear'][$paymentCurrency]->price = 0;
$counters['taxPayments']['lastYear'][$paymentCurrency]->taxes = 0;
}
$counters['taxPayments']['lastYear'][$paymentCurrency]->total += $taxPayment->total_price;
$counters['taxPayments']['lastYear'][$paymentCurrency]->count ++;
$counters['taxPayments']['lastYear'][$paymentCurrency]->price += $taxPayment->price;
$counters['taxPayments']['lastYear'][$paymentCurrency]->taxes += $taxPayment->tax_value;
}
$lastEgg = Egg::query()->latest('updated_at')->first();
$syncLastUpdate = $lastEgg ? $lastEgg->updated_at->isoFormat('LLL') : __('unknown');
@ -124,33 +166,30 @@ class OverViewController extends Controller
//Get latest tickets
$tickets = Cache::remember('tickets', self::TTL, function(){
$output = collect();
foreach(Ticket::query()->latest()->take(3)->get() as $ticket){
$output->put($ticket->ticket_id, collect());
$output[$ticket->ticket_id]->title = $ticket->title;
$user = User::query()->where('id', $ticket->user_id)->first();
$output[$ticket->ticket_id]->user_id = $user->id;
$output[$ticket->ticket_id]->user = $user->name;
$output[$ticket->ticket_id]->status = $ticket->status;
$output[$ticket->ticket_id]->last_updated = $ticket->updated_at->diffForHumans();
switch ($ticket->status) {
case 'Open':
$output[$ticket->ticket_id]->statusBadgeColor = 'badge-success';
break;
case 'Closed':
$output[$ticket->ticket_id]->statusBadgeColor = 'badge-danger';
break;
case 'Answered':
$output[$ticket->ticket_id]->statusBadgeColor = 'badge-info';
break;
default:
$output[$ticket->ticket_id]->statusBadgeColor = 'badge-warning';
break;
}
$tickets = collect();
foreach(Ticket::query()->latest()->take(5)->get() as $ticket){
$tickets->put($ticket->ticket_id, collect());
$tickets[$ticket->ticket_id]->title = $ticket->title;
$user = User::query()->where('id', $ticket->user_id)->first();
$tickets[$ticket->ticket_id]->user_id = $user->id;
$tickets[$ticket->ticket_id]->user = $user->name;
$tickets[$ticket->ticket_id]->status = $ticket->status;
$tickets[$ticket->ticket_id]->last_updated = $ticket->updated_at->diffForHumans();
switch ($ticket->status) {
case 'Open':
$tickets[$ticket->ticket_id]->statusBadgeColor = 'badge-success';
break;
case 'Closed':
$tickets[$ticket->ticket_id]->statusBadgeColor = 'badge-danger';
break;
case 'Answered':
$tickets[$ticket->ticket_id]->statusBadgeColor = 'badge-info';
break;
default:
$tickets[$ticket->ticket_id]->statusBadgeColor = 'badge-warning';
break;
}
return $output;
});
}
return view('admin.overview.index', [
'counters' => $counters,

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller;
use App\Models\InvoiceSettings;
use App\Models\PartnerDiscount;
use App\Models\Payment;
use App\Models\ShopProduct;
use App\Models\Settings;
@ -57,10 +58,13 @@ class PaymentController extends Controller
public function checkOut(Request $request, ShopProduct $shopProduct)
{
return view('store.checkout')->with([
'product' => $shopProduct,
'taxvalue' => $shopProduct->getTaxValue(),
'taxpercent' => $shopProduct->getTaxPercent(),
'total' => $shopProduct->getTotalPrice()
'product' => $shopProduct,
'discountpercent' => PartnerDiscount::getDiscount(),
'discountvalue' => PartnerDiscount::getDiscount() * $shopProduct->price/100,
'discountedprice' => $shopProduct->getPriceAfterDiscount(),
'taxvalue' => $shopProduct->getTaxValue(),
'taxpercent' => $shopProduct->getTaxPercent(),
'total' => $shopProduct->getTotalPrice()
]);
}
@ -78,7 +82,7 @@ class PaymentController extends Controller
"purchase_units" => [
[
"reference_id" => uniqid(),
"description" => $shopProduct->description,
"description" => $shopProduct->display . (PartnerDiscount::getDiscount()?(" (" . __('Discount') . " " . PartnerDiscount::getDiscount() . '%)'):""),
"amount" => [
"value" => $shopProduct->getTotalPrice(),
'currency_code' => strtoupper($shopProduct->currency_code),
@ -86,7 +90,7 @@ class PaymentController extends Controller
'item_total' =>
[
'currency_code' => strtoupper($shopProduct->currency_code),
'value' => $shopProduct->price,
'value' => $shopProduct->getPriceAfterDiscount(),
],
'tax_total' =>
[
@ -180,15 +184,31 @@ class PaymentController extends Controller
$user->increment('server_limit', $shopProduct->quantity);
}
//give referral commission always
if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "true"){
if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
$ref_user = User::findOrFail($ref_user->referral_id);
$increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"","");
$ref_user->increment('credits', $increment);
//LOGS REFERRALS IN THE ACTIVITY LOG
activity()
->performedOn($user)
->causedBy($ref_user)
->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')');
}
}
//update role give Referral-reward
if ($user->role == 'member') {
$user->update(['role' => 'client']);
if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits"){
//give referral commission only on first purchase
if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "false"){
if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
$ref_user = User::findOrFail($ref_user->referral_id);
$increment = number_format($shopProduct->quantity/100*config("SETTINGS::REFERRAL:PERCENTAGE"),0,"","");
$increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"","");
$ref_user->increment('credits', $increment);
//LOGS REFERRALS IN THE ACTIVITY LOG
@ -210,7 +230,7 @@ class PaymentController extends Controller
'type' => $shopProduct->type,
'status' => 'paid',
'amount' => $shopProduct->quantity,
'price' => $shopProduct->price,
'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100),
'tax_value' => $shopProduct->getTaxValue(),
'tax_percent' => $shopProduct->getTaxPercent(),
'total_price' => $shopProduct->getTotalPrice(),
@ -273,10 +293,10 @@ class PaymentController extends Controller
'price_data' => [
'currency' => $shopProduct->currency_code,
'product_data' => [
'name' => $shopProduct->display,
'name' => $shopProduct->display . (PartnerDiscount::getDiscount()?(" (" . __('Discount') . " " . PartnerDiscount::getDiscount() . '%)'):""),
'description' => $shopProduct->description,
],
'unit_amount_decimal' => round($shopProduct->price * 100, 2),
'unit_amount_decimal' => round($shopProduct->getPriceAfterDiscount() * 100, 2),
],
'quantity' => 1,
],
@ -284,7 +304,7 @@ class PaymentController extends Controller
'price_data' => [
'currency' => $shopProduct->currency_code,
'product_data' => [
'name' => 'Product Tax',
'name' => __('Tax'),
'description' => $shopProduct->getTaxPercent() . "%",
],
'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2) * 100,
@ -373,7 +393,7 @@ class PaymentController extends Controller
'type' => $shopProduct->type,
'status' => 'paid',
'amount' => $shopProduct->quantity,
'price' => $shopProduct->price,
'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100),
'tax_value' => $shopProduct->getTaxValue(),
'total_price' => $shopProduct->getTotalPrice(),
'tax_percent' => $shopProduct->getTaxPercent(),
@ -611,7 +631,7 @@ class PaymentController extends Controller
->name(__("Invoice"))
->buyer($customer)
->seller($seller)
->discountByPercent(0)
->discountByPercent(PartnerDiscount::getDiscount())
->taxRate(floatval($shopProduct->getTaxPercent()))
->shipping(0)
->addItem($item)
@ -654,7 +674,8 @@ class PaymentController extends Controller
return datatables($query)
->editColumn('user', function (Payment $payment) {
return $payment->user->name;
return
($payment->user)?'<a href="'.route('admin.users.show', $payment->user->id).'">'.$payment->user->name.'</a>':__('Unknown user');
})
->editColumn('price', function (Payment $payment) {
return $payment->formatToCurrency($payment->price);
@ -675,7 +696,7 @@ class PaymentController extends Controller
->addColumn('actions', function (Payment $payment) {
return '<a data-content="' . __("Download") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.invoices.downloadSingleInvoice', "id=" . $payment->payment_id) . '" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-file-download"></i></a>';
})
->rawColumns(['actions'])
->rawColumns(['actions', 'user'])
->make(true);
}
}
}

View file

@ -288,7 +288,8 @@ class UserController extends Controller
return $user->discordUser ? $user->discordUser->id : '';
})
->addColumn('last_seen', function (User $user) {
return $user->last_seen ? $user->last_seen->diffForHumans() : '';
return ['display' => $user->last_seen ? $user->last_seen->diffForHumans() : '',
'raw' => $user->last_seen ? strtotime($user->last_seen) : ''];
})
->addColumn('actions', function (User $user) {
$suspendColor = $user->isSuspended() ? "btn-success" : "btn-warning";
@ -331,9 +332,9 @@ class UserController extends Controller
->editColumn('name', function (User $user) {
return '<a class="text-info" target="_blank" href="' . config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/users/view/' . $user->pterodactyl_id . '">' . strip_tags($user->name) . '</a>';
})
->orderColumn('last_seen', function ($query) {
/*->orderColumn('last_seen', function ($query) {
$query->orderBy('last_seen', "desc");
})
})*/
->rawColumns(['avatar', 'name', 'credits', 'role', 'usage', 'referrals', 'actions', 'last_seen'])
->make(true);
}

View file

@ -2,9 +2,11 @@
namespace App\Http\Controllers;
use App\Models\PartnerDiscount;
use App\Models\UsefulLink;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
@ -105,7 +107,10 @@ class HomeController extends Controller
'useful_links' => UsefulLink::all()->sortBy('id'),
'bg' => $bg,
'boxText' => $boxText,
'unit' => $unit
'unit' => $unit,
'numberOfReferrals' => DB::table('user_referrals')->where("referral_id","=",Auth::user()->id)->count(),
'partnerDiscount' => PartnerDiscount::where('user_id', Auth::user()->id)->first(),
'myDiscount' => PartnerDiscount::getDiscount()
]);
}
}

View file

@ -0,0 +1,206 @@
<?php
namespace App\Http\Controllers;
use App\Models\PartnerDiscount;
use App\Models\User;
use Illuminate\Http\Request;
class PartnerController extends Controller
{
public function index()
{
return view('admin.partners.index');
}
/**
* Show the form for creating a new resource.
*
* @return Application|Factory|View
*/
public function create()
{
return view('admin.partners.create', [
'partners' =>PartnerDiscount::get(),
'users' => User::orderBy('name')->get()
]);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return RedirectResponse
*/
public function store(Request $request)
{
$request->validate([
'user_id' => 'required|integer|min:0',
'partner_discount' => 'required|integer|max:100|min:0',
'registered_user_discount' => 'required|integer|max:100|min:0'
]);
PartnerDiscount::create($request->all());
return redirect()->route('admin.partners.index')->with('success', __('partner has been created!'));
}
/**
* Display the specified resource.
*
* @param Voucher $voucher
* @return Response
*/
public function show(Voucher $voucher)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param Voucher $voucher
* @return Application|Factory|View
*/
public function edit(PartnerDiscount $partner)
{
return view('admin.partners.edit', [
'partners' =>PartnerDiscount::get(),
'partner' => $partner,
'users' => User::orderBy('name')->get()
]);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @param Voucher $voucher
* @return RedirectResponse
*/
public function update(Request $request, PartnerDiscount $partner)
{
//dd($request);
$request->validate([
'user_id' => 'required|integer|min:0',
'partner_discount' => 'required|integer|max:100|min:0',
'registered_user_discount' => 'required|integer|max:100|min:0'
]);
$partner->update($request->all());
return redirect()->route('admin.partners.index')->with('success', __('partner has been updated!'));
}
/**
* Remove the specified resource from storage.
*
* @param Voucher $voucher
* @return RedirectResponse
*/
public function destroy(PartnerDiscount $partner)
{
$partner->delete();
return redirect()->back()->with('success', __('partner has been removed!'));
}
public function users(Voucher $voucher)
{
return view('admin.vouchers.users', [
'voucher' => $voucher
]);
}
/**
* @param Request $request
* @return JsonResponse
* @throws ValidationException
*/
public function redeem(Request $request)
{
#general validations
$request->validate([
'code' => 'required|exists:vouchers,code'
]);
#get voucher by code
$voucher = Voucher::where('code', '=', $request->input('code'))->firstOrFail();
#extra validations
if ($voucher->getStatus() == 'USES_LIMIT_REACHED') throw ValidationException::withMessages([
'code' => __('This voucher has reached the maximum amount of uses')
]);
if ($voucher->getStatus() == 'EXPIRED') throw ValidationException::withMessages([
'code' => __('This voucher has expired')
]);
if (!$request->user()->vouchers()->where('id', '=', $voucher->id)->get()->isEmpty()) throw ValidationException::withMessages([
'code' => __('You already redeemed this voucher code')
]);
if ($request->user()->credits + $voucher->credits >= 99999999) throw ValidationException::withMessages([
'code' => "You can't redeem this voucher because you would exceed the limit of " . CREDITS_DISPLAY_NAME
]);
#redeem voucher
$voucher->redeem($request->user());
event(new UserUpdateCreditsEvent($request->user()));
return response()->json([
'success' => "{$voucher->credits} " . CREDITS_DISPLAY_NAME ." ". __("have been added to your balance!")
]);
}
public function usersDataTable(Voucher $voucher)
{
$users = $voucher->users();
return datatables($users)
->editColumn('name', function (User $user) {
return '<a class="text-info" target="_blank" href="' . route('admin.users.show', $user->id) . '">' . $user->name . '</a>';
})
->addColumn('credits', function (User $user) {
return '<i class="fas fa-coins mr-2"></i> ' . $user->credits();
})
->addColumn('last_seen', function (User $user) {
return $user->last_seen ? $user->last_seen->diffForHumans() : '';
})
->rawColumns(['name', 'credits', 'last_seen'])
->make();
}
public function dataTable()
{
$query = PartnerDiscount::query();
return datatables($query)
->addColumn('actions', function (PartnerDiscount $partner) {
return '
<a data-content="'.__("Edit").'" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.partners.edit', $partner->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.partners.destroy', $partner->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="'.__("Delete").'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})
->addColumn('user', function (PartnerDiscount $partner) {
return ($user=User::where('id', $partner->user_id)->first())?'<a href="'.route('admin.users.show', $partner->user_id).'">'.$user->name.'</a>':__('Unknown user');
})
->editColumn('created_at', function (PartnerDiscount $partner) {
return $partner->created_at ? $partner->created_at->diffForHumans() : '';
})
->editColumn('partner_discount', function (PartnerDiscount $partner) {
return $partner->partner_discount ? $partner->partner_discount . "%" : "0%";
})
->editColumn('registered_user_discount', function (PartnerDiscount $partner) {
return $partner->registered_user_discount ? $partner->registered_user_discount . "%" : "0%";
})
->editColumn('referral_system_commission', function (PartnerDiscount $partner) {
return $partner->referral_system_commission>=0 ? $partner->referral_system_commission . "%" : __('Default') . " (" . config("SETTINGS::REFERRAL:PERCENTAGE") . "%)";
})
->rawColumns(['user', 'actions'])
->make();
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class PartnerDiscount extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'partner_discount',
'registered_user_discount',
'referral_system_commission'
];
public static function getDiscount()
{
if($partnerDiscount = PartnerDiscount::where('user_id', Auth::user()->id)->first()){
return $partnerDiscount->partner_discount;
}
else if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', Auth::user()->id)->first()){
if($partnerDiscount = PartnerDiscount::where('user_id', $ref_user->referral_id)->first()){
return $partnerDiscount->registered_user_discount;
}
return 0;
}
return 0;
}
public static function getCommission($user_id)
{
if($partnerDiscount = PartnerDiscount::where('user_id', $user_id)->first()){
if($partnerDiscount->referral_system_commission>=0) return $partnerDiscount->referral_system_commission>=0;
}
return config("SETTINGS::REFERRAL:PERCENTAGE");
}
}

View file

@ -63,6 +63,11 @@ class ShopProduct extends Model
return $tax < 0 ? 0 : $tax;
}
public function getPriceAfterDiscount()
{
return number_format($this->price - ($this->price * PartnerDiscount::getDiscount() / 100), 2);
}
/**
* @description Returns the tax as Number
*
@ -70,7 +75,7 @@ class ShopProduct extends Model
*/
public function getTaxValue()
{
return number_format($this->price * $this->getTaxPercent() / 100, 2);
return number_format($this->getPriceAfterDiscount() * $this->getTaxPercent() / 100, 2);
}
/**
@ -80,6 +85,6 @@ class ShopProduct extends Model
*/
public function getTotalPrice()
{
return number_format($this->price + $this->getTaxValue(), 2);
return number_format($this->getPriceAfterDiscount() + $this->getTaxValue(), 2);
}
}
}

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePartnerDiscountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('partner_discounts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id');
$table->integer('partner_discount');
$table->integer('registered_user_discount');
$table->integer('referral_system_commission');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('partner_discounts');
}
}

View file

@ -479,6 +479,13 @@ class SettingsSeeder extends Seeder
'type' => 'string',
'description' => 'Enable or disable the referral system'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION',
], [
'value' =>"false",
'type' => 'string',
'description' => 'Whether referrals get percentage commission only on first purchase or on every purchase'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::REFERRAL::REWARD',
], [

View file

@ -254,6 +254,7 @@
</tr>
</tfoot>
</table>
<hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
</div>
</div>
<div class="card">
@ -266,32 +267,36 @@
</div>
<div class="card-body py-1">
<div class="row">
<div class="col-md-6" style="border-right:1px solid #6c757d">
<span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last month')}}:
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['lastMonth']->timeStart}} - {{$counters['payments']['lastMonth']->timeEnd}}"
class="fas fa-info-circle"></i>
</span>
<table class="table">
<thead>
<tr>
<th><b>{{__('Currency')}}</b></th>
<th>{{__('Number of payments')}}</th>
<th>{{__('Total income')}}</th>
</tr>
</thead>
<tbody>
@foreach($counters['payments']['lastMonth'] as $currency => $income)
<tr>
<td>{{$currency}}</td>
<td>{{$income->count}}</td>
<td>{{$income->total}}</td>
</tr>
@endforeach
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: -16px">
</div><div class="col-md-6">
@if($counters['payments']['lastMonth']->count())
<div class="col-md-6" style="border-right:1px solid #6c757d">
<span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last month')}}:
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['lastMonth']->timeStart}} - {{$counters['payments']['lastMonth']->timeEnd}}"
class="fas fa-info-circle"></i>
</span>
<table class="table">
<thead>
<tr>
<th><b>{{__('Currency')}}</b></th>
<th>{{__('Number of payments')}}</th>
<th>{{__('Total amount')}}</th>
</tr>
</thead>
<tbody>
@foreach($counters['payments']['lastMonth'] as $currency => $income)
<tr>
<td>{{$currency}}</td>
<td>{{$income->count}}</td>
<td>{{$income->total}}</td>
</tr>
@endforeach
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: -16px">
</div>
@endif
@if($counters['payments']['lastMonth']->count()) <div class="col-md-6">
@else <div class="col-md-12"> @endif
<span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This month')}}:
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Payments in this time window') }}:<br>{{$counters['payments']['thisMonth']->timeStart}} - {{$counters['payments']['thisMonth']->timeEnd}}"
@ -302,7 +307,7 @@
<tr>
<th><b>{{__('Currency')}}</b></th>
<th>{{__('Number of payments')}}</th>
<th>{{__('Total income')}}</th>
<th>{{__('Total amount')}}</th>
</tr>
</thead>
<tbody>
@ -321,6 +326,75 @@
</div>
</div>
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="card-title ">
<span><i class="fas fa-hand-holding-usd mr-2"></i>{{__('Tax overview')}}</span>
</div>
</div>
</div>
<div class="card-body py-1">
@if($counters['taxPayments']['lastYear']->count())
<span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('Last year')}}:
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['lastYear']->timeStart}} - {{$counters['taxPayments']['lastYear']->timeEnd}}"
class="fas fa-info-circle"></i>
</span>
<table class="table">
<thead>
<tr>
<th><b>{{__('Currency')}}</b></th>
<th>{{__('Number of payments')}}</th>
<th><b>{{__('Base amount')}}</b></th>
<th><b>{{__('Total taxes')}}</b></th>
<th>{{__('Total amount')}}</th>
</tr>
</thead>
<tbody>
@foreach($counters['taxPayments']['lastYear'] as $currency => $income)
<tr>
<td>{{$currency}}</td>
<td>{{$income->count}}</td>
<td>{{$income->price}}</td>
<td>{{$income->taxes}}</td>
<td>{{$income->total}}</td>
</tr>
@endforeach
</tbody>
</table>
<hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px; margin-bottom: 8px">
@endif
<span style="margin:auto; display:table; font-size: 18px; font-weight:700">{{__('This year')}}:
<i data-toggle="popover" data-trigger="hover" data-html="true"
data-content="{{ __('Payments in this time window') }}:<br>{{$counters['taxPayments']['thisYear']->timeStart}} - {{$counters['taxPayments']['thisYear']->timeEnd}}"
class="fas fa-info-circle"></i>
</span>
<table class="table">
<thead>
<tr>
<th><b>{{__('Currency')}}</b></th>
<th>{{__('Number of payments')}}</th>
<th><b>{{__('Base amount')}}</b></th>
<th><b>{{__('Total taxes')}}</b></th>
<th>{{__('Total amount')}}</th>
</tr>
</thead>
<tbody>
@foreach($counters['taxPayments']['thisYear'] as $currency => $income)
<tr>
<td>{{$currency}}</td>
<td>{{$income->count}}</td>
<td>{{$income->price}}</td>
<td>{{$income->taxes}}</td>
<td>{{$income->total}}</td>
</tr>
@endforeach
</tbody>
</table>
<hr style="width: 100%; height:2px; border-width:0; background-color:#6c757d; margin-top: 0px;">
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,139 @@
@extends('layouts.main')
@section('content')
<!-- CONTENT HEADER -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{__('Vouchers')}}</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
<li class="breadcrumb-item"><a href="{{route('admin.partners.index')}}">{{__('Vouchers')}}</a>
</li>
<li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.partners.create')}}">{{__('Create')}}</a>
</li>
</ol>
</div>
</div>
</div>
</section>
<!-- END CONTENT HEADER -->
<!-- MAIN CONTENT -->
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-handshake mr-2"></i>{{__('Partner details')}}
</h5>
</div>
<div class="card-body">
<form action="{{route('admin.partners.store')}}" method="POST">
@csrf
<div class="form-group">
<label for="user_id">{{__('User')}}</label>
<select id="user_id" style="width:100%"
class="custom-select @error('user') is-invalid @enderror" name="user_id" autocomplete="off">
@foreach($users as $user)
<option @if($partners->contains('user_id' , $user->id)) disabled @endif
value="{{$user->id}}">{{$user->name}} ({{$user->email}})</option>
@endforeach
</select>
@error('user')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="partner_discount">{{__('Partner discount')}}</label>
<input value="{{old('partner_discount')}}" placeholder="{{__('Discount in percent')}}" id="partner_discount" name="partner_discount"
type="number" step="any" min="0" max="100"
class="form-control @error('partner_discount') is-invalid @enderror">
@error('partner_discount')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="registered_user_discount">{{__('Registered user discount')}}</label>
<div class="input-group">
<input value="{{old('registered_user_discount')}}" placeholder="Discount in percent" id="registered_user_discount" name="registered_user_discount"
type="number" class="form-control @error('registered_user_discount') is-invalid @enderror"
required="required">
</div>
@error('registered_user_discount')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="referral_system_commission">{{__('Referral system commission')}}
<i data-toggle="popover" data-trigger="hover"
data-content="{{__('Override value for referral system commission. You can set it to -1 to get the default commission from settings.')}}"
class="fas fa-info-circle"></i>
</label>
<input value="{{old('referral_system_commission')}}" placeholder="{{__('Commission in percent')}}" id="referral_system_commission" name="referral_system_commission"
type="number" step="any" min="-1" max="100"
class="form-control @error('referral_system_commission') is-invalid @enderror">
@error('referral_system_commission')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-primary">
{{__('Submit')}}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<i class="fas"></i>
</div>
</section>
<!-- END CONTENT -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
$('#expires_at').datetimepicker({
format: 'DD-MM-yyyy HH:mm:ss',
icons: {
time: 'far fa-clock',
date: 'far fa-calendar',
up: 'fas fa-arrow-up',
down: 'fas fa-arrow-down',
previous: 'fas fa-chevron-left',
next: 'fas fa-chevron-right',
today: 'fas fa-calendar-check',
clear: 'far fa-trash-alt',
close: 'far fa-times-circle'
}
});
})
</script>
@endsection

View file

@ -0,0 +1,158 @@
@extends('layouts.main')
@section('content')
<!-- CONTENT HEADER -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{__('Partners')}}</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
<li class="breadcrumb-item"><a href="{{route('admin.partners.index')}}">{{__('Partners')}}</a>
</li>
<li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.partners.edit' , $partner->id)}}">{{__('Edit')}}</a>
</li>
</ol>
</div>
</div>
</div>
</section>
<!-- END CONTENT HEADER -->
<!-- MAIN CONTENT -->
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-handshake mr-2"></i>{{__('Partner details')}}
</h5>
</div>
<div class="card-body">
<form action="{{route('admin.partners.update' , $partner->id)}}" method="POST">
@csrf
@method('PATCH')
<div class="form-group">
<label for="user_id">{{__('User')}}</label>
<select id="user_id" style="width:100%"
class="custom-select @error('user') is-invalid @enderror" name="user_id" autocomplete="off">
@foreach($users as $user)
<option @if($partners->contains('user_id' , $user->id)&&$partner->user_id!=$user->id) disabled @endif
@if($partner->user_id==$user->id) selected @endif
value="{{$user->id}}">{{$user->name}} ({{$user->email}})</option>
@endforeach
</select>
@error('user')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="partner_discount">{{__('Partner discount')}}</label>
<input value="{{$partner->partner_discount}}" placeholder="{{__('Discount in percent')}}" id="partner_discount" name="partner_discount"
type="number" step="any" min="0" max="100"
class="form-control @error('partner_discount') is-invalid @enderror">
@error('partner_discount')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="registered_user_discount">{{__('Registered user discount')}}</label>
<div class="input-group">
<input value="{{$partner->registered_user_discount}}" placeholder="Discount in percent" id="registered_user_discount" name="registered_user_discount"
type="number" class="form-control @error('registered_user_discount') is-invalid @enderror"
required="required">
</div>
@error('registered_user_discount')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group">
<label for="referral_system_commission">{{__('Referral system commission')}}
<i data-toggle="popover" data-trigger="hover"
data-content="{{__('Override value for referral system commission. You can set it to -1 to get the default commission from settings.')}}"
class="fas fa-info-circle"></i>
</label>
<input value="{{$partner->referral_system_commission}}" placeholder="{{__('Commission in percent')}}" id="referral_system_commission" name="referral_system_commission"
type="number" step="any" min="-1" max="100"
class="form-control @error('referral_system_commission') is-invalid @enderror">
@error('referral_system_commission')
<div class="text-danger">
{{$message}}
</div>
@enderror
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-primary">
{{__('Submit')}}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- END CONTENT -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
$('#expires_at').datetimepicker({
format: 'DD-MM-yyyy HH:mm:ss',
icons: {
time: 'far fa-clock',
date: 'far fa-calendar',
up: 'fas fa-arrow-up',
down: 'fas fa-arrow-down',
previous: 'fas fa-chevron-left',
next: 'fas fa-chevron-right',
today: 'fas fa-calendar-check',
clear: 'far fa-trash-alt',
close: 'far fa-times-circle'
}
});
})
function setMaxUses() {
let element = document.getElementById('uses')
element.value = element.max;
console.log(element.max)
}
function setRandomCode() {
let element = document.getElementById('code')
element.value = getRandomCode(36)
}
function getRandomCode(length) {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-';
let charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;
}
</script>
@endsection

View file

@ -0,0 +1,94 @@
@extends('layouts.main')
@section('content')
<!-- CONTENT HEADER -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>{{__('Partners')}}</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="{{route('home')}}">{{__('Dashboard')}}</a></li>
<li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.partners.index')}}">{{__('Partners')}}</a></li>
</ol>
</div>
</div>
</div>
</section>
<!-- END CONTENT HEADER -->
<!-- MAIN CONTENT -->
<section class="content">
<div class="container-fluid">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<h5 class="card-title"><i class="fas fa-handshake mr-2"></i>{{__('Partners')}}</h5>
<a href="{{route('admin.partners.create')}}" class="btn btn-sm btn-primary"><i
class="fas fa-plus mr-1"></i>{{__('Create new')}}</a>
</div>
</div>
<div class="card-body table-responsive">
<table id="datatable" class="table table-striped">
<thead>
<tr>
<th>{{__('User')}}</th>
<th>{{__('Partner discount')}}</th>
<th>{{__('Registered user discount')}}</th>
<th>{{__('Referral system commission')}}</th>
<th>{{__('Created')}}</th>
<th>{{__('Actions')}}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<!-- END CUSTOM CONTENT -->
</section>
<!-- END CONTENT -->
<script>
function submitResult() {
return confirm("{{__('Are you sure you wish to delete?')}}") !== false;
}
document.addEventListener("DOMContentLoaded", function () {
$('#datatable').DataTable({
language: {
url: '//cdn.datatables.net/plug-ins/1.11.3/i18n/{{config("SETTINGS::LOCALE:DATATABLES")}}.json'
},
processing: true,
serverSide: true,
stateSave: true,
ajax: "{{route('admin.partners.datatable')}}",
columns: [
{data: 'user'},
{data: 'partner_discount'},
{data: 'registered_user_discount'},
{data: 'referral_system_commission'},
{data: 'created_at'},
{data: 'actions', sortable: false}
],
fnDrawCallback: function( oSettings ) {
$('[data-toggle="popover"]').popover();
}
});
});
</script>
@endsection

View file

@ -39,6 +39,7 @@
<tr>
<th>{{ __('ID') }}</th>
<th>{{ __('Type') }}</th>
<th>{{ __('User') }}</th>
<th>{{ __('Amount') }}</th>
<th>{{ __('Product Price') }}</th>
<th>{{ __('Tax Value') }}</th>
@ -77,6 +78,7 @@
columns: [
{data: 'id',name: 'payments.id'},
{data: 'type'},
{data: 'user', sortable: false},
{data: 'amount'},
{data: 'price'},
{data: 'tax_value'},

View file

@ -222,6 +222,20 @@
</div>
</div>
<div class="custom-control mb-3 p-0">
<div class="col m-0 p-0 d-flex justify-content-between align-items-center">
<div>
<input value="true" id="always_give_commission" name="always_give_commission"
{{ config('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') == 'true' ? 'checked' : '' }}
type="checkbox">
<label for="always_give_commission">{{ __('Always give commission') }}:
<i data-toggle="popover" data-trigger="hover"
data-content="{{ __('Should users recieve the commission only for the first payment, or for every payment?') }}" class="fas fa-info-circle"></i>
</label>
</div>
</div>
</div>
<div class="custom-control mb-3 p-0">
<label for="referral_mode">{{ __('Mode') }}:
<i data-toggle="popover" data-trigger="hover"

View file

@ -90,10 +90,10 @@
{data: 'role'},
{data: 'email', name: 'users.email'},
{data: 'credits' , name : 'users.credits'},
{data: 'servers' , sortable : false},
{data: 'servers'},
{data: 'referrals'},
{data: 'verified' , sortable : false},
{data: 'last_seen'},
{data: 'last_seen', type: 'num', render: {_: 'display', sort: 'raw'}},
{data: 'actions' , sortable : false},
],
fnDrawCallback: function( oSettings ) {

View file

@ -14,7 +14,7 @@
<li class="breadcrumb-item"><a href="{{route('admin.vouchers.index')}}">{{__('Vouchers')}}</a>
</li>
<li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.products.create')}}">{{__('Create')}}</a>
href="{{route('admin.vouchers.create')}}">{{__('Create')}}</a>
</li>
</ol>
</div>

View file

@ -14,7 +14,7 @@
<li class="breadcrumb-item"><a href="{{route('admin.vouchers.index')}}">{{__('Vouchers')}}</a>
</li>
<li class="breadcrumb-item"><a class="text-muted"
href="{{route('admin.products.edit' , $voucher->id)}}">{{__('Edit')}}</a>
href="{{route('admin.vouchers.edit' , $voucher->id)}}">{{__('Edit')}}</a>
</li>
</ol>
</div>

View file

@ -140,8 +140,7 @@
<!-- /.card-header -->
<div class="card-body py-0 pb-2">
<ul class="list-group list-group-flush">
@foreach (Auth::user()->actions()->take(8)->orderBy('created_at', 'desc')->get()
as $log)
@foreach (Auth::user()->actions()->take(8)->orderBy('created_at', 'desc')->get() as $log)
<li class="list-group-item d-flex justify-content-between text-muted">
<span>
@if(str_starts_with($log->description,"created"))
@ -168,6 +167,80 @@
<!-- /.card-body -->
</div>
<!-- /.card -->
@if((config('SETTINGS::REFERRAL::ENABLED') ==true))<!--PartnerDiscount::getDiscount()--->
<div class="card card-default">
<div class="card-header">
<h3 class="card-title">
<i class="fas fa-handshake mr-2"></i>
{{ __('Partner program') }}
</h3>
</div>
<!-- /.card-header -->
<div class="card-body py-0 pb-2">
@if((config('SETTINGS::REFERRAL::ALLOWED') == "client" && Auth::user()->role != "member") || config('SETTINGS::REFERRAL::ALLOWED') == "everyone")
<div class="row">
<div class="mt-3 col-md-8">
<span class="badge badge-success" style="font-size: 14px">
<i class="fa fa-user-check mr-2"></i>
{{__("Your referral URL")}}:
<span onmouseover="hoverIn()" onmouseout="hoverOut()" onclick="onClickCopy()" id="RefLink" style="cursor: pointer;">
{{__('Click to copy')}}
</span>
</span>
</div>
<div class="mt-3 col-md-4">
<span class="badge badge-info" style="font-size: 14px">{{__("Number of referred users:")}} {{$numberOfReferrals}}</span>
</div>
</div>
@if($partnerDiscount)
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{__('Your discount')}}</th>
<th>{{__('Discount for your new users')}}</th>
<th>{{__('Reward per registered user')}}</th>
<th>{{__('New user payment commision')}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$partnerDiscount->partner_discount}}%</td>
<td>{{$partnerDiscount->registered_user_discount}}%</td>
<td>{{config('SETTINGS::REFERRAL::REWARD')}} {{config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME')}}</td>
<td>{{($partnerDiscount->referral_system_commission==-1)?config('SETTINGS::REFERRAL:PERCENTAGE'):($partnerDiscount->referral_system_commission)}}%</td>
</tr>
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@else
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-bottom: 0px">
<table class="table">
<thead>
<tr>
<th>{{__('Reward per registered user')}}</th>
<th>{{__('New user payment commision')}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{config('SETTINGS::REFERRAL::REWARD')}} {{config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME')}}</td>
<td>{{config('SETTINGS::REFERRAL:PERCENTAGE')}}%</td>
</tr>
</tbody>
</table>
<hr style="width: 100%; height:1px; border-width:0; background-color:#6c757d; margin-top: 0px">
@endif
@else
<span class="badge badge-warning"><i
class="fa fa-user-check mr-2"></i>
{{__("Make a purchase to reveal your referral-URL")}}</span>
@endif
</div>
<!-- /.card-body -->
</div>
@endif
<!-- /.card -->
</div>
<!-- /.col -->
@ -176,5 +249,41 @@
</div>
</section>
<!-- END CONTENT -->
<script>
var originalText = document.getElementById('RefLink').innerText;
var link = "<?php echo ((route("register")) . '?ref=' . (Auth::user()->referral_code));?>";
var timeoutID;
function hoverIn() {
document.getElementById('RefLink').innerText = link;
timeoutID = setTimeout(function() {
document.getElementById('RefLink').innerText = originalText;
}, 2000);
}
function hoverOut() {
document.getElementById('RefLink').innerText = originalText;
clearTimeout(timeoutID);
}
function onClickCopy() {
if(navigator.clipboard) {
navigator.clipboard.writeText(link).then(() => {
Swal.fire({
icon: 'success',
title: '{{ __("URL copied to clipboard")}}',
position: 'top-middle',
showConfirmButton: false,
background: '#343a40',
toast: false,
timer: 1000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
})
} else {
console.log('Browser Not compatible')
}
}
</script>
@endsection

View file

@ -330,6 +330,14 @@
</a>
</li>
<li class="nav-item">
<a href="{{ route('admin.partners.index') }}"
class="nav-link @if (Request::routeIs('admin.partners.*')) active @endif">
<i class="nav-icon fas fa-handshake"></i>
<p>{{ __('Partners') }}</p>
</a>
</li>
{{-- <li class="nav-header">Pterodactyl</li> --}}
{{-- <li class="nav-item"> --}}

View file

@ -107,18 +107,20 @@
<div class="table-responsive">
<table class="table">
@if($discountpercent&&$discountvalue)
<tr>
<th>{{ __('Discount') }} ({{ $discountpercent }}%):</th>
<td>{{$product->formatToCurrency($discountvalue)}}</td>
</tr>
@endif
<tr>
<th style="width:50%">{{ __('Subtotal') }}:</th>
<td>{{ $product->formatToCurrency($product->price) }}</td>
<td>{{ $product->formatToCurrency($discountedprice) }}</td>
</tr>
<tr>
<th>{{ __('Tax') }} ({{ $taxpercent }}%)</th>
<th>{{ __('Tax') }} ({{ $taxpercent }}%):</th>
<td>{{ $product->formatToCurrency($taxvalue) }}</td>
</tr>
<tr>
<th>{{ __('Quantity') }}:</th>
<td>1</td>
</tr>
<tr>
<th>{{ __('Total') }}:</th>
<td>{{ $product->formatToCurrency($total) }}</td>
@ -154,7 +156,6 @@
//loading
paymentMethod: '',
paymentRoute: '',
setPaymentRoute(provider) {
switch (provider) {
case 'paypal':
@ -167,12 +168,9 @@
this.paymentRoute = '{{ route('payment.PaypalPay', $product->id) }}';
}
},
}
}
</script>
@endsection
@endsection

View file

@ -30,6 +30,7 @@ use Illuminate\Support\Facades\Route;
use App\Classes\Settings\Language;
use App\Classes\Settings\Invoices;
use App\Classes\Settings\System;
use App\Http\Controllers\PartnerController;
/*
|--------------------------------------------------------------------------
@ -184,6 +185,11 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
Route::get('vouchers/{voucher}/users', [VoucherController::class, 'users'])->name('vouchers.users');
Route::resource('vouchers', VoucherController::class);
#partners
Route::get('partners/datatable', [PartnerController::class, 'datatable'])->name('partners.datatable');
Route::get('partners/{voucher}/users', [PartnerController::class, 'users'])->name('partners.users');
Route::resource('partners', PartnerController::class);
#api-keys
Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable');
Route::resource('api', ApplicationApiController::class)->parameters([
@ -209,4 +215,4 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () {
});
Route::get('/home', [HomeController::class, 'index'])->name('home');
});
});