VoucherController.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Events\UserUpdateCreditsEvent;
  4. use App\Http\Controllers\Controller;
  5. use App\Models\User;
  6. use App\Models\Voucher;
  7. use Illuminate\Contracts\Foundation\Application;
  8. use Illuminate\Contracts\View\Factory;
  9. use Illuminate\Contracts\View\View;
  10. use Illuminate\Http\JsonResponse;
  11. use Illuminate\Http\RedirectResponse;
  12. use Illuminate\Http\Request;
  13. use Illuminate\Http\Response;
  14. use Illuminate\Validation\ValidationException;
  15. class VoucherController extends Controller
  16. {
  17. /**
  18. * Display a listing of the resource.
  19. *
  20. * @return Application|Factory|View
  21. */
  22. public function index()
  23. {
  24. return view('admin.vouchers.index');
  25. }
  26. /**
  27. * Show the form for creating a new resource.
  28. *
  29. * @return Application|Factory|View
  30. */
  31. public function create()
  32. {
  33. return view('admin.vouchers.create');
  34. }
  35. /**
  36. * Store a newly created resource in storage.
  37. *
  38. * @param Request $request
  39. * @return RedirectResponse
  40. */
  41. public function store(Request $request)
  42. {
  43. $request->validate([
  44. 'memo' => 'nullable|string|max:191',
  45. 'code' => 'required|string|alpha_dash|max:36|min:4|unique:vouchers',
  46. 'uses' => 'required|numeric|max:2147483647|min:1',
  47. 'credits' => 'required|numeric|between:0,99999999',
  48. 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years',
  49. ]);
  50. Voucher::create($request->except('_token'));
  51. return redirect()->route('admin.vouchers.index')->with('success', __('voucher has been created!'));
  52. }
  53. /**
  54. * Display the specified resource.
  55. *
  56. * @param Voucher $voucher
  57. * @return Response
  58. */
  59. public function show(Voucher $voucher)
  60. {
  61. //
  62. }
  63. /**
  64. * Show the form for editing the specified resource.
  65. *
  66. * @param Voucher $voucher
  67. * @return Application|Factory|View
  68. */
  69. public function edit(Voucher $voucher)
  70. {
  71. return view('admin.vouchers.edit', [
  72. 'voucher' => $voucher,
  73. ]);
  74. }
  75. /**
  76. * Update the specified resource in storage.
  77. *
  78. * @param Request $request
  79. * @param Voucher $voucher
  80. * @return RedirectResponse
  81. */
  82. public function update(Request $request, Voucher $voucher)
  83. {
  84. $request->validate([
  85. 'memo' => 'nullable|string|max:191',
  86. 'code' => "required|string|alpha_dash|max:36|min:4|unique:vouchers,code,{$voucher->id}",
  87. 'uses' => 'required|numeric|max:2147483647|min:1',
  88. 'credits' => 'required|numeric|between:0,99999999',
  89. 'expires_at' => 'nullable|multiple_date_format:d-m-Y H:i:s,d-m-Y|after:now|before:10 years',
  90. ]);
  91. $voucher->update($request->except('_token'));
  92. return redirect()->route('admin.vouchers.index')->with('success', __('voucher has been updated!'));
  93. }
  94. /**
  95. * Remove the specified resource from storage.
  96. *
  97. * @param Voucher $voucher
  98. * @return RedirectResponse
  99. */
  100. public function destroy(Voucher $voucher)
  101. {
  102. $voucher->delete();
  103. return redirect()->back()->with('success', __('voucher has been removed!'));
  104. }
  105. public function users(Voucher $voucher)
  106. {
  107. return view('admin.vouchers.users', [
  108. 'voucher' => $voucher,
  109. ]);
  110. }
  111. /**
  112. * @param Request $request
  113. * @return JsonResponse
  114. *
  115. * @throws ValidationException
  116. */
  117. public function redeem(Request $request)
  118. {
  119. //general validations
  120. $request->validate([
  121. 'code' => 'required|exists:vouchers,code',
  122. ]);
  123. //get voucher by code
  124. $voucher = Voucher::where('code', '=', $request->input('code'))->firstOrFail();
  125. //extra validations
  126. if ($voucher->getStatus() == 'USES_LIMIT_REACHED') {
  127. throw ValidationException::withMessages([
  128. 'code' => __('This voucher has reached the maximum amount of uses'),
  129. ]);
  130. }
  131. if ($voucher->getStatus() == 'EXPIRED') {
  132. throw ValidationException::withMessages([
  133. 'code' => __('This voucher has expired'),
  134. ]);
  135. }
  136. if (! $request->user()->vouchers()->where('id', '=', $voucher->id)->get()->isEmpty()) {
  137. throw ValidationException::withMessages([
  138. 'code' => __('You already redeemed this voucher code'),
  139. ]);
  140. }
  141. if ($request->user()->credits + $voucher->credits >= 99999999) {
  142. throw ValidationException::withMessages([
  143. 'code' => "You can't redeem this voucher because you would exceed the limit of ".CREDITS_DISPLAY_NAME,
  144. ]);
  145. }
  146. //redeem voucher
  147. $voucher->redeem($request->user());
  148. event(new UserUpdateCreditsEvent($request->user()));
  149. return response()->json([
  150. 'success' => "{$voucher->credits} ".CREDITS_DISPLAY_NAME.' '.__('have been added to your balance!'),
  151. ]);
  152. }
  153. public function usersDataTable(Voucher $voucher)
  154. {
  155. $users = $voucher->users();
  156. return datatables($users)
  157. ->editColumn('name', function (User $user) {
  158. return '<a class="text-info" target="_blank" href="'.route('admin.users.show', $user->id).'">'.$user->name.'</a>';
  159. })
  160. ->addColumn('credits', function (User $user) {
  161. return '<i class="fas fa-coins mr-2"></i> '.$user->credits();
  162. })
  163. ->addColumn('last_seen', function (User $user) {
  164. return $user->last_seen ? $user->last_seen->diffForHumans() : '';
  165. })
  166. ->rawColumns(['name', 'credits', 'last_seen'])
  167. ->make();
  168. }
  169. public function dataTable()
  170. {
  171. $query = Voucher::query();
  172. return datatables($query)
  173. ->addColumn('actions', function (Voucher $voucher) {
  174. return '
  175. <a data-content="'.__('Users').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.users', $voucher->id).'" class="btn btn-sm btn-primary mr-1"><i class="fas fa-users"></i></a>
  176. <a data-content="'.__('Edit').'" data-toggle="popover" data-trigger="hover" data-placement="top" href="'.route('admin.vouchers.edit', $voucher->id).'" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
  177. <form class="d-inline" onsubmit="return submitResult();" method="post" action="'.route('admin.vouchers.destroy', $voucher->id).'">
  178. '.csrf_field().'
  179. '.method_field('DELETE').'
  180. <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>
  181. </form>
  182. ';
  183. })
  184. ->addColumn('status', function (Voucher $voucher) {
  185. $color = 'success';
  186. if ($voucher->getStatus() != __('VALID')) {
  187. $color = 'danger';
  188. }
  189. return '<span class="badge badge-'.$color.'">'.$voucher->getStatus().'</span>';
  190. })
  191. ->editColumn('uses', function (Voucher $voucher) {
  192. return "{$voucher->used} / {$voucher->uses}";
  193. })
  194. ->editColumn('credits', function (Voucher $voucher) {
  195. return number_format($voucher->credits, 2, '.', '');
  196. })
  197. ->editColumn('expires_at', function (Voucher $voucher) {
  198. if (! $voucher->expires_at) {
  199. return '';
  200. }
  201. return $voucher->expires_at ? $voucher->expires_at->diffForHumans() : '';
  202. })
  203. ->editColumn('code', function (Voucher $voucher) {
  204. return "<code>{$voucher->code}</code>";
  205. })
  206. ->rawColumns(['actions', 'code', 'status'])
  207. ->make();
  208. }
  209. }