Exemplo n.º 1
0
 /**
  * @throws \InvalidArgumentException
  *
  * @return Collection|PotentialOffer[]
  */
 private function collect() : Collection
 {
     /*
      * Create buckets for each offer, keeping duplicate offers.
      * Assign each product to the first applicable bucket with spaces left.
      * Filter the buckets to those that are full.
      */
     return $this->components->sort(function (OfferComponent $a, OfferComponent $b) {
         $priceA = $a->product()->price()->asFloat();
         $priceB = $b->product()->price()->asFloat();
         return $priceA <=> $priceB;
     })->reduce(function (Collection $potentials, OfferComponent $component) {
         $potentials->first(function (PotentialOffer $potential) use($component) {
             return $potential->takeComponent($component);
         });
         return $potentials;
     }, $this->potentials())->filter(function (PotentialOffer $offer) {
         return $offer->requirementsAreMet();
     })->sort(function (PotentialOffer $offer) {
         return $offer->linePrice()->negative()->amount();
     });
 }