/** * Place a bid. * * @param \Illuminate\Http\Request $request * * @return \Illuminate\Http\RedirectResponse */ public function postBid(Request $request) { $item = Item::findOrFail($request->input('item_id')); if ($item->seller->userId == Auth::user()->userId) { return redirect()->back()->withErrors(['You cannot bid on your own items.']); } if (time() < $item->startDate) { return redirect()->back()->withErrors(['This item is not yet open for bidding.']); } if (time() > $item->endDate) { return redirect()->back()->withErrors(['This item has ended and cannot be bid on.']); } $minimum_bid = $item->bids->count() ? BidIncrement::getMinimumNextBid($item->biddingPrice) : $item->startPrice; $highest_bid = $item->getBidHistory()->first(); // If highest bidder, new bid must be higher than existing maximum if ($highest_bid && $highest_bid->bidder == Auth::user()) { if ($request->input('amount') < BidIncrement::getMinimumNextBid($highest_bid->amount)) { return redirect()->back()->withErrors(['amount' => 'Your new maximum bid does not meet the minimum amount.']); } // Not highest bidder, so bid must be higher than minimum amount for current bidding price } elseif ($request->input('amount') < $minimum_bid) { return redirect()->back()->withErrors(['amount' => 'Your bid does not meet the minimum amount.']); } $this->validate($request, ['amount' => 'required|monetary']); $item->placeBid($request->input('amount'), Auth::user()); // If there's no highest bid, there's no bids, so bidding price can stay at start price if ($highest_bid) { // Have we beaten the highest bid? if ($request->input('amount') > $highest_bid->amount) { // If the reserve price is above the last highest bid but below the new maximum bid, set bidding to that if ($item->isReserved() && $request->input('amount') >= $item->reservePrice) { $item->biddingPrice = $item->reservePrice; } // Check if we're increasing the maximum bid if ($highest_bid->bidder == Auth::user()) { // Save in case the bidding price has been bumped to the reserve $item->save(); $highest_bid->delete(); return redirect()->back()->withStatus('Your maximum bid has been increased.'); } // Make sure we're not using the reserve price as the new bidding price if (!in_array('bidding_price', array_keys($item->getDirty()))) { // Set bidding to the maximum bid or the next increment, whichever is lower $item->biddingPrice = min([$request->input('amount'), $item::getMinimumBidAmount($highest_bid->amount)]); } $highest_bid->bidder->sendEmail("You've been outbid", 'emails.item.outbid', ['item_id' => $item->itemId, 'item_name' => $item->name, 'item_price' => $item->biddingPrice]); // We're not the highest bid, so just increment } else { $item->biddingPrice = $request->input('amount'); } } else { $item->biddingPrice = $item->isReserved() && $request->input('amount') >= $item->reservePrice ? $item->reservePrice : $item->startPrice; } $item->save(); return redirect()->back()->withStatus('Your bid has been placed.'); }
/** * Unwatch an item. * * @param \Illuminate\Http\Request $request * * @return \Illuminate\Http\RedirectResponse */ public function postUnwatch(Request $request) { $item = Item::findOrFail($request->input('item_id')); if (!Auth::user()->watching->contains($item)) { return redirect()->back()->withErrors(["You aren't watching this item."]); } Auth::user()->watching()->detach($item); return redirect()->back()->withStatus($item->name . ' has been removed from your watched items.'); }
/** * Checkout an item. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse */ public function postCheckout(Request $request) { $item = Item::findOrFail($request->input('item_id')); if ($item->seller->userId == Auth::user()->userId) { return redirect($item->url)->withStatus('You cannot purchase your own items.'); } // Check for unpaid item if ($unpaid = $item->purchases()->where('user_id', Auth::user()->userId)->where('paid', 0)->first()) { return redirect('/pay/' . $unpaid->purchaseId); } if (!$item->auction && $item->isEnded()) { return redirect()->back()->withErrors(['You can no longer can no longer continue with this purchase because the item has ended.']); } if (!$item->auction && $request->input('quantity') > $item->quantity) { return redirect()->back()->withErrors(['You cannot purchase more than the available stock.']); } if ($item->auction && !$item->isEnded()) { return redirect()->back()->withErrors(['You must win an auction before you can pay for it.']); } if ($item->auction && !$item->winningBid) { return redirect()->back()->withErrors(['Please wait while this auction is processed.']); } if ($item->auction && $item->winningBid->bidder != Auth::user()) { return redirect()->back()->withErrors(["You can only pay for an auction you've won."]); } if ($item->auction && $item->isEnded() && $item->purchases->count()) { return redirect('/pay/' . $item->purchases->first()->purchaseId); } $validator = \Validator::make(\Input::all(), ['delivery_option' => 'required', 'quantity' => 'integer', 'postal_address' => 'required_if:delivery_option,collection', 'name' => 'required_if:postal_address,add', 'street1' => 'required_if:postal_address,add', 'city' => 'required_if:postal_address,add', 'county' => 'required_if:postal_address,add', 'postcode' => 'required_if:postal_address,add', 'country' => 'required_if:postal_address,add']); if ($validator->fails()) { return redirect()->back()->withErrors($validator); } $purchase = new Purchase(); $purchase->created = time(); $purchase->item()->associate($item); $purchase->buyer()->associate(Auth::user()); if ($request->input('delivery_option') != 'collection') { if (!($delivery_option = DeliveryOption::find($request->input('delivery_option')))) { return redirect()->back()->withErrors(['delivery_option' => 'Please select a valid delivery option.']); } $purchase->deliveryOption()->associate($delivery_option); if ($request->input('postal_address') == 'add') { $postal_address = new PostalAddress(); $postal_address->name = $request->input('name'); $postal_address->street1 = $request->input('street1'); $postal_address->street2 = $request->input('street2'); $postal_address->city = $request->input('city'); $postal_address->county = $request->input('county'); $postal_address->country = $request->input('country'); $postal_address->postcode = $request->input('postcode'); $postal_address->user()->associate(Auth::user()); if (!Iso3166::exists($postal_address->country)) { return redirect()->back()->withErrors(['country' => 'Please select a valid country.']); } if ($request->input('remember')) { $postal_address->save(); } } elseif (!($postal_address = PostalAddress::find($request->input('postal_address')))) { return redirect()->back()->withErrors(['postal_address' => 'Please select a valid postal address.']); } elseif ($postal_address->user != Auth::user()) { return redirect()->back()->withErrors(['postal_address' => 'You can only select your own postal addresses.']); } $purchase->useAddress($postal_address); } if ($item->auction && !$item->isActive()) { $purchase->unitPrice = $purchase->total = $item->biddingPrice; $purchase->quantity = 1; } else { $purchase->unitPrice = $item->fixedPrice; $purchase->quantity = $request->input('quantity') ?: 1; $purchase->total = round($purchase->unitPrice * $purchase->quantity, 2); $item->quantity -= $purchase->quantity; $item->save(); } $purchase->save(); return redirect("/pay/{$purchase->purchaseId}"); }