laravelshoppingcart
laravelshoppingcart copied to clipboard
check if user already used coupon code
Hi,
I have trouble with checking if user already used coupon code, currently user can use same coupon code over and over.
How can I check if user already used any coupon code once then stop him of using it for second time?
here is my update function:
public function update(Request $request, $id)
{
// quantity
$qty = $request->input('quantity');
$products = Product::findOrFail($request->proId);
$stock = $products->stock;
$mytime = Carbon::now();
$couponcode = $request->input('coupon');
$userId = Auth::user()->id;
$catId = Coupon::where('category_id', $products->category_id)
->where('value_to', '>=', $mytime)
->when($couponcode, function ($query) use ($couponcode) {
return $query->where('title', $couponcode);
})
->first();
if (!empty($qty) && !empty($couponcode)) { // 1. if both (quantity and couponcode) are given
if ($qty < $stock && (!is_null($catId) && $catId->title == $couponcode)) { // if quantity < stock AND coupon-code is correct
$coupon = new \Darryldecode\Cart\CartCondition(array(
'name' => $catId->title,
'type' => 'coupon',
'target' => 'item',
'value' => -$catId->amount,
));
Cart::update($id, array(
'quantity' => array(
'relative' => false,
'value' => $qty,
),
));
Cart::addItemCondition($id, $coupon);
Session::flash('success', 'Cart updated.');
return redirect()->route('cart.index');
} elseif ($qty > $stock) {
Session::flash('danger', 'quantity not available!');
return redirect()->route('cart.index');
} else {
Session::flash('danger', 'invalid coupon code!');
return redirect()->route('cart.index');
}
} elseif (!empty($qty)) { // 2. if just quantity is given
if ($qty < $stock) {
Cart::update($id, array(
'quantity' => array(
'relative' => false,
'value' => $qty,
),
));
Session::flash('success', 'Cart updated.');
return redirect()->route('cart.index');
} else {
Session::flash('danger', 'quantity not available!');
return redirect()->route('cart.index');
}
} elseif (!empty($couponcode)) { // 3. if just couponcode is given
if (!is_null($catId) && $catId->title == $couponcode) {
$coupon = new \Darryldecode\Cart\CartCondition(array(
'name' => $catId->title,
'type' => 'coupon',
'target' => 'item',
'value' => -$catId->amount,
));
// Cart::addItemCondition($id, $coupon);
Cart::session($userId)->addItemCondition($id, $coupon);
Session::flash('success', 'Coupon applied successfully.');
return redirect()->route('cart.index');
} else {
Session::flash('danger', 'invalid coupon code!');
return redirect()->route('cart.index');
}
} else{ // 1. if nothing is given
Session::flash('danger', 'Your request cannot be handle, please try again!');
return redirect()->route('cart.index');
}
}
thanks.
I dont know how is your coupon table in database, but my sugestion is to create a table named "coupon_user" with a column named "uses" and another with "user_id", and then, when you use a coupon, you subtract the value by -1 until reaches to 0, after that the only thing you need is making validations to disallow the user to use again the coupon when the "uses" have reached to 0.
Hope it helps! :D
You should be doing this check in a validator. Reiterating what @DSPNeves has said, you could have a form request class like this
<?php
namespace App\Http\Requests;
use App\Coupon;
use Illuminate\Foundation\Http\FormRequest;
class ApplyCouponToShoppingCartRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'coupon_code' => ['required', 'string'],
];
}
/**
* Configure the validator instance.
*
* @param \Illuminate\Validation\Validator $validator
*/
public function withValidator($validator)
{
$validator->after(function ($validator) {
$coupon = Coupon::whereCode($this->input('coupon_code'))->first();
if (!$coupon) {
return $validator->errors()->add('coupon_code', 'The coupon code is invalid.');
}
if ($this->usedByUser($coupon)) {
return $validator->errors()->add('coupon_code', 'This coupon has been used by your account.');
}
if ($this->numberOfUsersExceeded($coupon)) {
return $validator->errors()->add('coupon_code', 'Coupon number of users exceeded.');
}
});
}
private function usedByUser($coupon)
{
return $coupon->users()->where('user_id', auth()->id())->exists() ? true : false;
}
private function numberOfUsersExceeded($coupon)
{
$coupon->loadCount('users');
return ($coupon->users_count + 1) > $coupon->no_of_users ? true : false;
}
}