2 namespace Workspace\Controller;
5 class DeviceWorkspace2Controller extends \Zend\Mvc\Controller\AbstractActionController
15 protected $requestData;
21 * @var \Zend\ServiceManager\ServiceManager
25 * @var \Doctrine\ORM\EntityManager
39 protected $sessionData;
48 * Test for sending message to device via GCM.
50 public function testGcmAction()
53 $result = \Utility\Comms\Gcm::send(
55 'd5Io0rJATbY:APA91bF9_h9wmjdxe0PriWZ6DL5EdHOh8_bWdv35mysGDOH-IOUnau_7HhKV8GyTAs4Xe3Vt4vXvM2aC5lhK9pGYy6HaceBbtIsYtn35UN9YQGYaVuWTI9Qvx0ZgK8RksZtJZGYMpege',
59 'changeId' => '1441802190771'
73 public function init($arrayDataResponse = false, $expectPost = false)
76 define('APPLICATION', 'Portal');
77 \Utility\Registry::setServiceManager($this->serviceLocator);
78 $this->em = \Utility\Registry::getEntityManager();
83 \Zend\Mvc\MvcEvent::EVENT_RENDER,
88 ->addHeaderLine('Content-Type', 'application/json');
94 $request = !$expectPost
95 ? json_decode(file_get_contents('php://input'), true)
96 : (isset($_POST['data'])
97 ? json_decode($_POST['data'], true)
99 $this->request = $request;
100 $this->requestData = is_array($this->request) && array_key_exists('data', $this->request)
101 ? $this->request['data']
103 unset($this->request['data']);
105 //-- Authentication checking.
107 if (isset($this->request['authToken']) && !empty($this->request['authToken']))
109 $this->authToken = $this->request['authToken'];
110 $this->sessionData = \Utility\Registry::fetchJson('token_' . $this->authToken);
111 if (is_null($this->sessionData))
113 //-- Invalid auth token.
114 $this->response = new \Zend\View\Model\JsonModel(
117 'Reason' => 'Your applications authentication token is not synchronized with the server.'
119 . 'Please log in again and the data synchronization will continue in the background.',
120 'Data' => $arrayDataResponse
127 \Utility\Registry::set('IsDeviceApiCall', true);
129 //-- Registered device.
130 $this->profileId = $this->sessionData['AuthData']['id'];
133 if (isset($this->request['pushKey']) && !empty($this->request['pushKey']))
135 $this->pushKey = $this->request['pushKey'];
136 $deviceRegistration = $this->em->createQuery(
137 'SELECT deviceRegistration '
138 . 'FROM Company\Entity\DeviceRegistration deviceRegistration '
139 . 'WHERE deviceRegistration.pushKey = :pushKey'
141 ->setParameter('pushKey', $this->pushKey)
143 if (empty($deviceRegistration))
145 //-- Unregistered device trying to push data.
146 $this->response = new \Zend\View\Model\JsonModel(
149 'Reason' => 'Your applications authentication token is not synchronized with the server.'
151 . 'Please log in again and the data synchronization will continue in the background.',
152 'Data' => $arrayDataResponse
159 \Utility\Registry::set('IsDeviceApiCall', true);
161 //-- Registered device.
162 $this->profileId = $deviceRegistration[0]->profile->id;
172 public function pingAction()
176 return new \Zend\View\Model\JsonModel(
178 'Status' => 'Success',
179 'Reason' => 'Awesomeness.',
188 * Register mobile device.
189 * @return \Zend\View\Model\JsonModel
191 public function registerDeviceAction()
196 return $this->response;
199 //-- Check data packet.
200 if (!isset($this->requestData['deviceId'])
201 || !isset($this->requestData['registrationId'])
204 return new \Zend\View\Model\JsonModel(
207 'Reason' => 'Require deviceId and registrationId for device registration.',
208 'Data' => new \stdClass()
213 //-- Do registration.
214 $device = $this->em->getRepository('Company\Entity\Device')
217 'deviceId' => $this->requestData['deviceId']
220 $newDevice = is_null($device);
223 $device = new \Company\Entity\Device();
224 $device->deviceId = $this->requestData['deviceId'];
226 $device->registrationId = $this->requestData['registrationId'];
229 $this->em->persist($device);
234 return new \Zend\View\Model\JsonModel(
236 'Status' => 'Success',
237 'Reason' => 'Awesomeness.',
239 'Message' => 'Device registered.'
246 * Device user pin reset.
247 * @return \Zend\View\Model\JsonModel
249 public function resetPinAction()
254 return $this->response;
257 //-- Check data packet.
258 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
260 'email' => isset($this->requestData['email'])
261 ? $this->requestData['email']
263 'mobile' => isset($this->requestData['mobile'])
264 ? $this->requestData['mobile']
268 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
269 'data' => $input->pack()
271 $profileService = $this->serviceLocator->get('User.Service.Profile');
272 $response = $profileService->deviceResetPin($serviceInput->pack());
273 return new \Zend\View\Model\JsonModel(
275 'Status' => 'Success',
276 'Reason' => 'Awesomeness.',
277 'Data' => $response['Data']
284 * @return \Zend\View\Model\JsonModel
286 public function loginAction()
291 return $this->response;
294 //-- Check data packet.
295 if (!isset($this->requestData['deviceId'])
296 || !isset($this->requestData['email'])
297 || !isset($this->requestData['pin'])
300 return new \Zend\View\Model\JsonModel(
303 'Reason' => 'Require deviceId, email and pin for device login.',
304 'Data' => new \stdClass()
309 //-- Do authentication.
310 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
312 'email' => $this->requestData['email'],
313 'pin' => $this->requestData['pin']
316 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
317 'data' => $input->pack()
319 $profileService = $this->serviceLocator->get('User.Service.Profile');
320 $response = $profileService->deviceLogin($serviceInput->pack());
321 if (isset($response['Data']['authToken']))
324 $this->profileId = $response['Data']['id'];
325 $device = $this->em->getRepository('Company\Entity\Device')
328 'deviceId' => $this->requestData['deviceId']
331 $newDevice = is_null($device);
334 $device = new \Company\Entity\Device();
335 $device->deviceId = $this->requestData['deviceId'];
336 if (isset($this->requestData['registrationId']))
338 $device->registrationId = $this->requestData['registrationId'];
340 $this->em->persist($device);
345 $this->authToken = $response['Data']['authToken'];
346 $this->sessionData = array(
347 'AuthData' => $response['Data'],
348 'AuthToken' => $this->authToken
350 unset($this->sessionData['AuthData']['authToken']);
351 \Utility\Registry::storeJson('token_' . $this->authToken, $this->sessionData);
353 //-- Device registration.
354 $dealerId = $response['Data']['company']['id'];
355 $registration = $this->em->getRepository('Company\Entity\DeviceRegistration')
358 'company' => $dealerId,
359 'device' => $device->id
362 if (is_null($registration))
364 $registration = new \Company\Entity\DeviceRegistration();
365 $registration->company = $this->em->getReference('Company\Entity\Company', $dealerId);
366 $registration->profile = $this->em->getReference('User\\Entity\\Profile', $response['Data']['id']);
367 $registration->device = $device;
368 $registration->pushKey = md5($device->deviceId . ':' . $dealerId);
369 $this->em->persist($registration);
374 $registration->profile = $this->em->getReference('User\\Entity\\Profile', $response['Data']['id']);
379 $responseData = array(
380 'authToken' => $this->authToken,
381 'pushKey' => $registration->pushKey,
382 'dealerId' => $dealerId,
383 'profileId' => $response['Data']['id'],
384 'fullName' => $response['Data']['fullName'],
385 'permissions' => array(
386 'accessValuations' => ($response['Data']['permissions']['valuationPage']
387 && $response['Data']['permissions']['valuationView'])
388 || $response['Data']['permissions']['valuationCreateSales'],
389 'accessVehicles' => $response['Data']['permissions']['stockPage']
390 && $response['Data']['permissions']['stockView'],
391 'salesValuations' => $response['Data']['permissions']['valuationCreateSales'],
392 'completeValuations' => $response['Data']['permissions']['valuationCreatePending']
393 || $response['Data']['permissions']['valuationCreateComplete'],
394 'isTradeCenter' => 'Trade Center' == $response['Data']['company']['dealerType'],
395 'linkedToTradeCenter' => isset($response['Data']['company']['tradeCenter']['id'])
397 'valuators' => array(),
398 'allowedAuctionDays' => $this->getAuctionAllowedDays()
400 $profiles = $this->em->getRepository('User\\Entity\\Profile')
403 'company' => $dealerId
406 foreach ($profiles as $profile)
408 if ($profile->override->valuationCreatePending
409 || $profile->override->valuationCreateComplete
412 $responseData['valuators'][] = array(
413 'id' => $profile->id,
414 'fullName' => $profile->firstName . ' ' . $profile->familyName
420 return new \Zend\View\Model\JsonModel(
422 'Status' => 'Success',
423 'Reason' => 'Awesomeness.',
424 'Data' => $responseData
430 //-- Authentication fail.
431 return new \Zend\View\Model\JsonModel(
434 'Reason' => 'Authentication failure.',
435 'Data' => new \stdClass()
442 * Retrieve available auction end-date list.
443 * @return \Zend\View\Model\JsonModel
445 public function getAuctionDaysAction()
450 return $this->response;
452 $allowed = $this->getAuctionAllowedDays();
456 return new \Zend\View\Model\JsonModel(
458 'Status' => 'Success',
459 'Reason' => 'Awesomeness.',
465 protected function canUseAuctionDay($time, array $openDays, array $publicDays)
467 if (7 == date('N', $time))
471 if (6 == date('N', $time)
472 && !in_array(date('Y-m-d', $time), $openDays)
477 if (in_array(date('Y-m-d', $time), $publicDays))
485 * Retrieve trade and retail from mmCode.
486 * @return \Zend\View\Model\JsonModel
488 public function transunionFromMmCodeAction()
493 return $this->response;
497 if (!isset($this->requestData['mmCode']) || !is_numeric($this->requestData['mmCode'])
498 || !isset($this->requestData['vehicleYear']) || !is_numeric($this->requestData['vehicleYear'])
501 return new \Zend\View\Model\JsonModel(
504 'Reason' => 'Require mmCode and vehicleYear parameters.',
505 'Data' => new \stdClass()
510 //-- Process request.
511 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
513 'mmCode' => $this->requestData['mmCode'],
514 'vehicleYear' => $this->requestData['vehicleYear'],
519 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
520 'data' => $input->pack()
522 $stockUtilService = $this->serviceLocator->get('Stock.Service.Utility');
523 $response = $stockUtilService->deviceTransUnionFromMmCode($serviceInput->pack());
524 if (is_array($response['Data']) && !empty($response['Data'])
525 && isset($response['Data']['VehicleDetails'])
526 && !empty($response['Data']['VehicleDetails'])
529 return new \Zend\View\Model\JsonModel(
531 'Status' => 'Success',
532 'Reason' => 'Awesomeness.',
534 'NewPrice' => $response['Data']['VehicleDetails'][0]['Value']['NewPrice'],
535 'RetailPrice' => $response['Data']['VehicleDetails'][0]['Value']['RetailPrice'],
536 'TradePrice' => $response['Data']['VehicleDetails'][0]['Value']['TradePrice'],
537 'ListPrice' => $response['Data']['VehicleDetails'][0]['Value']['NewPrice']
542 return new \Zend\View\Model\JsonModel(
545 'Reason' => 'Could not retrieve trade and retail data.',
546 'Data' => new \stdClass()
552 * Claim a job item from queue.
553 * @return \Zend\View\Model\JsonModel
555 public function claimJobAction()
560 return $this->response;
564 if (!isset($this->requestData['uvi'])
565 || 0 >= $this->requestData['uvi']
568 return new \Zend\View\Model\JsonModel(
571 'Reason' => 'Require uvi parameter.',
572 'Data' => new \stdClass()
576 if (isset($this->requestData['uvi']))
578 $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13);
581 //-- Attempt to claim the job for this user.
582 $uvi = $this->requestData['uvi'];
583 $stock = $this->em->getRepository('Stock\\Entity\\Stock')
584 ->findOneBy(array('uvi' => $uvi));
585 if (is_null($stock) || is_null($stock->valuation))
587 return new \Zend\View\Model\JsonModel(
590 'Reason' => 'Could not find record.',
591 'Data' => new \stdClass()
595 $valuation = $stock->valuation;
596 if (1 != $valuation->queueStatus || !$valuation->claimQueueItem($this->em, $this->profileId))
598 return new \Zend\View\Model\JsonModel(
601 'Reason' => 'Job no longer available.',
602 'Data' => new \stdClass()
608 $recordId = $valuation->id;
609 $userId = $this->profileId;
610 exec("php /var/www/namibia/public/index.php stock change 4 $recordId $userId > /dev/null &");
611 return new \Zend\View\Model\JsonModel(
613 'Status' => 'Success',
614 'Reason' => 'Awesomeness.',
624 * Claim a job item from queue.
625 * @return \Zend\View\Model\JsonModel
627 public function unclaimJobAction()
632 return $this->response;
636 if (!isset($this->requestData['uvi'])
637 || 0 >= $this->requestData['uvi']
640 return new \Zend\View\Model\JsonModel(
643 'Reason' => 'Require uvi parameter.',
644 'Data' => new \stdClass()
648 if (isset($this->requestData['uvi']))
650 $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13);
653 //-- Attempt to un-claim this job.
654 $uvi = $this->requestData['uvi'];
655 $stock = $this->em->getRepository('Stock\\Entity\\Stock')
656 ->findOneBy(array('uvi' => $uvi));
657 if (is_null($stock) || is_null($stock->valuation))
659 return new \Zend\View\Model\JsonModel(
662 'Reason' => 'Could not find record.',
663 'Data' => new \stdClass()
667 $valuation = $stock->valuation;
668 if (2 != $valuation->queueStatus || !$valuation->unclaimQueueItem($this->em))
670 return new \Zend\View\Model\JsonModel(
673 'Reason' => 'Could not un-claim job.',
674 'Data' => new \stdClass()
680 $recordId = $valuation->id;
681 $userId = $this->profileId;
682 exec("php /var/www/namibia/public/index.php stock change 5 $recordId $userId > /dev/null &");
683 return new \Zend\View\Model\JsonModel(
685 'Status' => 'Success',
686 'Reason' => 'Awesomeness.',
696 * Get list of valuations.
697 * @return \Zend\View\Model\JsonModel
699 public function getValuationsAction()
704 return $this->response;
706 if (is_null($this->sessionData))
708 return new \Zend\View\Model\JsonModel(
711 'Reason' => 'Authentication required.',
712 'Data' => new \stdClass()
717 //-- Collect valuations.
718 $minDate = new \DateTime('now');
719 $minDate->sub(new \DateInterval('P90D'));
720 $stockItems = $this->em->createQuery(
721 'SELECT stock, valuation '
722 . 'FROM Stock\\Entity\\Stock stock '
723 . 'JOIN stock.type vehicleType '
724 . 'JOIN stock.company company '
725 . 'LEFT JOIN stock.valuation valuation '
726 . 'WHERE ((IDENTITY(stock.company) = :companyId AND stock.jobState IN (:stockStatusList)) '
727 . ' OR (IDENTITY(company.tradeCenter) = :companyId AND stock.jobState = :tcStockStatus)) '
728 . ' AND stock.archived = :archived'
729 . ' AND IDENTITY(vehicleType.category) < 8'
730 . ' AND (IDENTITY(stock.valuation) IS NULL OR (valuation.archived = :archived AND valuation.jobState != :statusArchived))'
731 . ' AND stock.created >= :minDate'
733 ->setParameter('companyId', $this->sessionData['AuthData']['company']['id'])
734 ->setParameter('archived', 0)
735 ->setParameter('statusArchived', 'Archived')
736 ->setParameter('minDate', $minDate)
737 ->setParameter('stockStatusList', array('Stock', 'Valuation'))
738 ->setParameter('tcStockStatus', 'Trade Center');
740 // \Utility\Debug::errorLog('getValuationsAction $stockItems->getSQL()', $stockItems->getSQL());
741 // \Utility\Debug::errorLog('getValuationsAction $stockItems->getParameters()', $stockItems->getParameters());
743 $stockItems = $stockItems->getResult();
744 $responseData = array();
746 foreach ($stockItems as $stock)
749 $responseData[$i] = $this->buildValuationData($stock);
751 //-- Done with this valuation.
754 //\Utility\Debug::errorLog('$responseData', $responseData);
755 //-- Return to sender.
756 return new \Zend\View\Model\JsonModel(
758 'Status' => 'Success',
759 'Reason' => 'Awesomeness.',
760 'Data' => $responseData
766 * Get a specific valuation.
767 * @return \Zend\View\Model\JsonModel
769 public function getValuationAction()
774 return $this->response;
776 if (is_null($this->sessionData))
778 return new \Zend\View\Model\JsonModel(
781 'Reason' => 'Authentication required.',
782 'Data' => new \stdClass()
786 if (!isset($this->requestData['uvi'])
787 || !is_numeric($this->requestData['uvi'])
790 return new \Zend\View\Model\JsonModel(
793 'Reason' => 'Field uvi required.',
794 'Data' => new \stdClass()
798 if (isset($this->requestData['uvi']))
800 $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13);
803 //-- Collect valuations.
804 $stock = $this->em->getRepository('Stock\\Entity\\Stock')
807 'uvi' => $this->requestData['uvi']
813 return new \Zend\View\Model\JsonModel(
816 'Reason' => 'Stock entry not found.',
817 'Data' => new \stdClass()
824 return new \Zend\View\Model\JsonModel(
826 'Status' => 'Success',
827 'Reason' => 'Awesomeness.',
828 'Data' => $this->buildValuationData($stock)
835 * Synchronize multiple valuations.
836 * @return \Zend\View\Model\JsonModel
838 public function synchValuationsAction()
841 if (!$this->init(true))
843 return $this->response;
845 \Utility\Registry::set('IsDeviceApiCall', true);
848 //-- Loop through valuations.
850 foreach ($this->requestData as $valuationItem)
853 $uviii = isset($valuationItem['uvi'])
854 ? $valuationItem['uvi']
856 if (!isset($valuationItem['dealerId'])
857 || !is_numeric($valuationItem['dealerId'])
860 error_log("synchValuationsAction : $uviii : NO DEALER ID");
862 'error' => 'Field dealerId required.'
866 if (!isset($valuationItem['profileId'])
867 || !is_numeric($valuationItem['profileId'])
870 error_log("synchValuationsAction : $uviii : NO PROFILE ID");
872 'error' => 'Field profileId required.'
876 if (!isset($valuationItem['owner'])
877 || 0 == strlen($valuationItem['owner'])
880 error_log("synchValuationsAction : $uviii : NO OWNER");
882 'error' => 'Field owner required.'
886 if (!isset($valuationItem['status'])
887 || 0 == strlen($valuationItem['status'])
890 error_log("synchValuationsAction : $uviii : NO STATUS");
892 'error' => 'Field status required.'
897 //-- Establish context.
899 if (isset($valuationItem['uvi']))
901 $originalUvi = $valuationItem['uvi'];
902 $valuationItem['uvi'] = (int) substr($valuationItem['uvi'], 0, 13);
904 $uviii = $valuationItem['uvi'];
905 error_log("synchValuationsAction : $originalUvi : $uviii");
906 $userId = $valuationItem['profileId'];
907 $dealerId = $valuationItem['dealerId'];
908 $existingItem = isset($valuationItem['uvi']);
909 $owner = $valuationItem['owner'];
910 if (0 == $dealerId || 0 == $userId)
912 $userId = $this->profileId;
913 if (!is_null($userId) && false != $userId && is_numeric($userId))
915 $profile = $this->em->find('User\\Entity\\Profile', $userId);
916 $dealerId = $profile->company->id;
921 $stock = $this->em->getRepository('Stock\\Entity\\Stock')
924 'uvi' => $valuationItem['uvi']
927 $existingItem = !is_null($stock);
933 $valuation = $stock->valuation;
934 $initialState = 'Valuation' == $owner
935 ? $valuation->jobState
941 $stock = new \Stock\Entity\Stock();
942 if (isset($valuationItem['uvi'])
943 && !is_null($valuationItem['uvi'])
944 && 0 < strlen($valuationItem['uvi'])
947 $stock->uvi = $valuationItem['uvi'];
949 $stock->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId);
950 $stock->company = $this->em->getReference('Company\\Entity\\Company', $dealerId);
951 $this->em->persist($stock);
952 if ('Valuation' == $owner)
954 $valuation = new \Valuation\Entity\Valuation();
955 $valuation->stock = $stock;
956 $valuation->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId);
957 $this->em->persist($valuation);
961 //-- Collect stock data.
962 $stock->type = $this->em->getReference(
963 'Stock\\Entity\\Type',
964 $valuationItem['vehicleModelTypeId']
966 $stock->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId);
967 $stock->company = $this->em->getReference('Company\\Entity\\Company', $dealerId);
968 //\Utility\Debug::errorLog('$valuationItem', $valuationItem);
969 if (isset($valuationItem['stockNumber']) && 0 < strlen($valuationItem['stockNumber']))
971 $stock->stockNumber = $valuationItem['stockNumber'];
973 if (isset($valuationItem['licenceNumber']))
975 $stock->registrationNumber = $valuationItem['licenceNumber'];
977 if (isset($valuationItem['vinNumber']))
979 $stock->vinNumber = $valuationItem['vinNumber'];
981 if (isset($valuationItem['engineNumber']))
983 $stock->engineNumber = $valuationItem['engineNumber'];
985 if (isset($valuationItem['fuelTypeId'])
986 && 0 < $valuationItem['fuelTypeId']
989 $stock->fuelType = $this->em->getReference(
990 'Stock\\Entity\\FuelType',
991 $valuationItem['fuelTypeId']
994 if (isset($valuationItem['transmissionTypeId'])
995 && 0 < $valuationItem['transmissionTypeId']
998 $stock->transmissionType = $this->em->getReference(
999 'Stock\\Entity\\TransmissionType',
1000 $valuationItem['transmissionTypeId']
1003 if (isset($valuationItem['exteriorColourId'])
1004 && 0 < $valuationItem['exteriorColourId']
1007 $stock->exteriorColour = $this->em->getReference(
1008 'Stock\\Entity\\ExteriorColour',
1009 $valuationItem['exteriorColourId']
1012 if (isset($valuationItem['interiorColourId'])
1013 && 0 < $valuationItem['interiorColourId']
1016 $stock->interiorColour = $this->em->getReference(
1017 'Stock\\Entity\\InteriorColour',
1018 $valuationItem['interiorColourId']
1021 if (isset($valuationItem['vehicleConditionId'])
1022 && 0 < $valuationItem['vehicleConditionId']
1025 $stock->condition = $this->em->getReference(
1026 'Stock\\Entity\\Condition',
1027 $valuationItem['vehicleConditionId']
1030 if (isset($valuationItem['vehicleYearId'])
1031 && 0 < $valuationItem['vehicleYearId']
1034 $stock->vehicleYear = $this->em->getReference(
1035 'Stock\\Entity\\Year',
1036 $valuationItem['vehicleYearId']
1039 if (isset($valuationItem['vehicleMileage']))
1041 $stock->km = $valuationItem['vehicleMileage'];
1043 if (isset($valuationItem['upholsteryId'])
1044 && 0 < $valuationItem['upholsteryId']
1047 $stock->upholstery = $this->em->getReference(
1048 'Stock\\Entity\\Upholstery',
1049 $valuationItem['upholsteryId']
1052 if (isset($valuationItem['spareKeysId'])
1053 && 0 < $valuationItem['spareKeysId']
1056 $stock->spareKeys = $valuationItem['spareKeysId'];
1058 if (isset($valuationItem['fullServiceHistoryId'])
1059 && 0 < $valuationItem['fullServiceHistoryId']
1062 $stock->fullServiceHistory = $this->em->getReference(
1063 'Stock\\Entity\\FullServiceHistory',
1064 $valuationItem['fullServiceHistoryId']
1067 if (isset($valuationItem['fullServiceHistoryNotes']))
1069 $stock->fshNotes = $valuationItem['fullServiceHistoryNotes'];
1071 if (isset($valuationItem['tradePrice']))
1073 $stock->tradePrice = $valuationItem['tradePrice'];
1075 if (isset($valuationItem['retailPrice']))
1077 $stock->retailPrice = $valuationItem['retailPrice'];
1079 if (isset($valuationItem['listPrice']))
1081 $stock->listPrice = $valuationItem['listPrice'];
1085 foreach ($stock->accessories as $accessory)
1087 $this->em->remove($accessory);
1089 foreach ($stock->damages as $damage)
1091 $this->em->remove($damage);
1096 if (isset($valuationItem['accessories'])
1097 && 0 < strlen($valuationItem['accessories'])
1100 $idList = explode(':', $valuationItem['accessories']);
1101 foreach ($idList as $accessoryId)
1103 $stockAccessory = new \Stock\Entity\StockAccessory();
1104 $stockAccessory->stock = $stock;
1105 $stockAccessory->accessory = $this->em->getReference(
1106 'Stock\\Entity\\Accessory',
1109 $this->em->persist($stockAccessory);
1112 if (isset($valuationItem['accessoriesComments']))
1114 $stock->accessoryNotes = $valuationItem['accessoriesComments'];
1117 if (isset($valuationItem['damages']))
1119 if (!is_array($valuationItem['damages']))
1121 $valuationItem['damages'] = json_decode($valuationItem['damages'], true);
1123 if (0 < count($valuationItem['damages']))
1125 foreach ($valuationItem['damages'] as $damageItem)
1127 if ((float)$damageItem['amount'] == 0.0)
1131 $damage = new \Stock\Entity\StockDamage();
1132 $damage->stock = $stock;
1133 $damage->damage = $this->em->getReference(
1134 'Stock\\Entity\\Damage',
1135 $damageItem['serverId']
1137 $damage->amount = $damageItem['amount'];
1138 $this->em->persist($damage);
1140 $damageTotal += (float)$damageItem['amount'];
1144 if (isset($valuationItem['damagesEstimatedRepairCost']))
1146 $stock->damageTotal = $damageTotal;
1148 if (isset($valuationItem['damagesComments']))
1150 $stock->damageNotes = $valuationItem['damagesComments'];
1152 if (isset($valuationItem['damagesPreviousRepairsNoted']))
1154 $stock->previousRepairsNoted = $valuationItem['damagesPreviousRepairsNoted'];
1156 if (isset($valuationItem['damagesPreviousRepairsComments']))
1158 $stock->previousRepairsNotes = $valuationItem['damagesPreviousRepairsComments'];
1161 //-- Valuation data.
1162 if ('Valuation' == $owner)
1164 $valuation->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId);
1165 if (isset($valuationItem['customerName']))
1167 $valuation->firstName = $valuationItem['customerName'];
1169 if (isset($valuationItem['customerSurname']))
1171 $valuation->familyName = $valuationItem['customerSurname'];
1173 if (isset($valuationItem['customerCellNumber']))
1175 $valuation->mobile = $valuationItem['customerCellNumber'];
1177 if (isset($valuationItem['offer']) && 0 < $valuationItem['offer'])
1179 $valuation->amountOffered = $valuationItem['offer'];
1184 if ('Valuation' == $owner)
1186 $stock->jobState = 'Valuation';
1187 $valuation->jobState = $valuationItem['status'];
1188 if (isset($valuationItem['previousStatus']) && '' != $valuationItem['previousStatus'])
1190 $valuation->previousState = $valuationItem['previousStatus'];
1195 if (!is_null($valuation))
1197 $valuation->previousState = $valuation->jobState;
1198 $valuation->jobState = 'Stock';
1199 $this->em->flush($valuation);
1201 $stock->jobState = $valuationItem['status'];
1202 if (isset($valuationItem['previousStatus']) && '' != $valuationItem['previousStatus'])
1204 $stock->previousState = $valuationItem['previousStatus'];
1212 $this->em->flush($stock);
1213 $stock->postInsert();
1214 if ('Valuation' == $owner)
1216 $this->em->flush($valuation);
1218 $stock->valuation = $valuation;
1220 $response[] = array(
1221 'modifiedUvi' => (int) substr($stock->uvi, 0, 13),
1222 'uvi' => $originalUvi
1225 catch (\Exception $e)
1227 if (1452517638893 == $originalUvi)
1229 $response[] = array(
1230 'modifiedUvi' => (int) $originalUvi,
1231 'uvi' => $originalUvi
1236 \Utility\Debug::errorLog(__METHOD__ . ':SynchValuationError on dealer:user', "$dealerId : $userId on $originalUvi");
1237 \Utility\Debug::errorLog(__METHOD__ . ':$valuationItem', $valuationItem);
1238 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
1239 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
1240 $response[] = array(
1241 'error' => 'Could not create entry.'
1247 \Utility\Debug::errorLog('$initialState', $initialState);
1248 \Utility\Debug::errorLog('$valuationItem[status]', $valuationItem['status']);
1250 //-- Actions to apply.
1252 || $initialState != $valuationItem['status']
1255 if ('Valuation' == $owner)
1258 error_log("synchValuationsAction : $originalUvi " . print_r($valuationItem, true));
1260 if ('New Valuation' == $valuation->jobState
1261 && 0 < $valuationItem['valuator']
1264 //-- Send to valuator.
1265 if (!$this->sendToValuator($valuationItem, $valuation))
1267 //-- Failed sending to Valuator.
1271 if ('Price Guide' == $valuation->jobState)
1273 //-- Attempt sending to Price Guide.
1274 if (!$this->sendValuationToPriceGuide($valuationItem, $valuation))
1276 //-- Failed sending to Price Guide.
1277 $valuation->jobState = 'Pending Valuation';
1284 \Utility\Debug::errorLog('in else', $stock->jobState);
1286 if ('Auction' == $stock->jobState)
1288 //-- Attempt sending to auction.
1289 if (!$this->sendToAuction($valuationItem, $stock))
1291 //-- Failed sending to Valuator.
1295 if ('Price Guide' == $stock->jobState)
1297 //-- Attempt sending to Price Guide.
1298 if (!$this->sendStockToPriceGuide($valuationItem, $stock))
1300 //-- Failed sending to Price Guide.
1301 $stock->jobState = 'Stock';
1305 if ('Trade Center' == $stock->jobState)
1307 //-- Attempt sending to Trade Center.
1308 $stock->jobState = 'Stock';
1310 if (!$this->sendStockToTradeCenter($valuationItem, $stock))
1312 //-- Failed sending to Price Guide.
1313 $stock->jobState = 'Stock';
1320 //-- Change notification.
1321 $owner = 'Valuation' == $owner
1324 $recordId = 'Valuation' == $owner
1327 exec("php /var/www/namibia/public/index.php stock change $changeCode $recordId $userId > /dev/null &");
1329 error_log("synchValuationsAction : $originalUvi : \\o/");
1332 \Utility\Debug::errorLog('\Zend\View\Model\JsonModel', array(
1333 'Status' => 'Success',
1334 'Reason' => 'Awesomeness.',
1338 //-- Return to sender.
1339 return new \Zend\View\Model\JsonModel(
1341 'Status' => 'Success',
1342 'Reason' => 'Awesomeness.',
1349 * Synchronize multiple photos.
1350 * @return \Zend\View\Model\JsonModel
1352 public function synchPhotosAction()
1355 if (!$this->init(true, true))
1357 return $this->response;
1360 //-- Loop through valuations.
1361 $filePath = \Utility\Registry::getConfigParam('ImagePath');
1362 $thumbPath = \Utility\Registry::getConfigParam('ThumbnailPath');
1365 if (!isset($this->requestData['uvi'])
1366 || !is_numeric($this->requestData['uvi'])
1369 error_log("synchPhotosAction : NON NUMERIC UVI : " . (!isset($this->requestData['uvi']) ? 'NO UVI' : $this->requestData['uvi']));
1370 return new \Zend\View\Model\JsonModel(
1372 'Status' => 'Error',
1373 'Reason' => 'Field uvi required.',
1374 'Data' => new \stdClass()
1378 if (!isset($this->requestData['type'])
1379 || empty($this->requestData['type'])
1382 error_log("synchPhotosAction : FIELD TYPE REQUIRED : ");
1383 return new \Zend\View\Model\JsonModel(
1385 'Status' => 'Error',
1386 'Reason' => 'Field type required.',
1387 'Data' => new \stdClass()
1391 $originalUvi = null;
1392 if (isset($this->requestData['uvi']))
1394 $originalUvi = $this->requestData['uvi'];
1395 $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13);
1397 error_log("synchPhotosAction : $originalUvi >> " . $this->requestData['uvi']);
1399 //-- Get stock item.
1400 $uvi = $this->requestData['uvi'];
1401 $type = $this->requestData['type'];
1402 $newFileName = $filePath . $type . $uvi . '.jpg';
1404 ->getRepository('Stock\\Entity\\Stock')
1405 ->findOneBy(array('uvi' => $this->requestData['uvi']));
1406 if (is_null($stock))
1408 error_log("synchPhotosAction : $originalUvi >> COULD NOT FIND STOCK ENTRY");
1409 return new \Zend\View\Model\JsonModel(
1411 'Status' => 'Error',
1412 'Reason' => 'Could not find stock entry.',
1413 'Data' => new \stdClass()
1418 //-- Save the image.
1419 ini_set('memory_limit', '512M');
1420 if (!move_uploaded_file($_FILES['photo']['tmp_name'], $newFileName)
1421 || !file_exists($newFileName))
1423 error_log("synchPhotosAction : $originalUvi >> COULD NOT MOVE TEMP FILE");
1424 return new \Zend\View\Model\JsonModel(
1426 'Status' => 'Error',
1427 'Reason' => 'Could not move temp file.',
1428 'Data' => new \stdClass()
1432 $photo = file_get_contents($newFileName, FILE_BINARY);
1433 $this->resizeImage($photo, 'image/jpeg', $thumbPath . $type . $uvi . '.jpg');
1434 $image = new \Utility\Entity\Image();
1435 $image->filename = $type . $uvi . '.jpg';
1436 $image->mimeType = 'image/jpeg';
1437 $this->em->persist($image);
1440 //-- Update stock entry.
1441 switch (strtoupper($type))
1444 $stock->mainImage = $image;
1447 $stock->frontImage = $image;
1450 $stock->rightImage = $image;
1453 $stock->leftImage = $image;
1456 $stock->backImage = $image;
1459 $stock->engineImage = $image;
1462 $stock->interiorImage = $image;
1465 $stock->natisImage = $image;
1470 'modifiedUvi' => $uvi,
1471 'uvi' => $originalUvi,
1474 exec("php /var/www/namibia/public/index.php stock change 2 " . $stock->id . " 0 > /dev/null &");
1476 //-- Return to sender.
1477 error_log("synchPhotosAction : " . print_r($response, true));
1478 error_log("synchPhotosAction : $originalUvi >> \\o/");
1479 return new \Zend\View\Model\JsonModel(
1481 'Status' => 'Success',
1482 'Reason' => 'Awesomeness.',
1489 * Get up to date with latest data.
1490 * @return \Zend\View\Model\JsonModel
1492 public function getMakesAction()
1497 return $this->response;
1500 //-- Let the utility handle it.
1501 $this->requestData['datasetName'] = 'makes';
1502 return $this->getDataUpdatesAction();
1506 * Get up to date with latest data.
1507 * @return \Zend\View\Model\JsonModel
1509 public function getModelsAction()
1514 return $this->response;
1517 //-- Let the utility handle it.
1518 $this->requestData['datasetName'] = 'models';
1519 return $this->getDataUpdatesAction();
1523 * Get up to date with latest data.
1524 * @return \Zend\View\Model\JsonModel
1526 public function getTypesAction()
1531 return $this->response;
1534 //-- Let the utility handle it.
1535 $this->requestData['datasetName'] = 'types';
1536 return $this->getDataUpdatesAction();
1540 * Get up to date with latest data.
1541 * @return \Zend\View\Model\JsonModel
1543 public function getYearsAction()
1548 return $this->response;
1551 //-- Let the utility handle it.
1552 $this->requestData['datasetName'] = 'years';
1553 return $this->getDataUpdatesAction();
1557 * Get up to date with latest data.
1558 * @return \Zend\View\Model\JsonModel
1560 public function getAccessoriesAction()
1565 return $this->response;
1568 //-- Let the utility handle it.
1569 $this->requestData['datasetName'] = 'accessories';
1570 return $this->getDataUpdatesAction();
1574 * Get up to date with latest data.
1575 * @return \Zend\View\Model\JsonModel
1577 protected function getDataUpdatesAction()
1580 if (!isset($this->requestData['datasetName'])
1581 || 0 == strlen($this->requestData['datasetName'])
1584 return new \Zend\View\Model\JsonModel(
1586 'Status' => 'Error',
1587 'Reason' => 'Field datasetName required.',
1588 'Data' => new \stdClass()
1594 switch ($this->requestData['datasetName'])
1598 $entityName = '\Location\Entity\Country';
1601 $entityName = '\Location\Entity\Region';
1604 $entityName = '\Location\Entity\Town';
1608 $entityName = '\Valuation\Entity\Valuation';
1611 $entityName = '\Stock\Entity\Accessory';
1614 $entityName = '\Stock\Entity\Damage';
1617 $entityName = '\Stock\Entity\Upholstery';
1620 $entityName = '\Stock\Entity\Condition';
1622 case 'exteriorColours':
1623 $entityName = '\Stock\Entity\ExteriorColour';
1625 case 'interiorColours':
1626 $entityName = '\Stock\Entity\InteriorColour';
1629 $entityName = '\Stock\Entity\FuelType';
1631 case 'fullServiceHistory':
1632 $entityName = '\Stock\Entity\FullServiceHistory';
1634 case 'transmissionTypes':
1635 $entityName = '\Stock\Entity\TransmissionType';
1638 $entityName = '\Stock\Entity\Natis';
1641 $entityName = '\Stock\Entity\Paper';
1644 $entityName = '\Stock\Entity\Year';
1647 $entityName = '\Stock\Entity\Category';
1650 $entityName = '\Stock\Entity\Make';
1653 ini_set('memory_limit', '512M');
1654 $entityName = '\Stock\Entity\Model';
1657 ini_set('memory_limit', '1024M');
1658 $entityName = '\Stock\Entity\Type';
1661 return new \Zend\View\Model\JsonModel(
1663 'Status' => 'Error',
1664 'Reason' => 'Invalid datasetName ' . $this->requestData['datasetName'] . ' requested.',
1665 'Data' => new \stdClass()
1671 //-- Collect relevant data.
1672 $responseData = array();
1673 $version = isset($this->requestData['version'])
1674 && is_numeric($this->requestData['version'])
1675 ? $this->requestData['version']
1677 $maxVersion = $version;
1679 if ('Build' == $entityName::PULL_SYNCH_STRATEGY)
1681 $filter = 'WHERE 1=1';
1682 $filter .= defined($entityName . '::JOB_QUEUE')
1683 ? ' AND a.queueStatus = 1'
1685 $filter .= $entityName::ARCHIVE
1686 ? ' AND a.archived = 0'
1688 if (method_exists($entityName, 'getSynchQuery'))
1690 $query = $this->em->createQuery(
1691 $entityName::getSynchQuery()
1696 $query = $this->em->createQuery(
1697 "SELECT a FROM $entityName a $filter ORDER BY a.id ASC"
1700 $responseData = $query->getResult();
1701 if (defined($entityName . '::JOB_QUEUE'))
1703 foreach ($responseData as $rowId => $record)
1705 $responseData[$rowId] = $record->toQueueArray();
1710 foreach ($responseData as $rowId => $record)
1712 $responseData[$rowId] = $record->toSynchArray();
1718 //-- Synchronization modification from entity context.
1720 $filter .= defined($entityName . '::JOB_QUEUE')
1721 ? ' AND a.queueStatus = 1'
1723 $filter .= $entityName::ARCHIVE
1724 ? ' AND a.archived = 0'
1726 if (method_exists($entityName, 'getSynchFilter'))
1728 $synchMod = $entityName::getSynchFilter();
1738 //-- Get latest version number.
1739 $versionResult = $this->em->createQuery(
1740 "SELECT MAX(a.createVersion) AS maxCreateVersion, "
1741 . " MAX(a.updateVersion) AS maxUpdateVersion "
1742 . "FROM $entityName a "
1744 . "WHERE $filter " . $synchMod['Filter']
1745 . " ORDER BY a.id ASC"
1747 ->getScalarResult();
1748 $maxVersion = $versionResult[0]['maxCreateVersion'];
1749 if ($maxVersion < $versionResult[0]['maxUpdateVersion'])
1751 $maxVersion = $versionResult[0]['maxUpdateVersion'];
1754 //-- Records to add.
1755 $query = "SELECT [SELECTION] "
1756 . "FROM $entityName a "
1758 . "WHERE a.archived = :archived"
1759 . " AND $filter " . $synchMod['Filter']
1760 . " AND a.createVersion BETWEEN :version AND :maxVersion"
1761 . " ORDER BY a.id ASC";
1763 'archived' => false,
1764 'version' => $version,
1765 'maxVersion' => $maxVersion
1767 $queryResult = $this->em->createQuery(
1768 str_replace('[SELECTION]', 'a', $query)
1770 ->setParameters($params)
1772 $responseData['Create'] = array();
1773 if (defined($entityName . '::JOB_QUEUE'))
1775 foreach ($queryResult as $rowId => $record)
1777 $responseData['Create'][$rowId] = $record[0]->toQueueArray();
1782 foreach ($queryResult as $rowId => $record)
1784 $responseData['Create'][$rowId] = $record[0]->toSynchArray();
1788 //-- Records to update.
1789 $query = "SELECT [SELECTION] "
1790 . "FROM $entityName a "
1792 . "WHERE a.archived = :archived"
1793 . " AND $filter " . $synchMod['Filter']
1794 . " AND a.createVersion < :version"
1795 . " AND a.updateVersion BETWEEN :version AND :maxVersion"
1796 . " ORDER BY a.id ASC";
1798 'archived' => false,
1799 'version' => $version,
1800 'maxVersion' => $maxVersion
1802 $queryResult = $this->em->createQuery(
1803 str_replace('[SELECTION]', 'a', $query)
1805 ->setParameters($params)
1807 $responseData['Update'] = array();
1808 if (defined($entityName . '::JOB_QUEUE'))
1810 foreach ($queryResult as $rowId => $record)
1812 $responseData['Update'][$rowId] = $record[0]->toQueueArray();
1817 foreach ($queryResult as $rowId => $record)
1819 $responseData['Update'][$rowId] = $record[0]->toSynchArray();
1823 //-- Records to remove.
1824 $responseData['Delete'] = array();
1828 return new \Zend\View\Model\JsonModel(
1830 'Status' => 'Success',
1831 'Reason' => 'Awesomeness.',
1833 'version' => $maxVersion,
1834 'strategy' => $entityName::PULL_SYNCH_STRATEGY,
1835 'changes' => $responseData
1844 * Utility to send stuff to Trade Center.
1845 * @param $valuationItem
1849 private function sendStockToTradeCenter($valuationItem, $stock)
1854 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
1856 'Context' => array()
1858 $wStock = $this->serviceLocator->get('Stock');
1859 $wStock->loadJob($stock->id);
1860 $wStock->directRoute('Stock.SendToTradeCenter', $stock->id);
1862 catch (\Exception $e)
1864 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
1865 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
1874 * Utility to send stuff to Auction.
1875 * @param $valuationItem
1879 private function sendToAuction($valuationItem, $stock)
1881 //\Utility\Debug::errorLog('sendToAuction $valuationItem', $valuationItem);
1883 //-- Update trade and retail pricing.
1884 if (8 != $stock->type->category->id)
1888 $tu = new \Utility\Comms\TransUnion();
1889 $data = $tu->searchByMmCode(
1890 $stock->type->mmCode,
1891 $stock->vehicleYear->name,
1896 catch (\Exception $e)
1899 \Utility\Debug::errorLog(
1900 'Exception on fetching trade and retail for Device send to auction',
1905 && isset($data['VehicleDetails'])
1906 && isset($data['VehicleDetails'][0])
1907 && isset($data['VehicleDetails'][0]['Value'])
1910 $this->tradePriceDate = new \DateTime('now');
1911 $this->oldTradePriceDate = new \DateTime('now');
1912 $this->listPriceDate = new \DateTime('now');
1913 $this->oldListPriceDate = new \DateTime('now');
1914 $stock->oldTradePrice = $stock->tradePrice;
1915 $stock->oldRetailPrice = $stock->retailPrice;
1916 $stock->oldListPrice = $stock->listPrice;
1917 $stock->tradePrice = $data['VehicleDetails'][0]['Value']['TradePrice'];
1918 $stock->retailPrice = $data['VehicleDetails'][0]['Value']['RetailPrice'];
1919 $stock->listPrice = $data['VehicleDetails'][0]['Value']['NewPrice'];
1920 $this->em->flush($stock);
1927 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
1930 'endDate' => date('Y-m-d H:i:s', ((int)$valuationItem['auctionEndDate'] / 1000)),
1931 'reservePrice' => $valuationItem['auctionReservePrice'],
1932 'profileId' => $this->profileId
1935 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
1936 'data' => $input->pack()
1938 $wStock = $this->serviceLocator->get('Stock');
1939 $wStock->loadJob($stock->id);
1940 $wStock->executeRoute('Stock.SendToAuction', $stock->id, $serviceInput->pack());
1942 catch (\Exception $e)
1944 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
1945 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
1954 * Utility to send stuff to Valuator(s).
1955 * @param $valuationItem
1959 private function sendToValuator($valuationItem, $valuation)
1964 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
1965 'id' => $valuation->id,
1966 'Valuation' => array(
1967 'valuators' => isset($valuationItem['valuators'])
1968 ? $valuationItem['valuators']
1969 : array($valuationItem['valuator'])
1971 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
1972 'data' => $input->pack()
1974 $sValuation = new \Valuation\Service\Valuation();
1975 $sValuation->setWorkflow($this->serviceLocator->get('Valuation'));
1976 $sValuation->sendToValuators(array(), $valuation, $valuation, $serviceInput->pack());
1978 catch (\Exception $e)
1980 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
1981 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
1990 * Utility to send stuff to Price Guide.
1991 * @param $valuationItem
1995 private function sendValuationToPriceGuide($valuationItem, $valuation)
1997 //-- Which clubs to send to?
1998 $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club')
2001 'company' => $valuationItem['dealerId'],
2002 'useAsDefault' => true,
2006 if (0 == count($clubs))
2008 $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club')
2011 'company' => $valuationItem['dealerId'],
2016 if (0 == count($clubs))
2018 //-- No clubs to send to, abort.
2022 //-- Pass it along the complicated internal process.
2024 foreach ($clubs as $club)
2026 $sendTo[] = array('id' => $club->id);
2030 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
2031 'id' => $valuation->id,
2035 'Valuation' => array(
2036 'firstName' => $valuation->firstName,
2037 'familyName' => $valuation->familyName,
2038 'mobile' => $valuation->mobile
2041 'vehicleYear' => $valuation->stock->vehicleYear->id,
2042 'type' => $valuation->stock->type->id,
2043 'registrationNumber' => $valuation->stock->registrationNumber,
2044 'fuelType' => $valuation->stock->fuelType->id,
2045 'transmissionType' => $valuation->stock->transmissionType->id
2047 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
2048 'data' => $input->pack()
2050 $wValuation = $this->serviceLocator->get('Valuation');
2051 $wValuation->loadJob($valuation->id);
2052 $wValuation->executeRoute('Valuation.SendToPriceGuide', $valuation->id, $serviceInput->pack());
2054 catch (\Exception $e)
2056 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
2057 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
2064 * Utility to send stuff to Price Guide.
2065 * @param $valuationItem
2069 private function sendStockToPriceGuide($valuationItem, $stock)
2071 //-- Which clubs to send to?
2072 $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club')
2075 'company' => $valuationItem['dealerId'],
2076 'useAsDefault' => true,
2080 if (0 == count($clubs))
2082 $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club')
2085 'company' => $valuationItem['dealerId'],
2090 if (0 == count($clubs))
2092 //-- No clubs to send to, abort.
2096 //-- Pass it along the complicated internal process.
2098 foreach ($clubs as $club)
2100 $sendTo[] = array('id' => $club->id);
2104 $input = new \Workspace\Utility\ServiceInput('ParamSet', array(
2109 $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array(
2110 'data' => $input->pack()
2112 $wStock = $this->serviceLocator->get('Stock');
2113 $wStock->loadJob($stock->id);
2114 $wStock->executeRoute('Stock.SendToPriceGuide', $stock->id, $serviceInput->pack());
2116 catch (\Exception $e)
2118 \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage());
2119 \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString());
2128 * Build valuation data for device..
2129 * @param \Stock\Entity\Stock $stock
2132 private function buildValuationData($stock)
2134 //-- Valuation data.
2135 $responseData = array(
2136 'uvi' => (int)$stock->uvi,
2137 'profileId' => $stock->createdBy->id,
2138 'dealerId' => $stock->company->id,
2139 'tradeCenterId' => 'Trade Center' == $stock->jobState && !is_null($stock->company->tradeCenter)
2140 ? $stock->company->tradeCenter->id
2143 'customerName' => !is_null($stock->valuation)
2144 ? $stock->valuation->firstName
2146 'customerSurname' => !is_null($stock->valuation)
2147 ? $stock->valuation->familyName
2149 'customerCellNumber' => !is_null($stock->valuation)
2150 ? $stock->valuation->mobile
2153 'vehicleYearId' => $stock->vehicleYear->id,
2154 'vehicleCategoryId' => $stock->type->category->id,
2155 'vehicleMakeId' => $stock->type->model->make->id,
2156 'vehicleModelId' => $stock->type->model->id,
2157 'vehicleModelTypeId' => $stock->type->id,
2158 'vehicleConditionId' => !is_null($stock->condition)
2159 ? $stock->condition->id
2161 'vehicleMileage' => $stock->km,
2163 'vehicleMakeName' => $stock->type->model->make->name,
2164 'vehicleModelName' => $stock->type->model->name,
2166 'tradePrice' => (float)$stock->tradePrice,
2167 'retailPrice' => (float)$stock->retailPrice,
2168 'listPrice' => (float)$stock->listPrice,
2170 'licenceNumber' => $stock->registrationNumber,
2171 'vinNumber' => $stock->vinNumber,
2172 'engineNumber' => $stock->engineNumber,
2173 'fuelTypeId' => !is_null($stock->fuelType)
2174 ? $stock->fuelType->id
2176 'transmissionTypeId' => !is_null($stock->transmissionType)
2177 ? $stock->transmissionType->id
2179 'exteriorColourId' => !is_null($stock->exteriorColour)
2180 ? $stock->exteriorColour->id
2182 'interiorColourId' => !is_null($stock->interiorColour)
2183 ? $stock->interiorColour->id
2185 'upholsteryId' => !is_null($stock->upholstery)
2186 ? $stock->upholstery->id
2188 'spareKeysId' => is_null($stock->spareKeys)
2190 : ($stock->spareKeys ? 0 : 1),
2191 'fullServiceHistoryId' => !is_null($stock->fullServiceHistory)
2192 ? $stock->fullServiceHistory->id
2194 'fullServiceHistoryNotes' => $stock->fshNotes,
2196 'accessories' => '',
2197 'accessoriesComments' => $stock->accessoryNotes,
2198 'damages' => array(),
2199 'damagesEstimatedRepairCost' => (float)$stock->damageTotal,
2200 'damagesComments' => $stock->damageNotes,
2201 'damagesPreviousRepairsNoted' => $stock->previousRepairsNoted,
2202 'damagesPreviousRepairsComments' => $stock->previousRepairsNotes,
2204 'owner' => !is_null($stock->valuation)
2205 && 'Valuation' == $stock->jobState
2208 'status' => !is_null($stock->valuation)
2209 && 'Valuation' == $stock->jobState
2210 ? $stock->valuation->jobState
2212 'queueStatus' => !is_null($stock->valuation)
2213 ? $stock->valuation->queueStatus
2215 'offer' => !is_null($stock->valuation)
2216 ? (float)$stock->valuation->amountOffered
2218 'stockNumber' => $stock->stockNumber,
2219 'auctionEndDate' => !is_null($stock->auction)
2220 && 'Active' == $stock->auction->jobState
2221 ? $stock->auction->endDate->getTimestamp() * 1000
2223 'auctionReservePrice' => !is_null($stock->auction)
2224 ? (float)$stock->auction->reservePrice
2228 if ('Stock' == $stock->jobState
2229 && !is_null($stock->auction)
2230 && 'Relist' == $stock->auction->jobState
2233 $responseData['status'] = 'Relist';
2236 // \Utility\Debug::errorLog('buildValuationData $responseData', $responseData);
2238 //-- Linked accessories.
2239 $accessories = array();
2240 foreach ($stock->accessories as $accessory)
2242 $accessories[] = $accessory->accessory->id;
2244 if (0 < count($accessories))
2246 $responseData['accessories'] = implode(':', $accessories);
2249 //-- Linked damages.
2251 foreach ($stock->damages as $damage)
2253 if ($damage->archived)
2258 'serverId' => $damage->damage->id,
2259 'amount' => (float)$damage->amount
2262 $responseData['damages'] = $damages;
2276 foreach ($photoMap as $type)
2278 $fieldName = $type . 'Image';
2279 if (!is_null($stock->$fieldName))
2282 'uvi' => (int)$stock->uvi,
2283 'serverId' => $stock->$fieldName->id,
2285 'webUri' => '/img/bin/thumbnail/' . $stock->$fieldName->filename
2289 $responseData['photos'] = $photos;
2290 return $responseData;
2297 * @param $destination
2300 private function resizeImage($imgString, $mimeType, $destination)
2302 $tmpFile = $destination;
2303 file_put_contents($tmpFile, $imgString);
2304 list($img_width, $img_height) = getimagesize($tmpFile);
2306 if (!$img_width || !$img_height)
2310 $src_img = imagecreatefromstring($imgString);
2317 file_put_contents($tmpFile, $imgString);
2320 $new_width = $img_width * $scale;
2321 $new_height = $img_height * $scale;
2322 $new_img = @imagecreatetruecolor($new_width, $new_height);
2327 $write_image = 'imagejpeg';
2328 $image_quality = 95;
2331 @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
2332 $write_image = 'imagegif';
2333 $image_quality = null;
2336 @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
2337 @imagealphablending($new_img, false);
2338 @imagesavealpha($new_img, true);
2339 $write_image = 'imagepng';
2343 case 'image/x-windows-bmp':
2344 $write_image = 'imagebmp';
2345 $image_quality = null;
2350 $success = @imagecopyresampled(
2361 $write_image($new_img, $tmpFile, $image_quality);
2362 @imagedestroy($src_img);
2363 @imagedestroy($new_img);
2366 @imagedestroy($src_img);
2367 @imagedestroy($new_img);
2373 * @throws \Doctrine\ORM\ORMException
2374 * @throws \Doctrine\ORM\OptimisticLockException
2375 * @throws \Doctrine\ORM\TransactionRequiredException
2377 protected function getAuctionAllowedDays()
2379 //-- Establish dealer group for user.
2380 $openDays = array();
2381 $profile = $this->em->find('User\\Entity\\Profile', $this->profileId);
2383 if (!is_null($profile->company)
2384 && !is_null($profile->company->groupDivision)
2385 && !is_null($profile->company->groupDivision->group)
2388 $groupId = $profile->company->groupDivision->group->id;
2390 if (!is_null($groupId))
2392 //-- Get open days for relevant group.
2393 $days = $this->em->createQuery(
2394 'SELECT openDayGroup, openDay '
2395 . 'FROM Auction\\Entity\\OpenDayGroup openDayGroup '
2396 . 'JOIN openDayGroup.openDay openDay '
2397 . 'WHERE IDENTITY(openDayGroup.companyGroup) = :groupId'
2398 . ' AND openDay.openDate > :startDate'
2400 ->setParameter('groupId', $groupId)
2401 ->setParameter('startDate', new \DateTime('now'))
2403 foreach ($days as $publicDay)
2405 $openDays[] = $publicDay->openDay->openDate->format('Y-m-d');
2409 //-- Get public holidays.
2410 $publicDays = array();
2411 $days = $this->em->createQuery(
2412 'SELECT publicHoliday '
2413 . 'FROM Auction\\Entity\\PublicHoliday publicHoliday '
2414 . 'WHERE publicHoliday.holiday > :startDate'
2416 ->setParameter('startDate', new \DateTime('now'))
2418 foreach ($days as $publicDay)
2420 $publicDays[] = $publicDay->holiday->format('Y-m-d');
2424 //-- Get auction max days.
2425 $config = \Utility\Cache::fetchEntity(
2426 'Config\Entity\Config', 1, \Utility\Registry::getEntityManager(), 600
2428 $maxDays = $config['auctionMaxDays'];
2431 $day = time() + 86400;
2433 if ($this->canUseAuctionDay($day, $openDays, $publicDays))
2435 $allowed[] = date('Y-m-d', $day);
2437 for ($i = 1; $i < $maxDays; $i++)
2439 //-- Move to next day.
2442 //-- Check if we can use this day.
2443 if ($this->canUseAuctionDay($day, $openDays, $publicDays))
2445 $allowed[] = date('Y-m-d', $day);