query('filter', '')); $paginator = Coupon::query() ->withCount('activeRedemptions as used_count') ->withSum('activeRedemptions as discounted_total', 'amount') ->when($search !== '', fn ($q) => $q->where(fn ($w) => $w ->where('code', 'like', "%{$search}%") ->orWhere('name', 'like', "%{$search}%"))) ->orderByDesc('id') ->paginate(min((int) $request->query('per_page', 15), 100)); return response()->json([ 'error' => false, 'data' => $paginator->items(), 'meta' => [ 'total' => $paginator->total(), 'per_page' => $paginator->perPage(), 'current_page' => $paginator->currentPage(), ], 'product_types' => array_map( fn (ProductTypeEnums $type) => ['value' => $type->value, 'label' => $type->label()], ProductTypeEnums::cases(), ), ]); } public function store(CouponRequest $request): JsonResponse { $coupon = Coupon::create($request->validated()); return response()->json(['error' => false, 'message' => 'Đã tạo mã giảm giá.', 'data' => $coupon], 201); } public function update(CouponRequest $request, int $id): JsonResponse { $coupon = Coupon::findOrFail($id); $coupon->update($request->validated()); return response()->json(['error' => false, 'message' => 'Đã cập nhật mã giảm giá.', 'data' => $coupon->fresh()]); } public function destroy(int $id): JsonResponse { $coupon = Coupon::findOrFail($id); if ($coupon->redemptions()->exists()) { return response()->json([ 'error' => true, 'message' => 'Mã đã được sử dụng, không thể xoá. Hãy tắt mã thay vì xoá.', ], 422); } $coupon->delete(); return response()->json(['error' => false, 'message' => 'Đã xoá mã giảm giá.']); } }