diff --git a/app/Http/Controllers/Admin/VoucherController.php b/app/Http/Controllers/Admin/VoucherController.php new file mode 100644 index 00000000..9d439f4a --- /dev/null +++ b/app/Http/Controllers/Admin/VoucherController.php @@ -0,0 +1,142 @@ +validate([ + 'memo' => 'sometimes|string|max:191', + 'code' => 'required|string|alpha_dash|max:36', + 'uses' => 'required|numeric|max:2147483647', + 'credits' => 'required|numeric|between:0,99999999', + 'expires_at' => 'required|date|after:today', + ]); + + Voucher::create($request->except('_token')); + + return redirect()->route('admin.vouchers.index')->with('success', 'voucher 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 Response + */ + public function edit(Voucher $voucher) + { + // + } + + /** + * Update the specified resource in storage. + * + * @param Request $request + * @param Voucher $voucher + * @return Response + */ + public function update(Request $request, Voucher $voucher) + { + // + } + + /** + * Remove the specified resource from storage. + * + * @param Voucher $voucher + * @return RedirectResponse + */ + public function destroy(Voucher $voucher) + { + $voucher->delete(); + return redirect()->back()->with('success', 'voucher has been removed!'); + } + + public function dataTable() + { + $query = Voucher::with(['users']); + + return datatables($query) + ->addColumn('actions', function (Voucher $voucher) { + return ' + + + +
+ ' . csrf_field() . ' + ' . method_field("DELETE") . ' + +
+ '; + }) + ->addColumn('status', function (Voucher $voucher) { + $color = 'success'; + if ($voucher->getStatus() != 'VALID') $color = 'danger'; + return ''. $voucher->getStatus() .''; + }) + ->editColumn('uses', function (Voucher $voucher) { + $userCount = $voucher->users()->count(); + return "{$userCount} / {$voucher->uses}"; + }) + ->editColumn('credits', function (Voucher $voucher) { + return number_format($voucher->credits, 2, '.', ''); + }) + ->editColumn('expires_at', function (Voucher $voucher) { + return $voucher->expires_at ? $voucher->expires_at->diffForHumans() : ''; + }) + ->editColumn('code' , function (Voucher $voucher) { + return "{$voucher->code}"; + }) + ->rawColumns(['actions' , 'code' , 'status']) + ->make(); + } + +} diff --git a/app/Models/Voucher.php b/app/Models/Voucher.php new file mode 100644 index 00000000..9071a9a2 --- /dev/null +++ b/app/Models/Voucher.php @@ -0,0 +1,57 @@ +users()->detach(); + }); + } + + public function getStatus(){ + if ($this->users()->count() >= $this->uses) return 'USES_LIMIT_REACHED'; + if ($this->expires_at->isPast()) return 'EXPIRED'; + return 'VALID'; + } + + /** + * @return BelongsToMany + */ + public function users() + { + return $this->belongsToMany(User::class); + } +} diff --git a/database/factories/VoucherFactory.php b/database/factories/VoucherFactory.php new file mode 100644 index 00000000..4f4a2f2b --- /dev/null +++ b/database/factories/VoucherFactory.php @@ -0,0 +1,29 @@ + $this->faker->numberBetween(100, 1000), + 'expires_at' => $this->faker->dateTimeBetween(now(), '+30 days') + ]; + } +} diff --git a/database/migrations/2021_07_09_190453_create_vouchers_table.php b/database/migrations/2021_07_09_190453_create_vouchers_table.php new file mode 100644 index 00000000..30a58d92 --- /dev/null +++ b/database/migrations/2021_07_09_190453_create_vouchers_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('code', 36)->unique(); + $table->string('memo')->nullable(); + $table->unsignedFloat('credits', 10); + $table->unsignedInteger('uses')->default(1); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('vouchers'); + } +} diff --git a/database/migrations/2021_07_09_191913_create_user_voucher_table.php b/database/migrations/2021_07_09_191913_create_user_voucher_table.php new file mode 100644 index 00000000..b75f7d26 --- /dev/null +++ b/database/migrations/2021_07_09_191913_create_user_voucher_table.php @@ -0,0 +1,32 @@ +foreignId('user_id')->constrained(); + $table->foreignId('voucher_id')->constrained(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_voucher'); + } +} diff --git a/resources/views/admin/users/edit.blade.php b/resources/views/admin/users/edit.blade.php index 59988edf..0148cb9a 100644 --- a/resources/views/admin/users/edit.blade.php +++ b/resources/views/admin/users/edit.blade.php @@ -72,7 +72,7 @@
@error('credits') diff --git a/resources/views/admin/vouchers/create.blade.php b/resources/views/admin/vouchers/create.blade.php index 2a29bbe8..33b875a2 100644 --- a/resources/views/admin/vouchers/create.blade.php +++ b/resources/views/admin/vouchers/create.blade.php @@ -6,12 +6,12 @@
-

Products

+

Vouchers

@@ -28,163 +28,94 @@
+
+
+ Voucher details +
+
-
+ @csrf -
-
- - + +
+ + + @error('memo') +
+ {{$message}}
+ @enderror
-
-
-
- - - @error('name') -
- {{$message}} -
- @enderror -
- -
- - - @error('price') -
- {{$message}} -
- @enderror -
- -
- - - @error('memory') -
- {{$message}} -
- @enderror -
- -
- - - @error('cpu') -
- {{$message}} -
- @enderror -
- -
- - - @error('swap') -
- {{$message}} -
- @enderror -
- -
- - - @error('description') -
- {{$message}} -
- @enderror -
- -
-
-
- - - @error('disk') -
- {{$message}} -
- @enderror -
-
- - - @error('io') -
- {{$message}} -
- @enderror -
-
- - - @error('databases') -
- {{$message}} -
- @enderror -
-
- - - @error('backups') -
- {{$message}} -
- @enderror -
-
- - - @error('allocations') -
- {{$message}} -
- @enderror -
+
+ + + @error('credits') +
+ {{$message}}
+ @enderror
+ +
+ +
+ +
+ +
+
+ @error('code') +
+ {{$message}} +
+ @enderror +
+ +
+ +
+ +
+ +
+
+ @error('uses') +
+ {{$message}} +
+ @enderror +
+ + +
+ + + @error('expires_at') +
+ {{$message}} +
+ @enderror +
+ +
@@ -34,12 +34,13 @@
- + @csrf + @method('PATCH')
- @error('memo') @@ -51,7 +52,7 @@
- @@ -66,7 +67,7 @@
- @@ -86,7 +87,7 @@
- @@ -105,7 +106,7 @@
- @error('expires_at') diff --git a/resources/views/admin/vouchers/index.blade.php b/resources/views/admin/vouchers/index.blade.php index 183e2793..bfe4cef6 100644 --- a/resources/views/admin/vouchers/index.blade.php +++ b/resources/views/admin/vouchers/index.blade.php @@ -6,13 +6,13 @@
-

Products

+

Vouchers

@@ -28,8 +28,8 @@
-
Products
- Vouchers + Create new
@@ -39,19 +39,12 @@ - - - - - - - - - - - - - + + + + + + @@ -79,21 +72,14 @@ processing: true, serverSide: true, stateSave: true, - ajax: "{{route('admin.products.datatable')}}", + ajax: "{{route('admin.vouchers.datatable')}}", columns: [ - {data: 'disabled'}, - {data: 'name'}, - {data: 'price'}, - {data: 'memory'}, - {data: 'cpu'}, - {data: 'swap'}, - {data: 'disk'}, - {data: 'io'}, - {data: 'databases'}, - {data: 'backups'}, - {data: 'allocations'}, - {data: 'servers', sortable: false}, - {data: 'created_at'}, + {data: 'status'}, + {data: 'code'}, + {data: 'memo'}, + {data: 'credits'}, + {data: 'uses'}, + {data: 'expires_at'}, {data: 'actions', sortable: false}, ], fnDrawCallback: function( oSettings ) { diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index 5cfa4957..6cbbfea1 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -96,6 +96,10 @@ Log back in @endif + + + Redeem code + @csrf @@ -253,6 +257,14 @@ + + - @endif @@ -289,6 +300,8 @@ @endif @yield('content') + + @include('models.redeem_voucher_modal')
@@ -319,6 +332,12 @@ diff --git a/routes/web.php b/routes/web.php index 598b09d8..7313c70f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -12,6 +12,7 @@ use App\Http\Controllers\Admin\ServerController as AdminServerController; use App\Http\Controllers\Admin\SettingsController; use App\Http\Controllers\Admin\UsefulLinkController; use App\Http\Controllers\Admin\UserController; +use App\Http\Controllers\Admin\VoucherController; use App\Http\Controllers\Auth\SocialiteController; use App\Http\Controllers\HomeController; use App\Http\Controllers\NotificationController; @@ -110,6 +111,9 @@ Route::middleware('auth')->group(function () { Route::get('usefullinks/datatable', [UsefulLinkController::class, 'datatable'])->name('usefullinks.datatable'); Route::resource('usefullinks', UsefulLinkController::class); + Route::get('vouchers/datatable', [VoucherController::class, 'datatable'])->name('vouchers.datatable'); + Route::resource('vouchers', VoucherController::class); + Route::get('api/datatable', [ApplicationApiController::class, 'datatable'])->name('api.datatable'); Route::resource('api', ApplicationApiController::class)->parameters([ 'api' => 'applicationApi',
ActiveNamePriceMemoryCpuSwapDiskIODatabasesBackupsAllocationsServersCreated atStatusCodeMemoCreditsUsed / UsesExpires