1, 'changeId' => '1441802190771' ) ); echo '
';
		var_dump($result);
		echo '
'; exit(); } /** * Initialize. */ public function init($arrayDataResponse = false, $expectPost = false) { //-- Context. define('APPLICATION', 'Portal'); \Utility\Registry::setServiceManager($this->serviceLocator); $this->em = \Utility\Registry::getEntityManager(); $this->serviceLocator ->get('Application') ->getEventManager() ->attach( \Zend\Mvc\MvcEvent::EVENT_RENDER, function ($event) { $event->getResponse() ->getHeaders() ->addHeaderLine('Content-Type', 'application/json'); }, -10000 ); //-- Request. $request = !$expectPost ? json_decode(file_get_contents('php://input'), true) : (isset($_POST['data']) ? json_decode($_POST['data'], true) : array()); $this->request = $request; $this->requestData = is_array($this->request) && array_key_exists('data', $this->request) ? $this->request['data'] : array(); unset($this->request['data']); //-- Authentication checking. // AuthToken check. if (isset($this->request['authToken']) && !empty($this->request['authToken'])) { $this->authToken = $this->request['authToken']; $this->sessionData = \Utility\Registry::fetchJson('token_' . $this->authToken); if (is_null($this->sessionData)) { //-- Invalid auth token. $this->response = new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Your applications authentication token is not synchronized with the server.' . "\n\n" . 'Please log in again and the data synchronization will continue in the background.', 'Data' => $arrayDataResponse ? array() : new \stdClass() ) ); return false; } \Utility\Registry::set('IsDeviceApiCall', true); //-- Registered device. $this->profileId = $this->sessionData['AuthData']['id']; } // PushKey check. if (isset($this->request['pushKey']) && !empty($this->request['pushKey'])) { $this->pushKey = $this->request['pushKey']; $deviceRegistration = $this->em->createQuery( 'SELECT deviceRegistration ' . 'FROM Company\Entity\DeviceRegistration deviceRegistration ' . 'WHERE deviceRegistration.pushKey = :pushKey' ) ->setParameter('pushKey', $this->pushKey) ->getResult(); if (empty($deviceRegistration)) { //-- Unregistered device trying to push data. $this->response = new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Your applications authentication token is not synchronized with the server.' . "\n\n" . 'Please log in again and the data synchronization will continue in the background.', 'Data' => $arrayDataResponse ? array() : new \stdClass() ) ); return false; } \Utility\Registry::set('IsDeviceApiCall', true); //-- Registered device. $this->profileId = $deviceRegistration[0]->profile->id; } //-- All good. return true; } /** * Ping-pong. */ public function pingAction() { //-- Fun. $this->init(); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'pong' => true ) ) ); } /** * Register mobile device. * @return \Zend\View\Model\JsonModel */ public function registerDeviceAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Check data packet. if (!isset($this->requestData['deviceId']) || !isset($this->requestData['registrationId']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Require deviceId and registrationId for device registration.', 'Data' => new \stdClass() ) ); } //-- Do registration. $device = $this->em->getRepository('Company\Entity\Device') ->findOneBy( array( 'deviceId' => $this->requestData['deviceId'] ) ); $newDevice = is_null($device); if ($newDevice) { $device = new \Company\Entity\Device(); $device->deviceId = $this->requestData['deviceId']; } $device->registrationId = $this->requestData['registrationId']; if ($newDevice) { $this->em->persist($device); } $this->em->flush(); //-- Done. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'Message' => 'Device registered.' ) ) ); } /** * Device user pin reset. * @return \Zend\View\Model\JsonModel */ public function resetPinAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Check data packet. $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'Login' => array( 'email' => isset($this->requestData['email']) ? $this->requestData['email'] : null, 'mobile' => isset($this->requestData['mobile']) ? $this->requestData['mobile'] : null ) )); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $profileService = $this->serviceLocator->get('User.Service.Profile'); $response = $profileService->deviceResetPin($serviceInput->pack()); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $response['Data'] ) ); } /** * Device user login. * @return \Zend\View\Model\JsonModel */ public function loginAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Check data packet. if (!isset($this->requestData['deviceId']) || !isset($this->requestData['email']) || !isset($this->requestData['pin']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Require deviceId, email and pin for device login.', 'Data' => new \stdClass() ) ); } //-- Do authentication. $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'Login' => array( 'email' => $this->requestData['email'], 'pin' => $this->requestData['pin'] ) )); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $profileService = $this->serviceLocator->get('User.Service.Profile'); $response = $profileService->deviceLogin($serviceInput->pack()); if (isset($response['Data']['authToken'])) { //-- Device entry. $this->profileId = $response['Data']['id']; $device = $this->em->getRepository('Company\Entity\Device') ->findOneBy( array( 'deviceId' => $this->requestData['deviceId'] ) ); $newDevice = is_null($device); if ($newDevice) { $device = new \Company\Entity\Device(); $device->deviceId = $this->requestData['deviceId']; if (isset($this->requestData['registrationId'])) { $device->registrationId = $this->requestData['registrationId']; } $this->em->persist($device); $this->em->flush(); } //-- Session data. $this->authToken = $response['Data']['authToken']; $this->sessionData = array( 'AuthData' => $response['Data'], 'AuthToken' => $this->authToken ); unset($this->sessionData['AuthData']['authToken']); \Utility\Registry::storeJson('token_' . $this->authToken, $this->sessionData); //-- Device registration. $dealerId = $response['Data']['company']['id']; $registration = $this->em->getRepository('Company\Entity\DeviceRegistration') ->findOneBy( array( 'company' => $dealerId, 'device' => $device->id ) ); if (is_null($registration)) { $registration = new \Company\Entity\DeviceRegistration(); $registration->company = $this->em->getReference('Company\Entity\Company', $dealerId); $registration->profile = $this->em->getReference('User\\Entity\\Profile', $response['Data']['id']); $registration->device = $device; $registration->pushKey = md5($device->deviceId . ':' . $dealerId); $this->em->persist($registration); $this->em->flush(); } else { $registration->profile = $this->em->getReference('User\\Entity\\Profile', $response['Data']['id']); $this->em->flush(); } //-- Response data. $responseData = array( 'authToken' => $this->authToken, 'pushKey' => $registration->pushKey, 'dealerId' => $dealerId, 'profileId' => $response['Data']['id'], 'fullName' => $response['Data']['fullName'], 'permissions' => array( 'accessValuations' => ($response['Data']['permissions']['valuationPage'] && $response['Data']['permissions']['valuationView']) || $response['Data']['permissions']['valuationCreateSales'], 'accessVehicles' => $response['Data']['permissions']['stockPage'] && $response['Data']['permissions']['stockView'], 'salesValuations' => $response['Data']['permissions']['valuationCreateSales'], 'completeValuations' => $response['Data']['permissions']['valuationCreatePending'] || $response['Data']['permissions']['valuationCreateComplete'], 'isTradeCenter' => 'Trade Center' == $response['Data']['company']['dealerType'], 'linkedToTradeCenter' => isset($response['Data']['company']['tradeCenter']['id']) ), 'valuators' => array(), 'allowedAuctionDays' => $this->getAuctionAllowedDays() ); $profiles = $this->em->getRepository('User\\Entity\\Profile') ->findBy( array( 'company' => $dealerId ) ); foreach ($profiles as $profile) { if ($profile->override->valuationCreatePending || $profile->override->valuationCreateComplete ) { $responseData['valuators'][] = array( 'id' => $profile->id, 'fullName' => $profile->firstName . ' ' . $profile->familyName ); } } //-- Done. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $responseData ) ); } else { //-- Authentication fail. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Authentication failure.', 'Data' => new \stdClass() ) ); } } /** * Retrieve available auction end-date list. * @return \Zend\View\Model\JsonModel */ public function getAuctionDaysAction() { //-- Preparations. if (!$this->init()) { return $this->response; } $allowed = $this->getAuctionAllowedDays(); //-- Done. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $allowed ) ); } protected function canUseAuctionDay($time, array $openDays, array $publicDays) { if (7 == date('N', $time)) { return false; } if (6 == date('N', $time) && !in_array(date('Y-m-d', $time), $openDays) ) { return false; } if (in_array(date('Y-m-d', $time), $publicDays)) { return false; } return true; } /** * Retrieve trade and retail from mmCode. * @return \Zend\View\Model\JsonModel */ public function transunionFromMmCodeAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Safety check. if (!isset($this->requestData['mmCode']) || !is_numeric($this->requestData['mmCode']) || !isset($this->requestData['vehicleYear']) || !is_numeric($this->requestData['vehicleYear']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Require mmCode and vehicleYear parameters.', 'Data' => new \stdClass() ) ); } //-- Process request. $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'Filter' => array( 'mmCode' => $this->requestData['mmCode'], 'vehicleYear' => $this->requestData['vehicleYear'], 'mileage' => null, 'condition' => null ) )); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $stockUtilService = $this->serviceLocator->get('Stock.Service.Utility'); $response = $stockUtilService->deviceTransUnionFromMmCode($serviceInput->pack()); if (is_array($response['Data']) && !empty($response['Data']) && isset($response['Data']['VehicleDetails']) && !empty($response['Data']['VehicleDetails']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'NewPrice' => $response['Data']['VehicleDetails'][0]['Value']['NewPrice'], 'RetailPrice' => $response['Data']['VehicleDetails'][0]['Value']['RetailPrice'], 'TradePrice' => $response['Data']['VehicleDetails'][0]['Value']['TradePrice'], 'ListPrice' => $response['Data']['VehicleDetails'][0]['Value']['NewPrice'] ) ) ); } return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not retrieve trade and retail data.', 'Data' => new \stdClass() ) ); } /** * Claim a job item from queue. * @return \Zend\View\Model\JsonModel */ public function claimJobAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Safety check. if (!isset($this->requestData['uvi']) || 0 >= $this->requestData['uvi'] ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Require uvi parameter.', 'Data' => new \stdClass() ) ); } if (isset($this->requestData['uvi'])) { $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13); } //-- Attempt to claim the job for this user. $uvi = $this->requestData['uvi']; $stock = $this->em->getRepository('Stock\\Entity\\Stock') ->findOneBy(array('uvi' => $uvi)); if (is_null($stock) || is_null($stock->valuation)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not find record.', 'Data' => new \stdClass() ) ); } $valuation = $stock->valuation; if (1 != $valuation->queueStatus || !$valuation->claimQueueItem($this->em, $this->profileId)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Job no longer available.', 'Data' => new \stdClass() ) ); } else { $recordId = $valuation->id; $userId = $this->profileId; exec("php /var/www/B4C2/public/index.php stock change 4 $recordId $userId > /dev/null &"); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'uvi' => $uvi ) ) ); } } /** * Claim a job item from queue. * @return \Zend\View\Model\JsonModel */ public function unclaimJobAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Safety check. if (!isset($this->requestData['uvi']) || 0 >= $this->requestData['uvi'] ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Require uvi parameter.', 'Data' => new \stdClass() ) ); } if (isset($this->requestData['uvi'])) { $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13); } //-- Attempt to un-claim this job. $uvi = $this->requestData['uvi']; $stock = $this->em->getRepository('Stock\\Entity\\Stock') ->findOneBy(array('uvi' => $uvi)); if (is_null($stock) || is_null($stock->valuation)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not find record.', 'Data' => new \stdClass() ) ); } $valuation = $stock->valuation; if (2 != $valuation->queueStatus || !$valuation->unclaimQueueItem($this->em)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not un-claim job.', 'Data' => new \stdClass() ) ); } else { $recordId = $valuation->id; $userId = $this->profileId; exec("php /var/www/B4C2/public/index.php stock change 5 $recordId $userId > /dev/null &"); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'uvi' => $uvi ) ) ); } } /** * Get list of valuations. * @return \Zend\View\Model\JsonModel */ public function getValuationsAction() { //-- Preparations. if (!$this->init()) { return $this->response; } if (is_null($this->sessionData)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Authentication required.', 'Data' => new \stdClass() ) ); } //-- Collect valuations. $minDate = new \DateTime('now'); $minDate->sub(new \DateInterval('P90D')); $stockItems = $this->em->createQuery( 'SELECT stock, valuation ' . 'FROM Stock\\Entity\\Stock stock ' . 'JOIN stock.type vehicleType ' . 'JOIN stock.company company ' . 'LEFT JOIN stock.valuation valuation ' . 'WHERE ((IDENTITY(stock.company) = :companyId AND stock.jobState IN (:stockStatusList)) ' . ' OR (IDENTITY(company.tradeCenter) = :companyId AND stock.jobState = :tcStockStatus)) ' . ' AND stock.archived = :archived' . ' AND IDENTITY(vehicleType.category) < 8' . ' AND (IDENTITY(stock.valuation) IS NULL OR (valuation.archived = :archived AND valuation.jobState != :statusArchived))' . ' AND stock.created >= :minDate' ) ->setParameter('companyId', $this->sessionData['AuthData']['company']['id']) ->setParameter('archived', 0) ->setParameter('statusArchived', 'Archived') ->setParameter('minDate', $minDate) ->setParameter('stockStatusList', array('Stock', 'Valuation')) ->setParameter('tcStockStatus', 'Trade Center'); // \Utility\Debug::errorLog('getValuationsAction $stockItems->getSQL()', $stockItems->getSQL()); // \Utility\Debug::errorLog('getValuationsAction $stockItems->getParameters()', $stockItems->getParameters()); $stockItems = $stockItems->getResult(); $responseData = array(); $i = 0; foreach ($stockItems as $stock) { //-- Valuation data. $responseData[$i] = $this->buildValuationData($stock); //-- Done with this valuation. $i++; } //\Utility\Debug::errorLog('$responseData', $responseData); //-- Return to sender. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $responseData ) ); } /** * Get a specific valuation. * @return \Zend\View\Model\JsonModel */ public function getValuationAction() { //-- Preparations. if (!$this->init()) { return $this->response; } if (is_null($this->sessionData)) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Authentication required.', 'Data' => new \stdClass() ) ); } if (!isset($this->requestData['uvi']) || !is_numeric($this->requestData['uvi']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Field uvi required.', 'Data' => new \stdClass() ) ); } if (isset($this->requestData['uvi'])) { $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13); } //-- Collect valuations. $stock = $this->em->getRepository('Stock\\Entity\\Stock') ->findOneBy( array( 'uvi' => $this->requestData['uvi'] ) ); if (is_null($stock)) { //-- Oops, 404. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Stock entry not found.', 'Data' => new \stdClass() ) ); } else { //-- All good. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $this->buildValuationData($stock) ) ); } } /** * Synchronize multiple valuations. * @return \Zend\View\Model\JsonModel */ public function synchValuationsAction() { //-- Preparations. if (!$this->init(true)) { return $this->response; }; \Utility\Registry::set('IsDeviceApiCall', true); //-- Loop through valuations. $response = array(); foreach ($this->requestData as $valuationItem) { //-- Safety checks. $uviii = isset($valuationItem['uvi']) ? $valuationItem['uvi'] : 'null'; if (!isset($valuationItem['dealerId']) || !is_numeric($valuationItem['dealerId']) ) { error_log("synchValuationsAction : $uviii : NO DEALER ID"); $response[] = array( 'error' => 'Field dealerId required.' ); continue; } if (!isset($valuationItem['profileId']) || !is_numeric($valuationItem['profileId']) ) { error_log("synchValuationsAction : $uviii : NO PROFILE ID"); $response[] = array( 'error' => 'Field profileId required.' ); continue; } if (!isset($valuationItem['owner']) || 0 == strlen($valuationItem['owner']) ) { error_log("synchValuationsAction : $uviii : NO OWNER"); $response[] = array( 'error' => 'Field owner required.' ); continue; } if (!isset($valuationItem['status']) || 0 == strlen($valuationItem['status']) ) { error_log("synchValuationsAction : $uviii : NO STATUS"); $response[] = array( 'error' => 'Field status required.' ); continue; } //-- Establish context. $originalUvi = null; if (isset($valuationItem['uvi'])) { $originalUvi = $valuationItem['uvi']; $valuationItem['uvi'] = (int) substr($valuationItem['uvi'], 0, 13); } $uviii = $valuationItem['uvi']; error_log("synchValuationsAction : $originalUvi : $uviii"); $userId = $valuationItem['profileId']; $dealerId = $valuationItem['dealerId']; $existingItem = isset($valuationItem['uvi']); $owner = $valuationItem['owner']; if (0 == $dealerId || 0 == $userId) { $userId = $this->profileId; if (!is_null($userId) && false != $userId && is_numeric($userId)) { $profile = $this->em->find('User\\Entity\\Profile', $userId); $dealerId = $profile->company->id; } } if ($existingItem) { $stock = $this->em->getRepository('Stock\\Entity\\Stock') ->findOneBy( array( 'uvi' => $valuationItem['uvi'] ) ); $existingItem = !is_null($stock); } $valuation = null; if ($existingItem) { $changeCode = 2; $valuation = $stock->valuation; $initialState = 'Valuation' == $owner ? $valuation->jobState : $stock->jobState; } else { $changeCode = 1; $stock = new \Stock\Entity\Stock(); if (isset($valuationItem['uvi']) && !is_null($valuationItem['uvi']) && 0 < strlen($valuationItem['uvi']) ) { $stock->uvi = $valuationItem['uvi']; } $stock->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId); $stock->company = $this->em->getReference('Company\\Entity\\Company', $dealerId); $this->em->persist($stock); if ('Valuation' == $owner) { $valuation = new \Valuation\Entity\Valuation(); $valuation->stock = $stock; $valuation->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId); $this->em->persist($valuation); } } //-- Collect stock data. $stock->type = $this->em->getReference( 'Stock\\Entity\\Type', $valuationItem['vehicleModelTypeId'] ); $stock->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId); $stock->company = $this->em->getReference('Company\\Entity\\Company', $dealerId); //\Utility\Debug::errorLog('$valuationItem', $valuationItem); if (isset($valuationItem['stockNumber']) && 0 < strlen($valuationItem['stockNumber'])) { $stock->stockNumber = $valuationItem['stockNumber']; } if (isset($valuationItem['licenceNumber'])) { $stock->registrationNumber = $valuationItem['licenceNumber']; } if (isset($valuationItem['vinNumber'])) { $stock->vinNumber = $valuationItem['vinNumber']; } if (isset($valuationItem['engineNumber'])) { $stock->engineNumber = $valuationItem['engineNumber']; } if (isset($valuationItem['fuelTypeId']) && 0 < $valuationItem['fuelTypeId'] ) { $stock->fuelType = $this->em->getReference( 'Stock\\Entity\\FuelType', $valuationItem['fuelTypeId'] ); } if (isset($valuationItem['transmissionTypeId']) && 0 < $valuationItem['transmissionTypeId'] ) { $stock->transmissionType = $this->em->getReference( 'Stock\\Entity\\TransmissionType', $valuationItem['transmissionTypeId'] ); } if (isset($valuationItem['exteriorColourId']) && 0 < $valuationItem['exteriorColourId'] ) { $stock->exteriorColour = $this->em->getReference( 'Stock\\Entity\\ExteriorColour', $valuationItem['exteriorColourId'] ); } if (isset($valuationItem['interiorColourId']) && 0 < $valuationItem['interiorColourId'] ) { $stock->interiorColour = $this->em->getReference( 'Stock\\Entity\\InteriorColour', $valuationItem['interiorColourId'] ); } if (isset($valuationItem['vehicleConditionId']) && 0 < $valuationItem['vehicleConditionId'] ) { $stock->condition = $this->em->getReference( 'Stock\\Entity\\Condition', $valuationItem['vehicleConditionId'] ); } if (isset($valuationItem['vehicleYearId']) && 0 < $valuationItem['vehicleYearId'] ) { $stock->vehicleYear = $this->em->getReference( 'Stock\\Entity\\Year', $valuationItem['vehicleYearId'] ); } if (isset($valuationItem['vehicleMileage'])) { $stock->km = $valuationItem['vehicleMileage']; } if (isset($valuationItem['upholsteryId']) && 0 < $valuationItem['upholsteryId'] ) { $stock->upholstery = $this->em->getReference( 'Stock\\Entity\\Upholstery', $valuationItem['upholsteryId'] ); } if (isset($valuationItem['spareKeysId']) && 0 < $valuationItem['spareKeysId'] ) { $stock->spareKeys = $valuationItem['spareKeysId']; } if (isset($valuationItem['fullServiceHistoryId']) && 0 < $valuationItem['fullServiceHistoryId'] ) { $stock->fullServiceHistory = $this->em->getReference( 'Stock\\Entity\\FullServiceHistory', $valuationItem['fullServiceHistoryId'] ); } if (isset($valuationItem['fullServiceHistoryNotes'])) { $stock->fshNotes = $valuationItem['fullServiceHistoryNotes']; } if (isset($valuationItem['tradePrice'])) { $stock->tradePrice = $valuationItem['tradePrice']; } if (isset($valuationItem['retailPrice'])) { $stock->retailPrice = $valuationItem['retailPrice']; } if (isset($valuationItem['listPrice'])) { $stock->listPrice = $valuationItem['listPrice']; } if ($existingItem) { foreach ($stock->accessories as $accessory) { $this->em->remove($accessory); } foreach ($stock->damages as $damage) { $this->em->remove($damage); } $this->em->flush(); } if (isset($valuationItem['accessories']) && 0 < strlen($valuationItem['accessories']) ) { $idList = explode(':', $valuationItem['accessories']); foreach ($idList as $accessoryId) { $stockAccessory = new \Stock\Entity\StockAccessory(); $stockAccessory->stock = $stock; $stockAccessory->accessory = $this->em->getReference( 'Stock\\Entity\\Accessory', $accessoryId ); $this->em->persist($stockAccessory); } } if (isset($valuationItem['accessoriesComments'])) { $stock->accessoryNotes = $valuationItem['accessoriesComments']; } $damageTotal = 0.0; if (isset($valuationItem['damages'])) { if (!is_array($valuationItem['damages'])) { $valuationItem['damages'] = json_decode($valuationItem['damages'], true); } if (0 < count($valuationItem['damages'])) { foreach ($valuationItem['damages'] as $damageItem) { if ((float)$damageItem['amount'] == 0.0) { continue; } $damage = new \Stock\Entity\StockDamage(); $damage->stock = $stock; $damage->damage = $this->em->getReference( 'Stock\\Entity\\Damage', $damageItem['serverId'] ); $damage->amount = $damageItem['amount']; $this->em->persist($damage); $damageTotal += (float)$damageItem['amount']; } } } if (isset($valuationItem['damagesEstimatedRepairCost'])) { $stock->damageTotal = $damageTotal; } if (isset($valuationItem['damagesComments'])) { $stock->damageNotes = $valuationItem['damagesComments']; } if (isset($valuationItem['damagesPreviousRepairsNoted'])) { $stock->previousRepairsNoted = $valuationItem['damagesPreviousRepairsNoted']; } if (isset($valuationItem['damagesPreviousRepairsComments'])) { $stock->previousRepairsNotes = $valuationItem['damagesPreviousRepairsComments']; } //-- Valuation data. if ('Valuation' == $owner) { $valuation->createdBy = $this->em->getReference('User\\Entity\\Profile', $userId); if (isset($valuationItem['customerName'])) { $valuation->firstName = $valuationItem['customerName']; } if (isset($valuationItem['customerSurname'])) { $valuation->familyName = $valuationItem['customerSurname']; } if (isset($valuationItem['customerCellNumber'])) { $valuation->mobile = $valuationItem['customerCellNumber']; } if (isset($valuationItem['offer']) && 0 < $valuationItem['offer']) { $valuation->amountOffered = $valuationItem['offer']; } } //-- Status. if ('Valuation' == $owner) { $stock->jobState = 'Valuation'; $valuation->jobState = $valuationItem['status']; if (isset($valuationItem['previousStatus']) && '' != $valuationItem['previousStatus']) { $valuation->previousState = $valuationItem['previousStatus']; } } else { if (!is_null($valuation)) { $valuation->previousState = $valuation->jobState; $valuation->jobState = 'Stock'; $this->em->flush($valuation); } $stock->jobState = $valuationItem['status']; if (isset($valuationItem['previousStatus']) && '' != $valuationItem['previousStatus']) { $stock->previousState = $valuationItem['previousStatus']; } } //-- Flush data. try { $this->em->flush($stock); $stock->postInsert(); if ('Valuation' == $owner) { $this->em->flush($valuation); } $stock->valuation = $valuation; $this->em->flush(); $response[] = array( 'modifiedUvi' => (int) substr($stock->uvi, 0, 13), 'uvi' => $originalUvi ); } catch (\Exception $e) { if (1452517638893 == $originalUvi) { $response[] = array( 'modifiedUvi' => (int) $originalUvi, 'uvi' => $originalUvi ); } else { \Utility\Debug::errorLog(__METHOD__ . ':SynchValuationError on dealer:user', "$dealerId : $userId on $originalUvi"); \Utility\Debug::errorLog(__METHOD__ . ':$valuationItem', $valuationItem); \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); $response[] = array( 'error' => 'Could not create entry.' ); } continue; } \Utility\Debug::errorLog('$initialState', $initialState); \Utility\Debug::errorLog('$valuationItem[status]', $valuationItem['status']); //-- Actions to apply. if (!$existingItem || $initialState != $valuationItem['status'] ) { if ('Valuation' == $owner) { error_log("synchValuationsAction : $originalUvi " . print_r($valuationItem, true)); if ('New Valuation' == $valuation->jobState && 0 < $valuationItem['valuator'] ) { //-- Send to valuator. if (!$this->sendToValuator($valuationItem, $valuation)) { //-- Failed sending to Valuator. $this->em->flush(); } } if ('Price Guide' == $valuation->jobState) { //-- Attempt sending to Price Guide. if (!$this->sendValuationToPriceGuide($valuationItem, $valuation)) { //-- Failed sending to Price Guide. $valuation->jobState = 'Pending Valuation'; $this->em->flush(); } } } else { \Utility\Debug::errorLog('in else', $stock->jobState); if ('Auction' == $stock->jobState) { //-- Attempt sending to auction. if (!$this->sendToAuction($valuationItem, $stock)) { //-- Failed sending to Valuator. $this->em->flush(); } } if ('Price Guide' == $stock->jobState) { //-- Attempt sending to Price Guide. if (!$this->sendStockToPriceGuide($valuationItem, $stock)) { //-- Failed sending to Price Guide. $stock->jobState = 'Stock'; $this->em->flush(); } } if ('Trade Center' == $stock->jobState) { //-- Attempt sending to Trade Center. $stock->jobState = 'Stock'; $this->em->flush(); if (!$this->sendStockToTradeCenter($valuationItem, $stock)) { //-- Failed sending to Price Guide. $stock->jobState = 'Stock'; $this->em->flush(); } } } } //-- Change notification. $owner = 'Valuation' == $owner ? 'valuation' : 'stock'; $recordId = 'Valuation' == $owner ? $valuation->id : $stock->id; exec("php /var/www/B4C2/public/index.php stock change $changeCode $recordId $userId > /dev/null &"); error_log("synchValuationsAction : $originalUvi : \\o/"); } \Utility\Debug::errorLog('\Zend\View\Model\JsonModel', array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $response )); //-- Return to sender. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $response ) ); } /** * Synchronize multiple photos. * @return \Zend\View\Model\JsonModel */ public function synchPhotosAction() { //-- Preparations. if (!$this->init(true, true)) { return $this->response; } //-- Loop through valuations. $filePath = \Utility\Registry::getConfigParam('ImagePath'); $thumbPath = \Utility\Registry::getConfigParam('ThumbnailPath'); //-- Safety checks. if (!isset($this->requestData['uvi']) || !is_numeric($this->requestData['uvi']) ) { error_log("synchPhotosAction : NON NUMERIC UVI : " . (!isset($this->requestData['uvi']) ? 'NO UVI' : $this->requestData['uvi'])); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Field uvi required.', 'Data' => new \stdClass() ) ); } if (!isset($this->requestData['type']) || empty($this->requestData['type']) ) { error_log("synchPhotosAction : FIELD TYPE REQUIRED : "); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Field type required.', 'Data' => new \stdClass() ) ); } $originalUvi = null; if (isset($this->requestData['uvi'])) { $originalUvi = $this->requestData['uvi']; $this->requestData['uvi'] = (int) substr($this->requestData['uvi'], 0, 13); } error_log("synchPhotosAction : $originalUvi >> " . $this->requestData['uvi']); //-- Get stock item. $uvi = $this->requestData['uvi']; $type = $this->requestData['type']; $newFileName = $filePath . $type . $uvi . '.jpg'; $stock = $this->em ->getRepository('Stock\\Entity\\Stock') ->findOneBy(array('uvi' => $this->requestData['uvi'])); if (is_null($stock)) { error_log("synchPhotosAction : $originalUvi >> COULD NOT FIND STOCK ENTRY"); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not find stock entry.', 'Data' => new \stdClass() ) ); } //-- Save the image. ini_set('memory_limit', '512M'); if (!move_uploaded_file($_FILES['photo']['tmp_name'], $newFileName) || !file_exists($newFileName)) { error_log("synchPhotosAction : $originalUvi >> COULD NOT MOVE TEMP FILE"); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Could not move temp file.', 'Data' => new \stdClass() ) ); } $photo = file_get_contents($newFileName, FILE_BINARY); $this->resizeImage($photo, 'image/jpeg', $thumbPath . $type . $uvi . '.jpg'); $image = new \Utility\Entity\Image(); $image->filename = $type . $uvi . '.jpg'; $image->mimeType = 'image/jpeg'; $this->em->persist($image); $this->em->flush(); //-- Update stock entry. switch (strtoupper($type)) { case 'MAIN': $stock->mainImage = $image; break; case 'FRONT': $stock->frontImage = $image; break; case 'RIGHT': $stock->rightImage = $image; break; case 'LEFT': $stock->leftImage = $image; break; case 'BACK': $stock->backImage = $image; break; case 'ENGINE': $stock->engineImage = $image; break; case 'INTERIOR': $stock->interiorImage = $image; break; case 'NATIS': $stock->natisImage = $image; break; } $this->em->flush(); $response = array( 'modifiedUvi' => $uvi, 'uvi' => $originalUvi, 'type' => $type ); exec("php /var/www/B4C2/public/index.php stock change 2 " . $stock->id . " 0 > /dev/null &"); //-- Return to sender. error_log("synchPhotosAction : " . print_r($response, true)); error_log("synchPhotosAction : $originalUvi >> \\o/"); return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => $response ) ); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ public function getMakesAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Let the utility handle it. $this->requestData['datasetName'] = 'makes'; return $this->getDataUpdatesAction(); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ public function getModelsAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Let the utility handle it. $this->requestData['datasetName'] = 'models'; return $this->getDataUpdatesAction(); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ public function getTypesAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Let the utility handle it. $this->requestData['datasetName'] = 'types'; return $this->getDataUpdatesAction(); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ public function getYearsAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Let the utility handle it. $this->requestData['datasetName'] = 'years'; return $this->getDataUpdatesAction(); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ public function getAccessoriesAction() { //-- Preparations. if (!$this->init()) { return $this->response; } //-- Let the utility handle it. $this->requestData['datasetName'] = 'accessories'; return $this->getDataUpdatesAction(); } /** * Get up to date with latest data. * @return \Zend\View\Model\JsonModel */ protected function getDataUpdatesAction() { //-- Safety checks. if (!isset($this->requestData['datasetName']) || 0 == strlen($this->requestData['datasetName']) ) { return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Field datasetName required.', 'Data' => new \stdClass() ) ); } //-- Context. switch ($this->requestData['datasetName']) { #-> Location case 'countries': $entityName = '\Location\Entity\Country'; break; case 'regions': $entityName = '\Location\Entity\Region'; break; case 'towns': $entityName = '\Location\Entity\Town'; break; #-> Stock case 'valuations': $entityName = '\Valuation\Entity\Valuation'; break; case 'accessories': $entityName = '\Stock\Entity\Accessory'; break; case 'damages': $entityName = '\Stock\Entity\Damage'; break; case 'upholstery': $entityName = '\Stock\Entity\Upholstery'; break; case 'condition': $entityName = '\Stock\Entity\Condition'; break; case 'exteriorColours': $entityName = '\Stock\Entity\ExteriorColour'; break; case 'interiorColours': $entityName = '\Stock\Entity\InteriorColour'; break; case 'fuelTypes': $entityName = '\Stock\Entity\FuelType'; break; case 'fullServiceHistory': $entityName = '\Stock\Entity\FullServiceHistory'; break; case 'transmissionTypes': $entityName = '\Stock\Entity\TransmissionType'; break; case 'natis': $entityName = '\Stock\Entity\Natis'; break; case 'papers': $entityName = '\Stock\Entity\Paper'; break; case 'years': $entityName = '\Stock\Entity\Year'; break; case 'categories': $entityName = '\Stock\Entity\Category'; break; case 'makes': $entityName = '\Stock\Entity\Make'; break; case 'models': ini_set('memory_limit', '512M'); $entityName = '\Stock\Entity\Model'; break; case 'types': ini_set('memory_limit', '1024M'); $entityName = '\Stock\Entity\Type'; break; default: return new \Zend\View\Model\JsonModel( array( 'Status' => 'Error', 'Reason' => 'Invalid datasetName ' . $this->requestData['datasetName'] . ' requested.', 'Data' => new \stdClass() ) ); break; } //-- Collect relevant data. $responseData = array(); $version = isset($this->requestData['version']) && is_numeric($this->requestData['version']) ? $this->requestData['version'] : 0; $maxVersion = $version; $version++; if ('Build' == $entityName::PULL_SYNCH_STRATEGY) { $filter = 'WHERE 1=1'; $filter .= defined($entityName . '::JOB_QUEUE') ? ' AND a.queueStatus = 1' : ''; $filter .= $entityName::ARCHIVE ? ' AND a.archived = 0' : ''; if (method_exists($entityName, 'getSynchQuery')) { $query = $this->em->createQuery( $entityName::getSynchQuery() ); } else { $query = $this->em->createQuery( "SELECT a FROM $entityName a $filter ORDER BY a.id ASC" ); } $responseData = $query->getResult(); if (defined($entityName . '::JOB_QUEUE')) { foreach ($responseData as $rowId => $record) { $responseData[$rowId] = $record->toQueueArray(); } } else { foreach ($responseData as $rowId => $record) { $responseData[$rowId] = $record->toSynchArray(); } } } else { //-- Synchronization modification from entity context. $filter = '1=1'; $filter .= defined($entityName . '::JOB_QUEUE') ? ' AND a.queueStatus = 1' : ''; $filter .= $entityName::ARCHIVE ? ' AND a.archived = 0' : ''; if (method_exists($entityName, 'getSynchFilter')) { $synchMod = $entityName::getSynchFilter(); } else { $synchMod = array( 'Join' => '', 'Filter' => '' ); } //-- Get latest version number. $versionResult = $this->em->createQuery( "SELECT MAX(a.createVersion) AS maxCreateVersion, " . " MAX(a.updateVersion) AS maxUpdateVersion " . "FROM $entityName a " . $synchMod['Join'] . "WHERE $filter " . $synchMod['Filter'] . " ORDER BY a.id ASC" ) ->getScalarResult(); $maxVersion = $versionResult[0]['maxCreateVersion']; if ($maxVersion < $versionResult[0]['maxUpdateVersion']) { $maxVersion = $versionResult[0]['maxUpdateVersion']; } //-- Records to add. $query = "SELECT [SELECTION] " . "FROM $entityName a " . $synchMod['Join'] . "WHERE a.archived = :archived" . " AND $filter " . $synchMod['Filter'] . " AND a.createVersion BETWEEN :version AND :maxVersion" . " ORDER BY a.id ASC"; $params = array( 'archived' => false, 'version' => $version, 'maxVersion' => $maxVersion ); $queryResult = $this->em->createQuery( str_replace('[SELECTION]', 'a', $query) ) ->setParameters($params) ->iterate(); $responseData['Create'] = array(); if (defined($entityName . '::JOB_QUEUE')) { foreach ($queryResult as $rowId => $record) { $responseData['Create'][$rowId] = $record[0]->toQueueArray(); } } else { foreach ($queryResult as $rowId => $record) { $responseData['Create'][$rowId] = $record[0]->toSynchArray(); } } //-- Records to update. $query = "SELECT [SELECTION] " . "FROM $entityName a " . $synchMod['Join'] . "WHERE a.archived = :archived" . " AND $filter " . $synchMod['Filter'] . " AND a.createVersion < :version" . " AND a.updateVersion BETWEEN :version AND :maxVersion" . " ORDER BY a.id ASC"; $params = array( 'archived' => false, 'version' => $version, 'maxVersion' => $maxVersion ); $queryResult = $this->em->createQuery( str_replace('[SELECTION]', 'a', $query) ) ->setParameters($params) ->iterate(); $responseData['Update'] = array(); if (defined($entityName . '::JOB_QUEUE')) { foreach ($queryResult as $rowId => $record) { $responseData['Update'][$rowId] = $record[0]->toQueueArray(); } } else { foreach ($queryResult as $rowId => $record) { $responseData['Update'][$rowId] = $record[0]->toSynchArray(); } } //-- Records to remove. $responseData['Delete'] = array(); } //-- Done. return new \Zend\View\Model\JsonModel( array( 'Status' => 'Success', 'Reason' => 'Awesomeness.', 'Data' => array( 'version' => $maxVersion, 'strategy' => $entityName::PULL_SYNCH_STRATEGY, 'changes' => $responseData ) ) ); } /** * Utility to send stuff to Trade Center. * @param $valuationItem * @param $stock * @return bool */ private function sendStockToTradeCenter($valuationItem, $stock) { //-- Pass it along. try { $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'id' => $stock->id, 'Context' => array() )); $wStock = $this->serviceLocator->get('Stock'); $wStock->loadJob($stock->id); $wStock->directRoute('Stock.SendToTradeCenter', $stock->id); } catch (\Exception $e) { \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); return false; } return true; } /** * Utility to send stuff to Auction. * @param $valuationItem * @param $stock * @return bool */ private function sendToAuction($valuationItem, $stock) { //\Utility\Debug::errorLog('sendToAuction $valuationItem', $valuationItem); //-- Update trade and retail pricing. if (8 != $stock->type->category->id) { try { $tu = new \Utility\Comms\TransUnion(); $data = $tu->searchByMmCode( $stock->type->mmCode, $stock->vehicleYear->name, null, null ); } catch (\Exception $e) { $data = false; \Utility\Debug::errorLog( 'Exception on fetching trade and retail for Device send to auction', $e->getMessage() ); } if (is_array($data) && isset($data['VehicleDetails']) && isset($data['VehicleDetails'][0]) && isset($data['VehicleDetails'][0]['Value']) ) { $this->tradePriceDate = new \DateTime('now'); $this->oldTradePriceDate = new \DateTime('now'); $this->listPriceDate = new \DateTime('now'); $this->oldListPriceDate = new \DateTime('now'); $stock->oldTradePrice = $stock->tradePrice; $stock->oldRetailPrice = $stock->retailPrice; $stock->oldListPrice = $stock->listPrice; $stock->tradePrice = $data['VehicleDetails'][0]['Value']['TradePrice']; $stock->retailPrice = $data['VehicleDetails'][0]['Value']['RetailPrice']; $stock->listPrice = $data['VehicleDetails'][0]['Value']['NewPrice']; $this->em->flush($stock); } } //-- Pass it along. try { $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'id' => $stock->id, 'Context' => array( 'endDate' => date('Y-m-d H:i:s', ((int)$valuationItem['auctionEndDate'] / 1000)), 'reservePrice' => $valuationItem['auctionReservePrice'], 'profileId' => $this->profileId ) )); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $wStock = $this->serviceLocator->get('Stock'); $wStock->loadJob($stock->id); $wStock->executeRoute('Stock.SendToAuction', $stock->id, $serviceInput->pack()); } catch (\Exception $e) { \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); return false; } return true; } /** * Utility to send stuff to Valuator(s). * @param $valuationItem * @param $valuation * @return bool */ private function sendToValuator($valuationItem, $valuation) { //-- Pass it along. try { $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'id' => $valuation->id, 'Valuation' => array( 'valuators' => isset($valuationItem['valuators']) ? $valuationItem['valuators'] : array($valuationItem['valuator']) ))); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $sValuation = new \Valuation\Service\Valuation(); $sValuation->setWorkflow($this->serviceLocator->get('Valuation')); $sValuation->sendToValuators(array(), $valuation, $valuation, $serviceInput->pack()); } catch (\Exception $e) { \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); return false; } return true; } /** * Utility to send stuff to Price Guide. * @param $valuationItem * @param $valuation * @return bool */ private function sendValuationToPriceGuide($valuationItem, $valuation) { //-- Which clubs to send to? $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club') ->findBy( array( 'company' => $valuationItem['dealerId'], 'useAsDefault' => true, 'archived' => false ) ); if (0 == count($clubs)) { $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club') ->findBy( array( 'company' => $valuationItem['dealerId'], 'archived' => false ) ); } if (0 == count($clubs)) { //-- No clubs to send to, abort. return false; } //-- Pass it along the complicated internal process. $sendTo = array(); foreach ($clubs as $club) { $sendTo[] = array('id' => $club->id); } try { $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'id' => $valuation->id, 'Context' => array( 'clubs' => $sendTo ), 'Valuation' => array( 'firstName' => $valuation->firstName, 'familyName' => $valuation->familyName, 'mobile' => $valuation->mobile ), 'Stock' => array( 'vehicleYear' => $valuation->stock->vehicleYear->id, 'type' => $valuation->stock->type->id, 'registrationNumber' => $valuation->stock->registrationNumber, 'fuelType' => $valuation->stock->fuelType->id, 'transmissionType' => $valuation->stock->transmissionType->id ))); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $wValuation = $this->serviceLocator->get('Valuation'); $wValuation->loadJob($valuation->id); $wValuation->executeRoute('Valuation.SendToPriceGuide', $valuation->id, $serviceInput->pack()); } catch (\Exception $e) { \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); return false; } return true; } /** * Utility to send stuff to Price Guide. * @param $valuationItem * @param $stock * @return bool */ private function sendStockToPriceGuide($valuationItem, $stock) { //-- Which clubs to send to? $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club') ->findBy( array( 'company' => $valuationItem['dealerId'], 'useAsDefault' => true, 'archived' => false ) ); if (0 == count($clubs)) { $clubs = $this->em->getRepository('PriceGuide\\Entity\\Club') ->findBy( array( 'company' => $valuationItem['dealerId'], 'archived' => false ) ); } if (0 == count($clubs)) { //-- No clubs to send to, abort. return false; } //-- Pass it along the complicated internal process. $sendTo = array(); foreach ($clubs as $club) { $sendTo[] = array('id' => $club->id); } try { $input = new \Workspace\Utility\ServiceInput('ParamSet', array( 'id' => $stock->id, 'Context' => array( 'clubs' => $sendTo ))); $serviceInput = new \Workspace\Utility\ServiceInput('ServiceInput', array( 'data' => $input->pack() )); $wStock = $this->serviceLocator->get('Stock'); $wStock->loadJob($stock->id); $wStock->executeRoute('Stock.SendToPriceGuide', $stock->id, $serviceInput->pack()); } catch (\Exception $e) { \Utility\Debug::errorLog(__METHOD__ . ':EXCEPTION', $e->getMessage()); \Utility\Debug::errorLog(__METHOD__ . ':TRACE', $e->getTraceAsString()); return false; } return true; } /** * Build valuation data for device.. * @param \Stock\Entity\Stock $stock * @return array */ private function buildValuationData($stock) { //-- Valuation data. $responseData = array( 'uvi' => (int)$stock->uvi, 'profileId' => $stock->createdBy->id, 'dealerId' => $stock->company->id, 'tradeCenterId' => 'Trade Center' == $stock->jobState && !is_null($stock->company->tradeCenter) ? $stock->company->tradeCenter->id : 0, 'customerName' => !is_null($stock->valuation) ? $stock->valuation->firstName : '', 'customerSurname' => !is_null($stock->valuation) ? $stock->valuation->familyName : '', 'customerCellNumber' => !is_null($stock->valuation) ? $stock->valuation->mobile : '', 'vehicleYearId' => $stock->vehicleYear->id, 'vehicleCategoryId' => $stock->type->category->id, 'vehicleMakeId' => $stock->type->model->make->id, 'vehicleModelId' => $stock->type->model->id, 'vehicleModelTypeId' => $stock->type->id, 'vehicleConditionId' => !is_null($stock->condition) ? $stock->condition->id : 0, 'vehicleMileage' => $stock->km, 'vehicleMakeName' => $stock->type->model->make->name, 'vehicleModelName' => $stock->type->model->name, 'tradePrice' => (float)$stock->tradePrice, 'retailPrice' => (float)$stock->retailPrice, 'listPrice' => (float)$stock->listPrice, 'licenceNumber' => $stock->registrationNumber, 'vinNumber' => $stock->vinNumber, 'engineNumber' => $stock->engineNumber, 'fuelTypeId' => !is_null($stock->fuelType) ? $stock->fuelType->id : 0, 'transmissionTypeId' => !is_null($stock->transmissionType) ? $stock->transmissionType->id : 0, 'exteriorColourId' => !is_null($stock->exteriorColour) ? $stock->exteriorColour->id : 0, 'interiorColourId' => !is_null($stock->interiorColour) ? $stock->interiorColour->id : 0, 'upholsteryId' => !is_null($stock->upholstery) ? $stock->upholstery->id : 0, 'spareKeysId' => is_null($stock->spareKeys) ? -1 : ($stock->spareKeys ? 0 : 1), 'fullServiceHistoryId' => !is_null($stock->fullServiceHistory) ? $stock->fullServiceHistory->id : 0, 'fullServiceHistoryNotes' => $stock->fshNotes, 'accessories' => '', 'accessoriesComments' => $stock->accessoryNotes, 'damages' => array(), 'damagesEstimatedRepairCost' => (float)$stock->damageTotal, 'damagesComments' => $stock->damageNotes, 'damagesPreviousRepairsNoted' => $stock->previousRepairsNoted, 'damagesPreviousRepairsComments' => $stock->previousRepairsNotes, 'owner' => !is_null($stock->valuation) && 'Valuation' == $stock->jobState ? 'Valuation' : 'Stock', 'status' => !is_null($stock->valuation) && 'Valuation' == $stock->jobState ? $stock->valuation->jobState : $stock->jobState, 'queueStatus' => !is_null($stock->valuation) ? $stock->valuation->queueStatus : 0, 'offer' => !is_null($stock->valuation) ? (float)$stock->valuation->amountOffered : 0.0, 'stockNumber' => $stock->stockNumber, 'auctionEndDate' => !is_null($stock->auction) && 'Active' == $stock->auction->jobState ? $stock->auction->endDate->getTimestamp() * 1000 : 0, 'auctionReservePrice' => !is_null($stock->auction) ? (float)$stock->auction->reservePrice : 0.0, 'photos' => array() ); if ('Stock' == $stock->jobState && !is_null($stock->auction) && 'Relist' == $stock->auction->jobState ) { $responseData['status'] = 'Relist'; } // \Utility\Debug::errorLog('buildValuationData $responseData', $responseData); //-- Linked accessories. $accessories = array(); foreach ($stock->accessories as $accessory) { $accessories[] = $accessory->accessory->id; } if (0 < count($accessories)) { $responseData['accessories'] = implode(':', $accessories); } //-- Linked damages. $damages = array(); foreach ($stock->damages as $damage) { if ($damage->archived) { continue; } $damages[] = array( 'serverId' => $damage->damage->id, 'amount' => (float)$damage->amount ); } $responseData['damages'] = $damages; //-- Photos $photoMap = array( 'main', 'front', 'right', 'left', 'back', 'interior', 'engine', 'natis' ); $photos = array(); foreach ($photoMap as $type) { $fieldName = $type . 'Image'; if (!is_null($stock->$fieldName)) { $photos[] = array( 'uvi' => (int)$stock->uvi, 'serverId' => $stock->$fieldName->id, 'type' => $type, 'webUri' => '/img/bin/thumbnail/' . $stock->$fieldName->filename ); } } $responseData['photos'] = $photos; return $responseData; } /** * Image resizing. * @param $imgString * @param $mimeType * @param $destination * @return bool */ private function resizeImage($imgString, $mimeType, $destination) { $tmpFile = $destination; file_put_contents($tmpFile, $imgString); list($img_width, $img_height) = getimagesize($tmpFile); unlink($tmpFile); if (!$img_width || !$img_height) { return false; } $src_img = imagecreatefromstring($imgString); $scale = min( 300 / $img_width, 200 / $img_height ); if ($scale >= 1) { file_put_contents($tmpFile, $imgString); return true; } $new_width = $img_width * $scale; $new_height = $img_height * $scale; $new_img = @imagecreatetruecolor($new_width, $new_height); switch ($mimeType) { case 'image/jpeg': case 'image/pjpeg': $write_image = 'imagejpeg'; $image_quality = 95; break; case 'image/gif': @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); $write_image = 'imagegif'; $image_quality = null; break; case 'image/png': @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0)); @imagealphablending($new_img, false); @imagesavealpha($new_img, true); $write_image = 'imagepng'; $image_quality = 9; break; case 'image/bmp': case 'image/x-windows-bmp': $write_image = 'imagebmp'; $image_quality = null; break; default: return false; } $success = @imagecopyresampled( $new_img, $src_img, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height ); if ($success) { $write_image($new_img, $tmpFile, $image_quality); @imagedestroy($src_img); @imagedestroy($new_img); return true; } @imagedestroy($src_img); @imagedestroy($new_img); return false; } /** * @return array * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\TransactionRequiredException */ protected function getAuctionAllowedDays() { //-- Establish dealer group for user. $openDays = array(); $profile = $this->em->find('User\\Entity\\Profile', $this->profileId); $groupId = null; if (!is_null($profile->company) && !is_null($profile->company->groupDivision) && !is_null($profile->company->groupDivision->group) ) { $groupId = $profile->company->groupDivision->group->id; } if (!is_null($groupId)) { //-- Get open days for relevant group. $days = $this->em->createQuery( 'SELECT openDayGroup, openDay ' . 'FROM Auction\\Entity\\OpenDayGroup openDayGroup ' . 'JOIN openDayGroup.openDay openDay ' . 'WHERE IDENTITY(openDayGroup.companyGroup) = :groupId' . ' AND openDay.openDate > :startDate' ) ->setParameter('groupId', $groupId) ->setParameter('startDate', new \DateTime('now')) ->getResult(); foreach ($days as $publicDay) { $openDays[] = $publicDay->openDay->openDate->format('Y-m-d'); } } //-- Get public holidays. $publicDays = array(); $days = $this->em->createQuery( 'SELECT publicHoliday ' . 'FROM Auction\\Entity\\PublicHoliday publicHoliday ' . 'WHERE publicHoliday.holiday > :startDate' ) ->setParameter('startDate', new \DateTime('now')) ->getResult(); foreach ($days as $publicDay) { $publicDays[] = $publicDay->holiday->format('Y-m-d'); } $days = null; //-- Get auction max days. $config = \Utility\Cache::fetchEntity( 'Config\Entity\Config', 1, \Utility\Registry::getEntityManager(), 600 ); $maxDays = $config['auctionMaxDays']; //-- Compute. $day = time() + 86400; $allowed = array(); if ($this->canUseAuctionDay($day, $openDays, $publicDays)) { $allowed[] = date('Y-m-d', $day); } for ($i = 1; $i < $maxDays; $i++) { //-- Move to next day. $day += 86400; //-- Check if we can use this day. if ($this->canUseAuctionDay($day, $openDays, $publicDays)) { $allowed[] = date('Y-m-d', $day); } } return $allowed; } }