has('products'))) { $flashSale->saveProducts(request('products')); } }); } /** * Get the active flash sale. * * @param int $id * @return self */ public static function active() { if (is_callable(self::$active)) { return call_user_func(self::$active); } return new self; } /** * Set an active flash sale campaign. * * @param int $id * @return void */ public static function activeCampaign($id) { self::$active = function () use ($id) { return once(function () use ($id) { return self::withEligibleProducts()->where('id', $id)->firstOrNew([]); }); }; } public static function contains(Product $product) { return self::active()->products->contains($product); } public static function pivot(Product $product) { return self::active()->products->find($product)->pivot; } public static function remainingQty(Product $product) { $flashSaleProduct = self::pivot($product); return $flashSaleProduct->qty - $flashSaleProduct->sold; } public function scopeWithEligibleProducts($query) { $query->with(['products' => function ($query) { $query->forCard()->wherePivot('end_date', '>', now()); }]); } public function products() { return $this->belongsToMany(Product::class, 'flash_sale_products') ->using(FlashSaleProduct::class) ->withPivot(['id', 'end_date', 'price', 'qty']) ->orderBy('position'); } public function getPriceAttribute($price) { return Money::inDefaultCurrency($price); } public function saveProducts($products) { $this->products()->sync( $this->buildProductPivots($products) ); } private function buildProductPivots($products) { return collect($products)->values()->mapWithKeys(function ($attributes, $index) { return [$attributes['product_id'] => [ 'end_date' => $attributes['end_date'], 'price' => $attributes['price'], 'qty' => $attributes['qty'], 'position' => $index, ]]; }); } public function table() { return new AdminTable($this->query()); } }