Helen Che
Helen Che

Reputation: 2011

Sum total items in multiple shopping carts using Laravel collection methods

Say I have a shopping cart with relationship:

public function items()
{
  return $this->belongsToMany(Item::class, 'cart_item', 'cart_id', 'item_id')->withPivot('quantity');
}

Say I have multiple $carts with each $cart->items and I want to generate a list of all items in this cart with summation on pivot.quantity.

e.g:

[
  {'item': Apple, 'pivot.quantity': 2},
  {'item': Orange, 'pivot.quantity': 1},
]

[
  {'item': Apple, 'pivot.quantity': 4},
  {'item': Banana, 'pivot.quantity': 1},
]

Will produce

[
  {'item': Apple, 'pivot.quantity': 6},
  {'item': Banana, 'pivot.quantity': 1},
  {'item': Orange, 'pivot.quantity': 1},
]

My thought would be first to iterate through all $carts to produce a list like this:

[$cart[0]->items[0], $cart[0]->items[1], …, $cart[n]->items[n]]

Is it possible to achieve something like this in one line?

Then summation would be a trivial groupBy('item') followed with appropriate sum.

Upvotes: 1

Views: 757

Answers (1)

oseintow
oseintow

Reputation: 7381

This should work

 $carts = [
   // this is your array;
 ];    

 $newCart = collect($carts)->flatten(1)->groupBy("item")->map(function($q){
    $item = $q->first()['item'];

    $quantity = $q->reduce(function($carry, $item){
        // Use this, as your quantity is not an object 
        // of pivot 
        return $carry + $item['pivot.quantity'];
        // use this if quantity is an object of pivot
        return $carry + $item['pivot']['quantity'];
    });

    return compact("item","quantity");
})->values();

Hope it helps.

Upvotes: 1

Related Questions