2 namespace Valuation\Entity;
4 use Doctrine\ORM\Mapping as ORM;
12 * @ORM\HasLifecycleCallbacks
13 * @ORM\Table(name="stock_valuation")
19 * Can archive records.
23 * Pull Synchronization Strategy for this table.
25 const PULL_SYNCH_STRATEGY = 'Build';
27 * Push Synchronization Strategy for this table.
29 const PUSH_SYNCH_STRATEGY = 'Update';
31 * Post insert action must be called after new entity is flushed to database.
33 const HAVE_POST_INSERT = true;
35 * Handle as a job queue for mobile devices.
37 const JOB_QUEUE = true;
43 const DEPARTMENT_NEW = 'New';
44 const DEPARTMENT_USED = 'Used';
48 /* ------------------------------------ Identification ------------------------------------ */
51 * @ORM\Column(type="integer");
52 * @ORM\GeneratedValue(strategy="AUTO")
57 * @ORM\Column(type="string", length=12, nullable=true, name="valuation_number");
59 protected $valuationNumber;
62 /* ------------------------------------ Ownership ------------------------------------ */
64 * @ORM\ManyToOne(targetEntity="\Stock\Entity\Stock", cascade={"all"})
65 * @ORM\JoinColumn(nullable=false, name="stock_id")
70 * @ORM\ManyToOne(targetEntity="\Valuation\Entity\XmlRpc", cascade={"all"})
71 * @ORM\JoinColumn(nullable=true, name="xmlrpc_auth_id")
73 protected $xmlRpcClient;
76 /* ------------------------------------ History ------------------------------------ */
78 * @ORM\ManyToOne(targetEntity="\User\Entity\Profile")
79 * @ORM\JoinColumn(nullable=false, name="created_by_profile_id")
84 * @ORM\ManyToOne(targetEntity="\User\Entity\Profile")
85 * @ORM\JoinColumn(nullable=true, name="valuated_by_profile_id")
87 protected $valuatedBy;
90 * @ORM\OneToMany(targetEntity="ValuationValuators", mappedBy="valuation", cascade={"all"}, fetch="EXTRA_LAZY")
95 * @ORM\ManyToOne(targetEntity="\User\Entity\Profile")
96 * @ORM\JoinColumn(nullable=true, name="sales_profile_id")
98 protected $salesProfile;
101 * @ORM\ManyToOne(targetEntity="\User\Entity\Profile")
102 * @ORM\JoinColumn(nullable=true, name="manager_profile_id")
104 protected $managerProfile;
107 * @ORM\Column(type="datetime", nullable=true, name="sent_to_sales");
109 protected $sentToSales;
112 * @ORM\Column(type="string", length=50, nullable=true, name="sales_force_item_id")
117 // /* ------------------------------------ Customer ------------------------------------ */
119 * @ORM\Column(type="string", length=50, nullable=true, name="first_name")
121 protected $firstName;
124 * @ORM\Column(type="string", length=50, nullable=true, name="family_name")
126 protected $familyName;
129 * @ORM\Column(type="string", length=13, nullable=true, name="id_number")
134 * @ORM\Column(type="string", length=20, nullable=true)
139 * @ORM\Column(type="string", length=255, nullable=true)
144 * @ORM\Column(type="string", length=25, nullable=true, name="department");
146 protected $department;
149 * @ORM\ManyToOne(targetEntity="\Location\Entity\Region")
150 * @ORM\JoinColumn(nullable=true, name="lib_region_id")
155 * @ORM\ManyToOne(targetEntity="\Location\Entity\Town")
156 * @ORM\JoinColumn(nullable=true, name="lib_city_id")
161 * @ORM\Column(type="string", length=150, nullable=true)
166 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=true, name="required_price", options={"unsigned"=true});
168 protected $requiredPrice = 0.0;
171 * @ORM\Column(type="boolean", nullable=true);
173 protected $sighted = true;
176 * @ORM\Column(nullable=true, type="boolean", name="license_disc_expired");
178 protected $licenseDiscExpired = true;
181 * @ORM\Column(type="boolean", nullable=true, name="trade_retail_requested");
183 protected $tradeRetailRequested;
186 /* ------------------------------------ Pricing ------------------------------------ */
188 * @ORM\Column(type="text", name="sales_comments")
190 protected $salesComments = '';
193 * @ORM\Column(type="text", name="customer_comments")
195 protected $customerComments = '';
198 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="amount_offered", options={"unsigned"=true});
200 protected $amountOffered = 0.0;
203 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="bank_settlement_amount", options={"unsigned"=true});
205 protected $bankSettlement = 0.0;
208 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="over_allowance", options={"unsigned"=true});
210 protected $overAllowance = 0.0;
213 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="stand_in_value", options={"unsigned"=true});
215 protected $standInValue = 0.0;
218 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="projected_retail", options={"unsigned"=true});
220 protected $projectedRetail = 0.0;
223 * @ORM\Column(type="decimal", scale=2, precision=11, nullable=false, name="planned_margin", options={"unsigned"=true});
225 protected $plannedMargin = 0.0;
229 * @ORM\Column(type="string", length=150, nullable=true, name="customer_address_street")
231 protected $customerAddressStreet;
234 * @ORM\Column(type="string", length=150, nullable=true, name="customer_address_street_name")
236 protected $customerAddressStreetName;
239 * @ORM\Column(type="string", length=150, nullable=true, name="customer_address_suburb")
241 protected $customerAddressSuburb;
244 * @ORM\Column(type="string", length=150, nullable=true, name="customer_address_city")
246 protected $customerAddressCity;
249 * @ORM\Column(type="string", length=150, nullable=true, name="customer_address_postal_code")
251 protected $customerAddressPostalCode;
254 * @ORM\ManyToOne(targetEntity="\Valuation\Entity\SendToStockFrom")
255 * @ORM\JoinColumn(nullable=true, name="send_to_stock_from_id")
257 protected $sendToStockFrom;
260 * @ORM\ManyToOne(targetEntity="\Valuation\Entity\DealNotDoneSelection")
261 * @ORM\JoinColumn(nullable=true, name="deal_not_done_selection_id")
263 protected $dealNotDoneSelection;
266 * @ORM\Column(type="text", name="deal_not_done_reason", nullable=true)
268 protected $dealNotDoneReason;
271 /* ------------------------------------ Tracking ------------------------------------ */
273 * @ORM\Column(type="smallint", name="queue_status");
275 protected $queueStatus = 0;
278 * @ORM\Column(nullable=true, type="string", length=25, nullable=true, name="internal_status");
280 protected $internalState;
283 * @ORM\Column(type="string", length=25, nullable=true, name="previous_status");
285 protected $previousState;
288 * @ORM\Column(nullable=true, type="string", length=25, name="status");
293 * @ORM\Column(type="datetime");
298 * @ORM\Column(type="datetime", nullable=true);
303 * @ORM\Column(type="boolean");
305 protected $archived = false;
308 * @ORM\Column(type="boolean", name="is_public");
310 protected $isPublic = false;
313 * @ORM\Column(type="boolean", name="is_public_customer");
315 protected $isPublicCustomer = false;
318 * Initialize collections.
320 public function __construct()
322 $this->valuators = new \Doctrine\Common\Collections\ArrayCollection();
326 * Add a new Valuator to this Stock Valuation Item.
327 * @param \User\Entity\Profile $profile
328 * @return \Valuation\Entity\Valuation
330 public function addValuator(\User\Entity\Profile $profile)
332 $this->valuators[] = $profile;
339 * Magic getter to expose protected properties.
341 * @param string $property
344 public function __get($property)
346 return $this->$property;
350 * Magic setter to save protected properties.
352 * @param string $property
353 * @param mixed $value
355 public function __set($property, $value)
357 $this->$property = $value;
363 public function setCreateTime()
365 if (!\Utility\Registry::get('IsDeviceApiCall', false))
367 $this->createdBy = \Utility\Registry::isAuthenticated()
368 ? \Utility\Registry::resolveProfileContext($this->createdBy)
369 : \Utility\Registry::getEntityManager()
370 ->getReference('\User\Entity\Profile', 1);
372 $this->created = new \DateTime("now");
378 public function setUpdateTime()
380 $this->updated = new \DateTime("now");
381 ('New Valuation' != $this->jobState)
382 && 0 < $this->queueStatus
383 && $this->queueStatus = 0;
384 if ('Price Guide' == $this->jobState
385 && is_null($this->stock->loadedOnPriceGuide))
387 $this->stock->loadedOnPriceGuide = new \DateTime("now");
389 if (!is_null($this->salesProfile) && is_null($this->sentToSales))
391 $this->sentToSales = new \DateTime("now");
396 * Automatically called from DataBin if HAVE_POST_INSERT constant is set on entity.
399 public function postInsert()
401 if (is_null($this->id) || !is_numeric($this->id))
405 $this->valuationNumber = 'V' . str_pad($this->id, 7, '0', STR_PAD_LEFT);
410 * Convert the object to an array.
411 * @param array $expand
412 * @param array $intersect
413 * @param boolean $showIdentifiers
414 * @param integer $expandAll
417 public function toArray(
418 array $expand = array(), array $intersect = array(),
419 $showIdentifiers = false, $expandAll = 0
422 $intersect = array_flip($intersect);
423 $dateTimeFormat = \Utility\Registry::getConfigParam('DateTimeFormat');
424 $includeAll = empty($intersect);
426 ($includeAll || isset($intersect['id']))
427 && $data['id'] = $this->id;
428 ($includeAll || isset($intersect['valuationNumber']))
429 && $data['valuationNumber'] = $this->valuationNumber;
430 ($includeAll || isset($intersect['stock']))
431 && $data['stock'] = (in_array('stock', $expand) || $expandAll || $showIdentifiers)
432 && !is_null($this->stock)
433 ? (!$showIdentifiers || in_array('stock', $expand) ? $this->stock->toArray(
434 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
435 ) : $this->stock->id)
437 ($includeAll || isset($intersect['xmlRpcClient']))
438 && $data['xmlRpcClient'] = (in_array('xmlRpcClient', $expand) || $expandAll || $showIdentifiers)
439 && !is_null($this->xmlRpcClient)
440 ? (!$showIdentifiers || in_array('xmlRpcClient', $expand) ? $this->xmlRpcClient->toArray(
441 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
442 ) : $this->xmlRpcClient->id)
444 ($includeAll || isset($intersect['createdBy']))
445 && $data['createdBy'] = (in_array('createdBy', $expand) || $expandAll || $showIdentifiers)
446 && !is_null($this->createdBy)
447 ? (!$showIdentifiers || in_array('createdBy', $expand) ? $this->createdBy->toArray(
448 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
449 ) : $this->createdBy->id)
451 ($includeAll || isset($intersect['valuatedBy']))
452 && $data['valuatedBy'] = (in_array('valuatedBy', $expand) || $expandAll || $showIdentifiers)
453 && !is_null($this->valuatedBy)
454 ? (!$showIdentifiers || in_array('valuatedBy', $expand) ? $this->valuatedBy->toArray(
455 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
456 ) : $this->valuatedBy->id)
458 ($includeAll || isset($intersect['valuators']))
459 && $data['valuators'] = (in_array('valuators', $expand) || $expandAll || $showIdentifiers)
460 && !is_null($this->valuators)
461 ? $this->valuatorsToArray($showIdentifiers)
463 ($includeAll || isset($intersect['salesProfile']))
464 && $data['salesProfile'] = (in_array('salesProfile', $expand) || $expandAll || $showIdentifiers)
465 && !is_null($this->salesProfile)
466 ? (!$showIdentifiers || in_array('salesProfile', $expand) ? $this->salesProfile->toArray(
467 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
468 ) : $this->salesProfile->id)
470 ($includeAll || isset($intersect['managerProfile']))
471 && $data['managerProfile'] = (in_array('managerProfile', $expand) || $expandAll || $showIdentifiers)
472 && !is_null($this->managerProfile)
473 ? (!$showIdentifiers || in_array('managerProfile', $expand) ? $this->managerProfile->toArray(
474 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
475 ) : $this->managerProfile->id)
477 ($includeAll || isset($intersect['firstName']))
478 && $data['firstName'] = $this->firstName;
479 ($includeAll || isset($intersect['familyName']))
480 && $data['familyName'] = $this->familyName;
481 ($includeAll || isset($intersect['idNumber']))
482 && $data['idNumber'] = $this->idNumber;
483 ($includeAll || isset($intersect['mobile']))
484 && $data['mobile'] = $this->mobile;
485 ($includeAll || isset($intersect['email']))
486 && $data['email'] = $this->email;
487 ($includeAll || isset($intersect['department']))
488 && $data['department'] = $this->department;
489 ($includeAll || isset($intersect['region']))
490 && $data['region'] = (in_array('region', $expand) || $expandAll || $showIdentifiers)
491 && !is_null($this->region)
492 ? (!$showIdentifiers || in_array('region', $expand) ? $this->region->toArray(
493 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
494 ) : $this->region->id)
496 ($includeAll || isset($intersect['city']))
497 && $data['city'] = (in_array('city', $expand) || $expandAll || $showIdentifiers)
498 && !is_null($this->city)
499 ? (!$showIdentifiers || in_array('city', $expand) ? $this->city->toArray(
500 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
503 ($includeAll || isset($intersect['street']))
504 && $data['street'] = $this->street;
505 ($includeAll || isset($intersect['sighted']))
506 && $data['sighted'] = $this->sighted;
507 ($includeAll || isset($intersect['licenseDiscExpired']))
508 && $data['licenseDiscExpired'] = $this->licenseDiscExpired;
509 ($includeAll || isset($intersect['requiredPrice']))
510 && $data['requiredPrice'] = $this->requiredPrice;
511 ($includeAll || isset($intersect['amountOffered']))
512 && $data['amountOffered'] = $this->amountOffered;
513 ($includeAll || isset($intersect['bankSettlement']))
514 && $data['bankSettlement'] = $this->bankSettlement;
515 ($includeAll || isset($intersect['salesComments']))
516 && $data['salesComments'] = $this->salesComments;
518 ($includeAll || isset($intersect['customerComments']))
519 && $data['customerComments'] = $this->customerComments;
521 ($includeAll || isset($intersect['customerAddressStreet']))
522 && $data['customerAddressStreet'] = $this->customerAddressStreet;
523 ($includeAll || isset($intersect['customerAddressStreetName']))
524 && $data['customerAddressStreetName'] = $this->customerAddressStreetName;
525 ($includeAll || isset($intersect['customerAddressSuburb']))
526 && $data['customerAddressSuburb'] = $this->customerAddressSuburb;
527 ($includeAll || isset($intersect['customerAddressCity']))
528 && $data['customerAddressCity'] = $this->customerAddressCity;
529 ($includeAll || isset($intersect['customerAddressPostalCode']))
530 && $data['customerAddressPostalCode'] = $this->customerAddressPostalCode;
533 ($includeAll || isset($intersect['sendToStockFrom']))
534 && $data['sendToStockFrom'] = (in_array('sendToStockFrom', $expand) || $expandAll || $showIdentifiers)
535 && !is_null($this->sendToStockFrom)
536 ? (!$showIdentifiers || in_array('sendToStockFrom', $expand) ? $this->sendToStockFrom->toArray(
537 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
538 ) : $this->sendToStockFrom->id)
541 ($includeAll || isset($intersect['dealNotDoneSelection']))
542 && $data['dealNotDoneSelection'] = (in_array('dealNotDoneSelection', $expand) || $expandAll || $showIdentifiers)
543 && !is_null($this->dealNotDoneSelection)
544 ? (!$showIdentifiers || in_array('dealNotDoneSelection', $expand) ? $this->dealNotDoneSelection->toArray(
545 $expand, $intersect, $showIdentifiers, ($expandAll - 1)
546 ) : $this->dealNotDoneSelection->id)
549 ($includeAll || isset($intersect['dealNotDoneReason']))
550 && $data['dealNotDoneReason'] = $this->dealNotDoneReason;
552 ($includeAll || isset($intersect['overAllowance']))
553 && $data['overAllowance'] = $this->overAllowance;
554 ($includeAll || isset($intersect['standInValue']))
555 && $data['standInValue'] = $this->standInValue;
556 ($includeAll || isset($intersect['projectedRetail']))
557 && $data['projectedRetail'] = $this->projectedRetail;
558 ($includeAll || isset($intersect['plannedMargin']))
559 && $data['plannedMargin'] = $this->plannedMargin;
560 ($includeAll || isset($intersect['queueStatus']))
561 && $data['queueStatus'] = $this->queueStatus;
562 ($includeAll || isset($intersect['jobState']))
563 && $data['jobState'] = $this->jobState;
565 ($includeAll || isset($intersect['previousState']))
566 && $data['previousState'] = $this->previousState;
567 ($includeAll || isset($intersect['isPublicCustomer']))
568 && $data['isPublicCustomer'] = $this->isPublicCustomer;
570 ($includeAll || isset($intersect['created']))
571 && $data['created'] = !is_null($this->created)
572 ? $this->created->format($dateTimeFormat)
574 ($includeAll || isset($intersect['updated']))
575 && $data['updated'] = !is_null($this->updated)
576 ? $this->updated->format($dateTimeFormat)
582 * Internal utility to change valuators collection into array.
583 * @param boolean $showIdentifiers
586 protected function valuatorsToArray($showIdentifiers = false)
589 $iterator = $this->valuators->getIterator();
590 foreach ($iterator as $valuator)
592 $data[] = $showIdentifiers
593 ? array('id' => $valuator->profile->id)
594 : $valuator->toArray();
600 * Convert the object to an array for queue synchronization.
603 public function toQueueArray()
607 'created' => $this->created->format('Y-m-d H:i'),
608 'created_by' => $this->createdBy->firstName . ' ' . $this->createdBy->familyName,
609 'reg_number' => $this->stock->registrationNumber,
610 'make' => $this->stock->type->model->make->name,
611 'model' => $this->stock->type->model->name,
612 'type' => $this->stock->type->name,
613 'queue_status' => $this->queueStatus
618 * Convert the object to an array for synchronization.
621 public function toSynchArray()
625 'created' => $this->created->format(
626 \Utility\Registry::getConfigParam('DateTimeFormat')
628 'created_by' => $this->createdBy->firstName . ' ' . $this->createdBy->familyName,
629 'reg_number' => $this->stock->registrationNumber,
630 'make' => $this->stock->type->model->make->name,
631 'model' => $this->stock->type->model->name,
632 'type' => $this->stock->type->name
637 * Query to use for synchronization pull.
640 public static function getSynchQuery()
642 return 'SELECT valuation '
643 . 'FROM \Valuation\Entity\Valuation valuation '
644 . 'JOIN valuation.valuators valuator '
645 . 'WHERE (valuation.queueStatus = 1 AND IDENTITY(valuator.profile) = '
646 . \Utility\Registry::getAuthParam('id') . ')'
647 . ' OR (valuation.queueStatus = 2 AND IDENTITY(valuation.valuatedBy) = '
648 . \Utility\Registry::getAuthParam('id') . ')';
652 * Claim job queue item.
653 * @param \Doctrine\ORM\EntityManager $em
656 public function claimQueueItem(\Doctrine\ORM\EntityManager $em, $profileId = false)
658 $profileId = false !== $profileId
660 : \Utility\Registry::getAuthParam('id');
661 if (2 == $this->queueStatus && $profileId != $this->valuatedBy->id)
665 $this->queueStatus = 2;
666 $this->valuatedBy = $em->getReference(
667 '\User\Entity\Profile',
675 * Unclaim job queue item.
676 * @param \Doctrine\ORM\EntityManager $em
679 public function unclaimQueueItem(\Doctrine\ORM\EntityManager $em)
681 $this->queueStatus = 1;
682 $this->valuatedBy = null;
688 * Complete claimed job queue item.
689 * @param \Doctrine\ORM\EntityManager $em
691 public function completeQueueItem(\Doctrine\ORM\EntityManager $em)
693 $iterator = $this->valuators->getIterator();
694 foreach ($iterator as $val)
702 * Populate from an array.
705 public function fromArray($data = array())
708 && $this->id = $data['id'];
709 isset($data['stock'])
710 && $this->stock = $data['stock'];
711 isset($data['xmlRpcClient'])
712 && $this->xmlRpcClient = $data['xmlRpcClient'];
713 isset($data['createdBy'])
714 && $this->createdBy = $data['createdBy'];
715 isset($data['valuatedBy'])
716 && $this->valuatedBy = $data['valuatedBy'];
717 isset($data['salesProfile'])
718 && $this->salesProfile = $data['salesProfile'];
719 isset($data['firstName'])
720 && $this->firstName = $data['firstName'];
721 isset($data['familyName'])
722 && $this->familyName = $data['familyName'];
723 isset($data['idNumber'])
724 && $this->idNumber = $data['idNumber'];
725 isset($data['mobile'])
726 && $this->mobile = $data['mobile'];
727 isset($data['email'])
728 && $this->email = $data['email'];
729 isset($data['department'])
730 && $this->department = $data['department'];
731 isset($data['region'])
732 && $this->region = $data['region'];
734 && $this->city = $data['city'];
735 isset($data['street'])
736 && $this->street = $data['street'];
737 isset($data['sighted'])
738 && $this->sighted = $data['sighted'];
739 isset($data['licenseDiscExpired'])
740 && $this->licenseDiscExpired = $data['licenseDiscExpired'];
741 isset($data['requiredPrice'])
742 && $this->requiredPrice = $data['requiredPrice'];
743 isset($data['salesComments'])
744 && $this->salesComments = $data['salesComments'];
746 isset($data['customerComments'])
747 && $this->customerComments = $data['customerComments'];
749 isset($data['customerAddressStreet'])
750 && $this->customerAddressStreet = $data['customerAddressStreet'];
751 isset($data['customerAddressStreetName'])
752 && $this->customerAddressStreetName = $data['customerAddressStreetName'];
753 isset($data['customerAddressSuburb'])
754 && $this->customerAddressSuburb = $data['customerAddressSuburb'];
755 isset($data['customerAddressCity'])
756 && $this->customerAddressCity = $data['customerAddressCity'];
757 isset($data['customerAddressPostalCode'])
758 && $this->customerAddressPostalCode = $data['customerAddressPostalCode'];
760 isset($data['sendToStockFrom'])
761 && $this->sendToStockFrom = $data['sendToStockFrom'];
762 isset($data['dealNotDoneSelection'])
763 && $this->dealNotDoneSelection = $data['dealNotDoneSelection'];
764 isset($data['dealNotDoneReason'])
765 && $this->dealNotDoneReason = $data['dealNotDoneReason'];
767 isset($data['amountOffered'])
768 && $this->amountOffered = $data['amountOffered'];
769 isset($data['bankSettlement'])
770 && $this->bankSettlement = $data['bankSettlement'];
771 isset($data['overAllowance'])
772 && $this->overAllowance = $data['overAllowance'];
773 isset($data['standInValue'])
774 && $this->standInValue = $data['standInValue'];
775 isset($data['projectedRetail'])
776 && $this->projectedRetail = $data['projectedRetail'];
777 isset($data['plannedMargin'])
778 && $this->plannedMargin = $data['plannedMargin'];
779 isset($data['queueStatus'])
780 && $this->queueStatus = $data['queueStatus'];
781 if (isset($data['valuators']))
783 $em = \Utility\Registry::getEntityManager();
785 foreach ($data['valuators'] as $val)
787 $newVals[$val['id']] = $val['id'];
789 $currentVals = array();
790 $iterator = $this->valuators->getIterator();
791 foreach ($iterator as $val)
793 $currentVals[$val->id] = $val->id;
794 !isset($newVals[$val->id])
795 && $em->remove($val);
798 foreach ($data['valuators'] as $val)
800 if (!isset($currentVals[$val['id']]))
802 $valuator = new ValuationValuators();
803 $valuator->profile = $em->getReference('\User\Entity\Profile', $val['id']);
804 $valuator->valuation = $this;
805 $this->valuators->add($valuator);