I have cart system and everything works just fine, the only issue that i have is; that each user can use same coupon code over and over.
What I want is to limit each user to be able to use each coupon only once, and if user have more than one coupon code only be able to use one of them.
this is my cart update function where my cart will be update with coupon codes etc.
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');
$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);
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');
}
}
I came up with this query in order to get my cart items conditions name
$cartItems = Cart::getContent();
foreach($cartItems as $item)
{
if(is_array($item['conditions']) && !empty($item['conditions'])) {
$temp = [];
foreach($item['conditions'] as $key => $value)
{
$temp[]=[
'name' => $value->getName(),
];
}
$item['_conditions'] = $temp;
foreach($item['_conditions'] as $itessm)
{
$copname[] = $itessm['name'];
}
}
}
now $copname
is conditions names which are stored in my cart session, I need to change my function (above) in order to compare input coupon and see if is exist in my conditions or not, if not let user add it, but is already exist return error.
something like:
if( $couponcode == $copname )
any idea?
I changed my code to:
$cartItems = Cart::getContent();
foreach($cartItems as $item)
{
if(is_array($item['conditions']) && !empty($item['conditions'])) {
$temp = [];
foreach($item['conditions'] as $key )
{
$temp[] = $key['name'];
}
}
}
And I get results like:
if no condition exist: []
if conditions exist: array 2: 0 => 'xxxx', and so on
then I changed my update function like:
$cartItems = Cart::getContent();
foreach($cartItems as $item)
{
if(is_array($item['conditions']) && !empty($item['conditions'])) {
$temp = [];
foreach($item['conditions'] as $key )
{
// $temp[] = $key['name'];
$temp[] = $key['name'];
}
$item['_conditions'] = $temp;
}
}
//this IF has added
if($couponcode == $item['_conditions']){
Session::flash('danger', 'You already used this coupon, you cannot use it again!');
return redirect()->route('cart.index');
}else{
$catId = Coupon::where('category_id', $products->category_id)
->where('value_to', '>=', $mytime)
->when($couponcode, function ($query) use ($couponcode) {
return $query->where('title', $couponcode);
})
->first();
}
now the problem here is that i get this error:
Cannot use object of type Darryldecode\Cart\CartCondition as array
anyone?
You should make it so users can only use a coupon after they have been logged in.
Once they use the coupon, then simply store it to the database, and associate it w/their user account.
When they get to the coupon entry page, once they enter their coupon details, make a ajax call and check to see if the coupon is valid for them to use.
If the application you are working on is software that is out of the box, I personally would create a table called UsedCoupon and give it a minimum of 2 columns which are UserId and CouponCode. I would store my used codes there.
If the application is being created from scratch, you might be able to get away w/storing the used coupon data in a more denormalized manner.