text changes to registration mail content
[namibia] / module / Auction / src / Auction / Service / Bid.php
1 <?php
2 namespace Auction\Service;
3
4
5
6 /**
7  * Manage Offer data.
8  * @author andre.fourie
9  */
10 class Bid extends \Auction\DataBin\Bid
11 {
12
13         protected $_increments = null;
14
15         /**
16          * Retrieve next higher auto-increment rule.
17          * @param unknown $price
18          * @return \Auction\Entity\Increment
19          */
20         public function _getNextIncrement($price)
21         {
22                 if (!$this->_increments)
23                 {
24                         $this->_increments = $this->em
25                                 ->getRepository('\Auction\Entity\Increment')
26                                 ->findBy(array(), array('to' => 'ASC'));
27                 }
28                 foreach ($this->_increments as $incr)
29                 {
30                         if ($incr->from >= $price)
31                         {
32                                 return $incr;
33                         }
34                 }
35                 return false;
36         }
37
38
39         /**
40          * ConditionalContract: Update.
41          *
42          * @param array $meta
43          * @param object|null $jobRecord
44          * @param object|null $record
45          * @param \Workspace\Contract\AbstractBase $contract
46          * @return array
47          */
48         public function noBidOnExpiredAuction($meta, $jobRecord, $record, \Workspace\Contract\AbstractBase $contract)
49         {
50                 if ('Active' != $jobRecord->jobState
51                         || $jobRecord->endDate->getTimestamp() > time())
52                 {
53                         throw new \Exception('Auction already closed.');
54                 }
55         }
56
57         /**
58          * ExecuteAfter: Create.
59          * Handle bidding details.
60          * @param array $meta
61          * @param object|null $jobRecord
62          * @param object|null $record
63          * @param \Workspace\Utility\ServiceInputParams $contract
64          * @return array
65          */
66         public function updateStatus($meta, $auction, $record, \Workspace\Utility\ServiceInputParams $contract)
67         {
68                 #-> Collect some info.
69                 $basket = $this->em
70                         ->getRepository('\Auction\Entity\Basket')
71                         ->findOneBy(array(
72                                 'auction' => $auction->id,
73                                 'company' => $record->company->id
74                         ));
75                 if (is_null($basket))
76                 {
77                         $basket = new \Auction\Entity\Basket();
78                         $basket->fromArray(array(
79                                         'auction' => $auction,
80                                         'company' => $record->company,
81                                         'profile' => $record->profile
82                         ));
83                         $this->em->persist($basket);
84                         $this->em->flush($basket);
85                 }
86                 elseif (true == $basket->archived)
87                 {
88                         $basket->archived = false;
89                         $this->em->flush($basket);
90                 }
91                 if ($auction->reservePrice > $record->amount)
92                 {
93                         $record->status = 'Archived';
94                         $this->em->flush($record);
95                         throw new \Exception('Your bid was placed but you were just outbid.');
96                         return;
97                 }
98                 $newCurrentBid = false;
99                 $newBid        = null;
100                 $oldBid        = null;
101                 $doNotify      = false;
102
103                 #-> Lockdown some working space.
104                 $this->em->clear();
105                 $this->em->getConnection()->beginTransaction();
106                 $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($this->em);
107                 $rsm->addRootEntityFromClassMetadata('\Auction\Entity\Auction', 'auction');
108                 $query = $this->em->createNativeQuery("SELECT * FROM auction WHERE id = :id FOR UPDATE", $rsm);
109                 $query->setParameter("id", $auction->id);
110                 $jobRecord = $query->getOneOrNullResult();
111                 $cBidId = $jobRecord->currentBid
112                         ? $jobRecord->currentBid->id
113                         : 0;
114                 $aBidId = $jobRecord->currentBid && $jobRecord->currentBid->autoBid
115                         ? $jobRecord->currentBid->autoBid->id
116                         : 0;
117                 $record = $this->em->find('\Auction\Entity\Bid', $record->id);
118
119                 #-> Safety check.
120                 if ('Active' != $jobRecord->jobState
121                         || time() > $jobRecord->endDate->getTimestamp())
122                 {
123                         $record->status = 'Archived';
124                         $this->em->flush($record);
125                         $this->em->getConnection()->commit();
126                         throw new \Exception('Your bid could not be placed. This auction item have been closed.');
127                         return;
128                 }
129
130                 #-> Some more info.
131                 $nextRule = $this->_getNextIncrement(
132                                 $jobRecord->currentBidPrice != 0.0
133                                         ? $jobRecord->currentBidPrice
134                                         : $jobRecord->reservePrice
135                                 );
136                 $incr = $jobRecord->bidIncrement;
137
138                 #-> Process.
139                 $haveAtBid = false;
140                 $jobRecord->numberOfBids++;
141                 //$record->amount = floor($record->amount / $incr) * $incr;
142                 if ($nextRule && $record->amount >= $nextRule->from)
143                 {
144                         $jobRecord->bidIncrement = $nextRule->amount;
145                         $incr = $nextRule->amount;
146                 }
147                 if (is_null($jobRecord->currentBid))
148                 {
149                         #-> First bid on this item.
150                         $newCurrentBid = true;
151                         $newBid = $record;
152                 }
153                 elseif ($jobRecord->currentBidPrice >= $record->amount
154                         || $jobRecord->currentBid->company->id == $record->company->id)
155                 {
156                         #-> Late arrival or useless hack.
157                         $record->status = 'Archived';
158                         $this->em->flush($record);
159                         $this->em->getConnection()->commit();
160                         if ($jobRecord->currentBid->company->id == $record->company->id)
161                         {
162                                 throw new \Exception('Your bid was not successfull. Your dealership already has the winning bid.');
163                         }
164                         else
165                         {
166                                 throw new \Exception('Your bid was placed but you were just outbid.');
167                         }
168                         $doNotify = true;
169                         $oldBid = $record;
170                 }
171                 else
172                 {
173                         #-> Competing bids, figure it out.
174                         //$this->em->merge($jobRecord->currentBid);
175                         
176                         $doNotify = true;
177                         if (!is_null($jobRecord->currentBid->autoBid))
178                         {
179                                 #-> Bid against existing auto-bid.
180                                 if ($record->amount > $jobRecord->currentBid->autoBid->amount)
181                                 {
182                                         $newCurrentBid = true;
183                                         $newBid = $record;
184                                         $oldBid = $jobRecord->currentBid;
185                                         $jobRecord->currentBid->status = 'Archived';
186                                         $jobRecord->currentBid->autoBid->status = 'Archived';
187                                         $this->em->flush($jobRecord->currentBid);
188                                         $this->em->flush($jobRecord->currentBid->autoBid);
189
190 //                    $jobRecord->numberOfBids++;
191                                 }
192                                 elseif ($record->amount <= $jobRecord->currentBid->autoBid->amount
193                                                 && $jobRecord->currentBid->autoBid->amount < ($record->amount + $incr))
194                                 {
195                                         $atBid = new \Auction\Entity\Bid();
196                                         $atBid->fromArray(array(
197                                                         'auction' => $jobRecord,
198                                                         'company' => $jobRecord->currentBid->company,
199                                                         'profile' => $jobRecord->currentBid->profile,
200                                                         'autoBid' => $jobRecord->currentBid->autoBid,
201                                                         'amount'  => $record->amount
202                                         ));
203                                         $this->em->persist($atBid);
204                                         $this->em->flush($atBid);
205                                         $jobRecord->numberOfBids++;
206                                         $newCurrentBid = true;
207                                         $newBid = $atBid;
208                                         $oldBid = $record;
209                                         $record->status = 'Archived';
210                                         $this->em->flush($record);
211                                         $haveAtBid = true;
212                                 }
213                                 else
214                                 {
215                                         $atBid = new \Auction\Entity\Bid();
216                                         $atBid->fromArray(array(
217                                                 'auction' => $jobRecord,
218                                                 'company' => $jobRecord->currentBid->company,
219                                                 'profile' => $jobRecord->currentBid->profile,
220                                                 'autoBid' => $jobRecord->currentBid->autoBid,
221                                                 'amount'  => $record->amount + $incr
222                                         ));
223                                         $this->em->persist($atBid);
224                                         $this->em->flush($atBid);
225                                         $jobRecord->numberOfBids++;
226                                         $newCurrentBid = true;
227                                         $newBid = $atBid;
228                                         $oldBid = $record;
229                                         $record->status = 'Archived';
230                                         $this->em->flush($record);
231                                         $haveAtBid = true;
232                                 }
233                         }
234                         else
235                         {
236                                 #-> Bid against bid.
237                                 if ($record->amount > $jobRecord->currentBidPrice)
238                                 {
239                                         $newCurrentBid = true;
240                                         $newBid = $record;
241                                         $oldBid = $jobRecord->currentBid;
242                                         $jobRecord->currentBid->status = 'Archived';
243                                         $this->em->flush($jobRecord->currentBid);
244
245 //                    $jobRecord->numberOfBids++;
246                                 }
247                                 else
248                                 {
249                                         $oldBid = $record;
250                                         $record->status = 'Archived';
251                                         $this->em->flush($record);
252                                 }
253 //                $jobRecord->numberOfBids++;
254                         }
255                 }
256
257                 #-> Update auction with latest.
258                 if ($newCurrentBid)
259                 {
260                         $jobRecord->currentBid = $newBid;
261                         $jobRecord->currentBidPrice = $newBid->amount;
262                         if ($nextRule && $newBid->amount >= $nextRule->from)
263                         {
264                                 $jobRecord->bidIncrement = $nextRule->amount;
265                                 $incr = $nextRule->amount;
266                         }
267                 }
268
269                 #-> Expiry buffer.
270                 if (time() > ($jobRecord->endDate->getTimestamp() - 300))
271                 {
272                         #-> Move end date out with 5 minutes.
273                         $jobRecord->endDate = new \DateTime(
274                                                 date('Y-m-d H:i:s', $jobRecord->endDate->getTimestamp() + 300)
275                         );
276                         error_log($jobRecord->endDate->getTimestamp());
277                 }
278                 /* if ($haveAtBid)
279                 {
280                         $this->em->flush($atBid);
281                 } */
282                 $this->em->flush($jobRecord);
283
284                 #-> Unlock.
285                 $this->em->getConnection()->commit();
286
287                 #-> Notify clients with updated auction data.
288                 $vehicle = $jobRecord->stock->type->model->make->name
289                         . ', ' . $jobRecord->stock->type->model->name
290                         . ', ' . $jobRecord->stock->type->name
291                         . ' (' . $jobRecord->stock->vehicleYear->name . ')';
292                 if ($newCurrentBid)
293                 {
294                         #-> Update stock entry.
295                         $jobRecord->stock->highestBid = $jobRecord->currentBidPrice;
296                         $this->em->flush();
297
298                         #-> Chat to ape comet server.
299                         \Utility\Comms\Ape::broadcast('LiveAuction', array(
300                                 'id'                => $jobRecord->id,
301                                 'current_bid'       => $jobRecord->currentBid->toArray(array(), array(), 1),
302                                 'current_bid_id'    => $jobRecord->currentBid->id,
303                                 'current_bid_price' => $jobRecord->currentBidPrice,
304                                 'number_of_bids'    => $jobRecord->numberOfBids,
305                                 'expire_datetime'   => $jobRecord->endDate->format(\Utility\Definitions\Locale::getDateTimeFormat()),
306                                 'winner'            => $newBid->company->id,
307                                 'looser'            => !is_null($oldBid) ? $oldBid->company->id : 0,
308                                 'basket'            => $basket->toArray(array(), array(), 1),
309                                 'vehicle'                       => $vehicle
310                                 ));
311                 }
312
313                 #-> Outbid notification.
314                 if ($newCurrentBid && $doNotify)
315                 {
316                         #-> Send email.
317                         $currPrefix = \Utility\Definitions\Locale::getCurrencyPrefix() . ' ';
318                         $oNotify = new \Utility\Comms\Notification();
319                         $oNotify->sendFromTemplate(
320                                         null, null,
321                                         $oldBid->company->id, $oldBid->profile->id,
322                                         null, $oldBid->profile->mobile,
323                                         null,
324                                         'auction-outbid',
325                                         array(
326                                                 'first_name'                    => $oldBid->profile->firstName,
327                                                 'family_name'                   => $oldBid->profile->familyName,
328                                                 'vehicle'                               => $vehicle,
329                                                 'seller'                                => $jobRecord->company->name,
330                                                 'price'                                 => $currPrefix . ($jobRecord->currentBidPrice + $incr),
331                                                 'bid'                                   => $currPrefix . $oldBid->amount,
332                                                 'auction_expiry_date'   => $jobRecord->endDate->format(
333                                                                                                         \Utility\Definitions\Locale::getDateTimeFormat()
334                                                                                                 )
335                                         ));
336                 }
337
338                 #-> Feedback.
339                 if ($newCurrentBid && $record->company->id != $newBid->company->id)
340                 {
341                         throw new \Exception('Your bid was placed but you were just outbid.');
342                 }
343         }
344
345
346
347 }