Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
60.00% |
18 / 30 |
|
28.57% |
2 / 7 |
CRAP | |
0.00% |
0 / 1 |
| CouponController | |
60.00% |
18 / 30 |
|
28.57% |
2 / 7 |
10.14 | |
0.00% |
0 / 1 |
| index | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
| create | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| store | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| edit | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| update | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| destroy | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| validated | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Http\Controllers\admin; |
| 4 | |
| 5 | use App\Http\Controllers\Controller; |
| 6 | use App\Models\Coupon; |
| 7 | use Illuminate\Http\RedirectResponse; |
| 8 | use Illuminate\Http\Request; |
| 9 | use Illuminate\Validation\Rule; |
| 10 | use Illuminate\View\View; |
| 11 | |
| 12 | /** |
| 13 | * Sales → Coupons. Percent / fixed discount codes with windows, limits and a |
| 14 | * minimum order. Gated by the `coupons` feature. |
| 15 | */ |
| 16 | class CouponController extends Controller |
| 17 | { |
| 18 | public function index(Request $request): View |
| 19 | { |
| 20 | $coupons = Coupon::query() |
| 21 | ->when($request->filled('search'), fn ($q) => $q->where('code', 'like', '%' . $request->input('search') . '%')) |
| 22 | ->latest() |
| 23 | ->paginate(20) |
| 24 | ->withQueryString(); |
| 25 | |
| 26 | return view('admin.coupons.index', compact('coupons')); |
| 27 | } |
| 28 | |
| 29 | public function create(): View |
| 30 | { |
| 31 | return view('admin.coupons.form', ['coupon' => new Coupon(['type' => 'percent', 'is_active' => true])]); |
| 32 | } |
| 33 | |
| 34 | public function store(Request $request): RedirectResponse |
| 35 | { |
| 36 | Coupon::create($this->validated($request)); |
| 37 | |
| 38 | return redirect()->route('admin.coupons.index')->with('success', 'Coupon created.'); |
| 39 | } |
| 40 | |
| 41 | public function edit(Coupon $coupon): View |
| 42 | { |
| 43 | return view('admin.coupons.form', compact('coupon')); |
| 44 | } |
| 45 | |
| 46 | public function update(Request $request, Coupon $coupon): RedirectResponse |
| 47 | { |
| 48 | $coupon->update($this->validated($request, $coupon)); |
| 49 | |
| 50 | return redirect()->route('admin.coupons.index')->with('success', 'Coupon updated.'); |
| 51 | } |
| 52 | |
| 53 | public function destroy(Coupon $coupon): RedirectResponse |
| 54 | { |
| 55 | $coupon->delete(); |
| 56 | |
| 57 | return redirect()->route('admin.coupons.index')->with('success', 'Coupon deleted.'); |
| 58 | } |
| 59 | |
| 60 | private function validated(Request $request, ?Coupon $coupon = null): array |
| 61 | { |
| 62 | $data = $request->validate([ |
| 63 | 'code' => ['required', 'string', 'max:40', Rule::unique('coupons', 'code')->ignore($coupon)], |
| 64 | 'type' => ['required', Rule::in(['percent', 'fixed'])], |
| 65 | 'value' => ['required', 'numeric', 'min:0'], |
| 66 | 'min_order' => ['nullable', 'numeric', 'min:0'], |
| 67 | 'max_discount' => ['nullable', 'numeric', 'min:0'], |
| 68 | 'usage_limit' => ['nullable', 'integer', 'min:1'], |
| 69 | 'per_customer_limit' => ['nullable', 'integer', 'min:1'], |
| 70 | 'starts_at' => ['nullable', 'date'], |
| 71 | 'ends_at' => ['nullable', 'date', 'after_or_equal:starts_at'], |
| 72 | 'description' => ['nullable', 'string', 'max:255'], |
| 73 | 'is_active' => ['nullable', 'boolean'], |
| 74 | ]); |
| 75 | |
| 76 | $data['is_active'] = $request->boolean('is_active'); |
| 77 | $data['code'] = strtoupper(trim($data['code'])); |
| 78 | |
| 79 | return $data; |
| 80 | } |
| 81 | } |