瀏覽代碼

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

Partners and discounts
Dennis 2 年之前
父節點
當前提交
8b8d73c3b2

+ 2 - 0
app/Classes/Settings/Misc.php

@@ -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"
 

+ 65 - 26
app/Http/Controllers/Admin/OverViewController.php

@@ -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,

+ 38 - 17
app/Http/Controllers/Admin/PaymentController.php

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

+ 4 - 3
app/Http/Controllers/Admin/UserController.php

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

+ 6 - 1
app/Http/Controllers/HomeController.php

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

+ 206 - 0
app/Http/Controllers/PartnerController.php

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

+ 41 - 0
app/Models/PartnerDiscount.php

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

+ 8 - 3
app/Models/ShopProduct.php

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

+ 35 - 0
database/migrations/2022_08_25_202109_create_partner_discounts_table.php

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

+ 7 - 0
database/seeders/Seeds/SettingsSeeder.php

@@ -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',
         ], [

+ 101 - 27
resources/views/admin/overview/index.blade.php

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

+ 139 - 0
resources/views/admin/partners/create.blade.php

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

+ 158 - 0
resources/views/admin/partners/edit.blade.php

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

+ 94 - 0
resources/views/admin/partners/index.blade.php

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

+ 2 - 0
resources/views/admin/payments/index.blade.php

@@ -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'},

+ 14 - 0
resources/views/admin/settings/tabs/misc.blade.php

@@ -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"

+ 2 - 2
resources/views/admin/users/index.blade.php

@@ -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 ) {

+ 1 - 1
resources/views/admin/vouchers/create.blade.php

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

+ 1 - 1
resources/views/admin/vouchers/edit.blade.php

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

+ 112 - 3
resources/views/home.blade.php

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

+ 8 - 0
resources/views/layouts/main.blade.php

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

+ 9 - 11
resources/views/store/checkout.blade.php

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

+ 7 - 1
routes/web.php

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