_increments) { $this->_increments = $this->em ->getRepository('\Auction\Entity\Increment') ->findBy(array(), array('to' => 'ASC')); } foreach ($this->_increments as $incr) { if ($incr->from >= $price) { return $incr; } } return false; } /** * ConditionalContract: Update. * * @param array $meta * @param object|null $jobRecord * @param object|null $record * @param \Workspace\Contract\AbstractBase $contract * @return array */ public function noBidOnExpiredAuction($meta, $jobRecord, $record, \Workspace\Contract\AbstractBase $contract) { if ('Active' != $jobRecord->jobState || $jobRecord->endDate->getTimestamp() > time()) { throw new \Exception('Auction already closed.'); } } /** * ExecuteAfter: Create. * Handle bidding details. * @param array $meta * @param object|null $jobRecord * @param object|null $record * @param \Workspace\Utility\ServiceInputParams $contract * @return array */ public function updateStatus($meta, $auction, $record, \Workspace\Utility\ServiceInputParams $contract) { #-> Collect some info. $basket = $this->em ->getRepository('\Auction\Entity\Basket') ->findOneBy(array( 'auction' => $auction->id, 'company' => $record->company->id )); if (is_null($basket)) { $basket = new \Auction\Entity\Basket(); $basket->fromArray(array( 'auction' => $auction, 'company' => $record->company, 'profile' => $record->profile )); $this->em->persist($basket); $this->em->flush($basket); } elseif (true == $basket->archived) { $basket->archived = false; $this->em->flush($basket); } if ($auction->reservePrice > $record->amount) { $record->status = 'Archived'; $this->em->flush($record); throw new \Exception('Your bid was placed but you were just outbid.'); return; } $newCurrentBid = false; $newBid = null; $oldBid = null; $doNotify = false; #-> Lockdown some working space. $this->em->clear(); $this->em->getConnection()->beginTransaction(); $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->em); $rsm->addRootEntityFromClassMetadata('\Auction\Entity\Auction', 'auction'); $query = $this->em->createNativeQuery("SELECT * FROM auction WHERE id = :id FOR UPDATE", $rsm); $query->setParameter("id", $auction->id); $jobRecord = $query->getOneOrNullResult(); $cBidId = $jobRecord->currentBid ? $jobRecord->currentBid->id : 0; $aBidId = $jobRecord->currentBid && $jobRecord->currentBid->autoBid ? $jobRecord->currentBid->autoBid->id : 0; $record = $this->em->find('\Auction\Entity\Bid', $record->id); #-> Safety check. if ('Active' != $jobRecord->jobState || time() > $jobRecord->endDate->getTimestamp()) { $record->status = 'Archived'; $this->em->flush($record); $this->em->getConnection()->commit(); throw new \Exception('Your bid could not be placed. This auction item have been closed.'); return; } #-> Some more info. $nextRule = $this->_getNextIncrement( $jobRecord->currentBidPrice != 0.0 ? $jobRecord->currentBidPrice : $jobRecord->reservePrice ); $incr = $jobRecord->bidIncrement; #-> Process. $haveAtBid = false; $jobRecord->numberOfBids++; //$record->amount = floor($record->amount / $incr) * $incr; if ($nextRule && $record->amount >= $nextRule->from) { $jobRecord->bidIncrement = $nextRule->amount; $incr = $nextRule->amount; } if (is_null($jobRecord->currentBid)) { #-> First bid on this item. $newCurrentBid = true; $newBid = $record; } elseif ($jobRecord->currentBidPrice >= $record->amount || $jobRecord->currentBid->company->id == $record->company->id) { #-> Late arrival or useless hack. $record->status = 'Archived'; $this->em->flush($record); $this->em->getConnection()->commit(); if ($jobRecord->currentBid->company->id == $record->company->id) { throw new \Exception('Your bid was not successfull. Your dealership already has the winning bid.'); } else { throw new \Exception('Your bid was placed but you were just outbid.'); } $doNotify = true; $oldBid = $record; } else { #-> Competing bids, figure it out. //$this->em->merge($jobRecord->currentBid); $doNotify = true; if (!is_null($jobRecord->currentBid->autoBid)) { #-> Bid against existing auto-bid. if ($record->amount > $jobRecord->currentBid->autoBid->amount) { $newCurrentBid = true; $newBid = $record; $oldBid = $jobRecord->currentBid; $jobRecord->currentBid->status = 'Archived'; $jobRecord->currentBid->autoBid->status = 'Archived'; $this->em->flush($jobRecord->currentBid); $this->em->flush($jobRecord->currentBid->autoBid); // $jobRecord->numberOfBids++; } elseif ($record->amount <= $jobRecord->currentBid->autoBid->amount && $jobRecord->currentBid->autoBid->amount < ($record->amount + $incr)) { $atBid = new \Auction\Entity\Bid(); $atBid->fromArray(array( 'auction' => $jobRecord, 'company' => $jobRecord->currentBid->company, 'profile' => $jobRecord->currentBid->profile, 'autoBid' => $jobRecord->currentBid->autoBid, 'amount' => $record->amount )); $this->em->persist($atBid); $this->em->flush($atBid); $jobRecord->numberOfBids++; $newCurrentBid = true; $newBid = $atBid; $oldBid = $record; $record->status = 'Archived'; $this->em->flush($record); $haveAtBid = true; } else { $atBid = new \Auction\Entity\Bid(); $atBid->fromArray(array( 'auction' => $jobRecord, 'company' => $jobRecord->currentBid->company, 'profile' => $jobRecord->currentBid->profile, 'autoBid' => $jobRecord->currentBid->autoBid, 'amount' => $record->amount + $incr )); $this->em->persist($atBid); $this->em->flush($atBid); $jobRecord->numberOfBids++; $newCurrentBid = true; $newBid = $atBid; $oldBid = $record; $record->status = 'Archived'; $this->em->flush($record); $haveAtBid = true; } } else { #-> Bid against bid. if ($record->amount > $jobRecord->currentBidPrice) { $newCurrentBid = true; $newBid = $record; $oldBid = $jobRecord->currentBid; $jobRecord->currentBid->status = 'Archived'; $this->em->flush($jobRecord->currentBid); // $jobRecord->numberOfBids++; } else { $oldBid = $record; $record->status = 'Archived'; $this->em->flush($record); } // $jobRecord->numberOfBids++; } } #-> Update auction with latest. if ($newCurrentBid) { $jobRecord->currentBid = $newBid; $jobRecord->currentBidPrice = $newBid->amount; if ($nextRule && $newBid->amount >= $nextRule->from) { $jobRecord->bidIncrement = $nextRule->amount; $incr = $nextRule->amount; } } #-> Expiry buffer. if (time() > ($jobRecord->endDate->getTimestamp() - 300)) { #-> Move end date out with 5 minutes. $jobRecord->endDate = new \DateTime( date('Y-m-d H:i:s', $jobRecord->endDate->getTimestamp() + 300) ); error_log($jobRecord->endDate->getTimestamp()); } /* if ($haveAtBid) { $this->em->flush($atBid); } */ $this->em->flush($jobRecord); #-> Unlock. $this->em->getConnection()->commit(); #-> Notify clients with updated auction data. $vehicle = $jobRecord->stock->type->model->make->name . ', ' . $jobRecord->stock->type->model->name . ', ' . $jobRecord->stock->type->name . ' (' . $jobRecord->stock->vehicleYear->name . ')'; if ($newCurrentBid) { #-> Update stock entry. $jobRecord->stock->highestBid = $jobRecord->currentBidPrice; $this->em->flush(); #-> Chat to ape comet server. \Utility\Comms\Ape::broadcast('LiveAuction', array( 'id' => $jobRecord->id, 'current_bid' => $jobRecord->currentBid->toArray(array(), array(), 1), 'current_bid_id' => $jobRecord->currentBid->id, 'current_bid_price' => $jobRecord->currentBidPrice, 'number_of_bids' => $jobRecord->numberOfBids, 'expire_datetime' => $jobRecord->endDate->format(\Utility\Definitions\Locale::getDateTimeFormat()), 'winner' => $newBid->company->id, 'looser' => !is_null($oldBid) ? $oldBid->company->id : 0, 'basket' => $basket->toArray(array(), array(), 1), 'vehicle' => $vehicle )); } #-> Outbid notification. if ($newCurrentBid && $doNotify) { #-> Send email. $currPrefix = \Utility\Definitions\Locale::getCurrencyPrefix() . ' '; $oNotify = new \Utility\Comms\Notification(); $oNotify->sendFromTemplate( null, null, $oldBid->company->id, $oldBid->profile->id, null, $oldBid->profile->mobile, null, 'auction-outbid', array( 'first_name' => $oldBid->profile->firstName, 'family_name' => $oldBid->profile->familyName, 'vehicle' => $vehicle, 'seller' => $jobRecord->company->name, 'price' => $currPrefix . ($jobRecord->currentBidPrice + $incr), 'bid' => $currPrefix . $oldBid->amount, 'auction_expiry_date' => $jobRecord->endDate->format( \Utility\Definitions\Locale::getDateTimeFormat() ) )); } #-> Feedback. if ($newCurrentBid && $record->company->id != $newBid->company->id) { throw new \Exception('Your bid was placed but you were just outbid.'); } } }