Offer.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. /**
  3. *
  4. * PHP Pro Bid $Id$ 0uJApXGHcK0nsw0Ak8YVgJnj82NHj7iRW64al/8o0LY=
  5. *
  6. * @link http://www.phpprobid.com
  7. * @copyright Copyright (c) 2015 Online Ventures Software & CodeCube SRL
  8. * @license http://www.phpprobid.com/license Commercial License
  9. *
  10. * @version 7.6
  11. */
  12. /**
  13. * offers table row object model
  14. */
  15. namespace Ppb\Db\Table\Row;
  16. use Ppb\Service;
  17. class Offer extends AbstractRow
  18. {
  19. /**
  20. * offer statuses
  21. */
  22. const STATUS_PENDING = 'pending';
  23. const STATUS_ACCEPTED = 'accepted';
  24. const STATUS_DECLINED = 'declined';
  25. const STATUS_WITHDRAWN = 'withdrawn';
  26. const STATUS_COUNTER = 'counter';
  27. /**
  28. *
  29. * allowed offer statuses
  30. *
  31. * @var array
  32. */
  33. public static $statuses = array(
  34. self::STATUS_PENDING => 'Pending',
  35. self::STATUS_ACCEPTED => 'Accepted',
  36. self::STATUS_DECLINED => 'Declined',
  37. self::STATUS_WITHDRAWN => 'Withdrawn',
  38. self::STATUS_COUNTER => 'Counter Offer',
  39. );
  40. /**
  41. *
  42. * check if the offer can be accepted
  43. * - must be the offer receiver
  44. * - the listing has to have enough quantity available
  45. * - the offer must have the status = pending
  46. *
  47. * @param \Ppb\Db\Table\Row\Listing $listing
  48. *
  49. * @return bool
  50. */
  51. public function canAccept(Listing $listing = null)
  52. {
  53. if (!$listing instanceof Listing) {
  54. /** @var \Ppb\Db\Table\Row\Listing $listing */
  55. $listing = $this->findParentRow('\Ppb\Db\Table\Listings');
  56. }
  57. $user = $this->getUser();
  58. $quantity = $this->getData('quantity');
  59. $productAttributes = \Ppb\Utility::unserialize($this->getData('product_attributes'));
  60. if (
  61. $listing->canAcceptOffer($quantity, $productAttributes) &&
  62. $this->getData('receiver_id') == $user['id'] &&
  63. $this->getData('status') == self::STATUS_PENDING
  64. ) {
  65. return true;
  66. }
  67. return false;
  68. }
  69. /**
  70. *
  71. * check if counteroffer can be made to this offer
  72. * just marks the status flag as "counter"
  73. *
  74. * will just clone the canAccept() method
  75. *
  76. * @param \Ppb\Db\Table\Row\Listing $listing
  77. *
  78. * @return bool
  79. */
  80. public function canCounter(Listing $listing = null)
  81. {
  82. return $this->canAccept($listing);
  83. }
  84. /**
  85. *
  86. * check if the logged in user can withdraw the offer
  87. * - must be the offer poster
  88. * - the offer must have the status = pending
  89. *
  90. * @return bool
  91. */
  92. public function canWithdraw()
  93. {
  94. $user = $this->getUser();
  95. return ($this->getData('user_id') == $user['id'] &&
  96. $this->getData('status') == self::STATUS_PENDING) ? true : false;
  97. }
  98. /**
  99. *
  100. * check if the offer can be declined
  101. * - must be the offer receiver
  102. * - the offer must have the status = pending
  103. *
  104. * @return bool
  105. */
  106. public function canDecline()
  107. {
  108. $user = $this->getUser();
  109. return ($this->getData('receiver_id') == $user['id'] &&
  110. $this->getData('status') == self::STATUS_PENDING) ? true : false;
  111. }
  112. /**
  113. *
  114. * determines the id of the buyer in an offer row object
  115. *
  116. * @param Listing $listing
  117. *
  118. * @return int
  119. */
  120. public function getBuyerId(Listing $listing = null)
  121. {
  122. if (!$listing instanceof Listing) {
  123. /** @var \Ppb\Db\Table\Row\Listing $listing */
  124. $listing = $this->findParentRow('\Ppb\Db\Table\Listings');
  125. }
  126. return ($this->getData('user_id') == $listing['user_id']) ?
  127. $this->getData('receiver_id') : $this->getData('user_id');
  128. }
  129. /**
  130. *
  131. * accept the offer and create a new sale
  132. * the listing is selected with the for update clause so that
  133. * no other transactions can update the listing while
  134. * this action is in progress
  135. *
  136. * @return bool
  137. */
  138. public function accept()
  139. {
  140. /** @var \Ppb\Db\Table\Row\Listing $listing */
  141. $listing = $this->findParentRow('\Ppb\Db\Table\Listings', null, $this->getTable()->select()->forUpdate());
  142. if ($this->canAccept($listing)) {
  143. $this->save(array(
  144. 'status' => self::STATUS_ACCEPTED,
  145. ));
  146. //MAIL OFFER ACCEPTED USER NOTIFICATION
  147. $mail = new \Listings\Model\Mail\UserNotification();
  148. $mail->offerAccepted($listing, $this)->send();
  149. $service = new Service\Sales();
  150. $data = array(
  151. 'buyer_id' => $this->getBuyerId($listing),
  152. 'seller_id' => $listing['user_id'],
  153. 'listings' => array(
  154. array(
  155. 'listing_id' => $listing['id'],
  156. 'price' => $this->getData('amount'),
  157. 'quantity' => (int)$this->getData('quantity'),
  158. 'product_attributes' => $this->getData('product_attributes'),
  159. ),
  160. ),
  161. );
  162. $service->save($data);
  163. return true;
  164. }
  165. return false;
  166. }
  167. /**
  168. *
  169. * mark this offer as counter offered
  170. *
  171. * @return bool
  172. */
  173. public function counter()
  174. {
  175. /** @var \Ppb\Db\Table\Row\Listing $listing */
  176. $listing = $this->findParentRow('\Ppb\Db\Table\Listings');
  177. if ($this->canCounter($listing)) {
  178. $this->save(array(
  179. 'status' => self::STATUS_COUNTER,
  180. ));
  181. return true;
  182. }
  183. return false;
  184. }
  185. /**
  186. *
  187. * decline an offer
  188. *
  189. * @return bool
  190. */
  191. public function decline()
  192. {
  193. /** @var \Ppb\Db\Table\Row\Listing $listing */
  194. $listing = $this->findParentRow('\Ppb\Db\Table\Listings');
  195. if ($this->canDecline()) {
  196. $this->save(array(
  197. 'status' => self::STATUS_DECLINED,
  198. ));
  199. //MAIL OFFER DECLINED USER NOTIFICATION
  200. $mail = new \Listings\Model\Mail\UserNotification();
  201. $mail->offerDeclined($listing, $this)->send();
  202. return true;
  203. }
  204. return false;
  205. }
  206. /**
  207. *
  208. * withdraw an offer
  209. * (only the poster can do this)
  210. *
  211. * @return bool
  212. */
  213. public function withdraw()
  214. {
  215. if ($this->canWithdraw()) {
  216. /** @var \Ppb\Db\Table\Row\Listing $listing */
  217. $listing = $this->findParentRow('\Ppb\Db\Table\Listings');
  218. $this->save(array(
  219. 'status' => self::STATUS_WITHDRAWN,
  220. ));
  221. //MAIL OFFER WITHDRAWN USER NOTIFICATION
  222. $mail = new \Listings\Model\Mail\UserNotification();
  223. $mail->offerWithdrawn($listing, $this)->send();
  224. return true;
  225. }
  226. return false;
  227. }
  228. }