Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 59 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
| CouponController | |
0.00% |
0 / 59 |
|
0.00% |
0 / 5 |
90 | |
0.00% |
0 / 1 |
| index | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
| store | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
6 | |||
| update | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
| destroy | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| ensureCouponBelongsToCurrentStore | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Http\Controllers\Admin; |
| 4 | |
| 5 | use App\Enums\CouponStatus; |
| 6 | use App\Http\Controllers\Concerns\ResolvesContext; |
| 7 | use App\Http\Controllers\Controller; |
| 8 | use App\Models\Influencer; |
| 9 | use App\Models\InfluencerCoupon; |
| 10 | use App\Models\StoreIntegration; |
| 11 | use App\Services\Nuvemshop\NuvemshopCouponService; |
| 12 | use Illuminate\Http\RedirectResponse; |
| 13 | use Illuminate\Http\Request; |
| 14 | use Illuminate\Validation\Rule; |
| 15 | use Illuminate\View\View; |
| 16 | use RuntimeException; |
| 17 | |
| 18 | class CouponController extends Controller |
| 19 | { |
| 20 | use ResolvesContext; |
| 21 | |
| 22 | public function index(): View |
| 23 | { |
| 24 | $store = $this->currentStore(); |
| 25 | |
| 26 | return view('admin.coupons.index', [ |
| 27 | 'coupons' => InfluencerCoupon::with(['influencer', 'orders']) |
| 28 | ->where('store_id', $store->id) |
| 29 | ->latest() |
| 30 | ->paginate(20), |
| 31 | 'influencers' => Influencer::where('store_id', $store->id) |
| 32 | ->where('status', 'active') |
| 33 | ->orderBy('name') |
| 34 | ->get(), |
| 35 | ]); |
| 36 | } |
| 37 | |
| 38 | public function store(Request $request, NuvemshopCouponService $service): RedirectResponse |
| 39 | { |
| 40 | $data = $request->validate([ |
| 41 | 'influencer_id' => ['required', 'exists:influencers,id'], |
| 42 | 'coupon_code_original' => ['required', 'alpha_num', 'max:80'], |
| 43 | 'discount_percentage' => ['required', 'numeric', 'min:0.01', 'max:100'], |
| 44 | ]); |
| 45 | |
| 46 | $influencer = Influencer::findOrFail($data['influencer_id']); |
| 47 | |
| 48 | $integration = StoreIntegration::query() |
| 49 | ->where('store_id', $influencer->store_id) |
| 50 | ->whereHas('provider', fn ($q) => $q->where('slug', 'nuvemshop')) |
| 51 | ->firstOrFail(); |
| 52 | |
| 53 | try { |
| 54 | $service->createForInfluencer( |
| 55 | $influencer, |
| 56 | $integration, |
| 57 | $data['coupon_code_original'], |
| 58 | (float) $data['discount_percentage'] |
| 59 | ); |
| 60 | } catch (RuntimeException $exception) { |
| 61 | return back() |
| 62 | ->withInput() |
| 63 | ->withErrors(['coupon' => $exception->getMessage()]); |
| 64 | } |
| 65 | |
| 66 | return back()->with('success', 'Cupom criado/vinculado com sucesso.'); |
| 67 | } |
| 68 | |
| 69 | public function update(Request $request, InfluencerCoupon $coupon, NuvemshopCouponService $service): RedirectResponse |
| 70 | { |
| 71 | $this->ensureCouponBelongsToCurrentStore($coupon); |
| 72 | |
| 73 | $data = $request->validate([ |
| 74 | 'coupon_code_original' => ['required', 'alpha_num', 'max:80'], |
| 75 | 'discount_percentage' => ['required', 'numeric', 'min:0.01', 'max:100'], |
| 76 | 'status' => ['required', Rule::in([ |
| 77 | CouponStatus::Active->value, |
| 78 | CouponStatus::Inactive->value, |
| 79 | ])], |
| 80 | ]); |
| 81 | |
| 82 | try { |
| 83 | $service->updateCoupon( |
| 84 | $coupon, |
| 85 | $data['coupon_code_original'], |
| 86 | (float) $data['discount_percentage'], |
| 87 | CouponStatus::from($data['status']) |
| 88 | ); |
| 89 | } catch (RuntimeException $exception) { |
| 90 | return back() |
| 91 | ->withInput() |
| 92 | ->withErrors(['coupon' => $exception->getMessage()]); |
| 93 | } |
| 94 | |
| 95 | return back()->with('success', 'Cupom atualizado na Nuvemshop e no Orvox.'); |
| 96 | } |
| 97 | |
| 98 | public function destroy(InfluencerCoupon $coupon, NuvemshopCouponService $service): RedirectResponse |
| 99 | { |
| 100 | $this->ensureCouponBelongsToCurrentStore($coupon); |
| 101 | |
| 102 | try { |
| 103 | $service->deleteCoupon($coupon); |
| 104 | } catch (RuntimeException $exception) { |
| 105 | return back()->withErrors(['coupon' => $exception->getMessage()]); |
| 106 | } |
| 107 | |
| 108 | return back()->with('success', 'Cupom excluído na Nuvemshop e marcado como excluído no Orvox.'); |
| 109 | } |
| 110 | |
| 111 | private function ensureCouponBelongsToCurrentStore(InfluencerCoupon $coupon): void |
| 112 | { |
| 113 | if ((int) $coupon->store_id !== (int) $this->currentStore()->id) { |
| 114 | abort(404); |
| 115 | } |
| 116 | } |
| 117 | } |