2 namespace Stock\Service;
4 use Stock\Utility\DataStore;
5 use Stock\Utility\BulkImportHelper;
6 use Stock\Utility\ImportUtility;
8 use Utility\Import\Csv as ImportCsv;
9 use Workspace\Contract\UseOnce as ContractUseOnce;
10 use Workspace\Service\DataBin as DataBinCore;
11 use Workspace\UseCase\Options as UseCaseOptions;
12 use Workspace\UseCase\Requirement as UseCaseRequirement;
13 use Workspace\Utility\ServiceInputParams;
14 use Zend\Form\Element\DateTime;
19 * @package Stock\Service
20 * @author Andre Fourie
22 class BulkImport extends DataBinCore
26 * @var \Stock\Utility\ImportUtility
30 * @var \Stock\Utility\BulkImportHelper
34 * @var \Stock\Utility\DataStore
38 * @var \Utility\Import\Csv
44 public $previousMmCode;
49 public $exceptions = array();
54 public $recordCounter = 0;
55 public $successCounter = 0;
56 public $failedCounter = 0;
58 #-------------------------------------------------- API INTERFACE
60 * Contract to Upload and run the TU data import.
61 * @return \Workspace\Contract\UseOnce
63 public function contractUpload()
65 $requirement = new UseCaseRequirement();
66 $requirement->addRequiredInput(
70 'importType' => 'String255'
74 return new ContractUseOnce(
81 * Upload and run the TU data import.
82 * @param object|null $jobRecord
83 * @param \Workspace\Utility\ServiceInputParams $contract
86 public function executeUpload($jobRecord, ServiceInputParams $contract)
88 // \Utility\Debug::errorLog('executeUpload $contract->data', $contract->data);
91 $uploadId = $contract->data->Upload['csvFile'];
92 $document = $this->em->find('Utility\\Entity\\Document', $uploadId);
93 if (is_null($document))
96 'Bulk Data Import EXCEPTION',
97 'Could not find document id: ' . $uploadId
101 $fileName = $document->filename;
102 $importType = $contract->data->Upload['importType'];
104 $this->offlineBulkDataImport($fileName,$importType);
106 return $contract->success('Import being processed.', array());
114 protected function offlineBulkDataImport($fileName,$importType)
117 // 'php /var/www/namibia/public/index.php bulk vehicle import '
118 // . $fileName . ' ' . $importType
119 // . ' >>/log/php.log &'
122 $authData = \Utility\Registry::getAuthData();
123 $companyId = isset($authData['company']['id']) ? $authData['company']['id'] : null;
124 $userId = isset($authData['id']) ? $authData['id'] : null;
127 // 'php /var/www/NIRPH/Bid4Cars2Repo/public/index.php bulk vehicle import '
128 // . $fileName . ' ' . $importType . ' ' . $userId . ' ' . $companyId
129 // . ' >>/log/php.log &'
133 'php /var/www/namibia/public/index.php bulk vehicle import '
134 . $fileName . ' ' . $importType . ' ' . $userId . ' ' . $companyId
135 . ' >>/log/php.log &'
141 #-------------------------------------------------- OFFLINE PROCESSING
143 * CRON functionality: Import updated transunion vehicle data.
144 * @param string $filename
146 public function scriptUpdateVehicleData($filename,$importType,$userId,$companyId)
148 // \Utility\Debug::errorLog('$filename', $filename);
149 // \Utility\Debug::errorLog('$importType', $importType);
151 #-> Ensure we don't have problem with script timeout.
155 $this->util = new ImportUtility($this->em);
156 $this->store = new DataStore();
157 $this->helper = new BulkImportHelper($this->em, $this->store);
158 $this->exceptions = array();
159 $this->userId = $userId;
160 $this->companyId = $companyId;
165 #-> Get things ready.
166 $this->prepareForCsvProcessing($filename);
172 $file = fopen(getcwd() . '/public/documents/' . $filename, 'r');
174 while (($data_tmp = fgetcsv($file, 1000, ";")) !== FALSE) {
175 // \Utility\Debug::errorLog('$data_tmp', $data_tmp);
182 $file = fopen(getcwd() . '/public/documents/' . $filename, 'w');
183 foreach($data as $d){
184 $d = str_replace('"','',$d);
185 // \Utility\Debug::errorLog('$d', $d);
186 fputcsv($file, $d, ';');
193 #-> Open uploaded csv file.
194 $data = $this->importer = new ImportCsv(
195 getcwd() . '/public/documents/' . $filename, true, ';'
200 ini_set('auto_detect_line_endings',TRUE);
201 while (($data = $this->importer->getRecord(ImportCsv::FETCH_ASSOC)) !== false)
203 $this->processCsvEntryForPersistenceIfRequired($data,$importType);
205 // ini_set('auto_detect_line_endings',FALSE);
208 $this->cleanupAfterCsvProcessing();
210 catch (\Exception $e)
212 Debug::errorLog('Bulk Data Import EXCEPTION', $e->getMessage());
213 Debug::errorLog('Bulk Data Import TRACE', $e->getTraceAsString());
216 \Utility\Debug::errorLog('$importType', $importType);
217 \Utility\Debug::errorLog('$this->exceptions', $this->exceptions);
218 \Utility\Debug::errorLog('$this->recordCounter', $this->recordCounter);
219 \Utility\Debug::errorLog('$this->successCounter', $this->successCounter);
220 \Utility\Debug::errorLog('$this->failedCounter', $this->failedCounter);
222 * send email with exceptions to user
224 if(!empty($this->exceptions))
226 $profileEntry = $this->em->getRepository('\\User\\Entity\\Profile')
227 ->find($this->userId);
229 // \Utility\Debug::errorLog('$profileEntry->email', $profileEntry->email);
231 $toCompanyId = $this->companyId;
232 $toProfileId = $this->userId;
233 $email = $profileEntry->email;
235 $subject = "Bulk import of $importType system";
236 $templateName = 'general';
238 $params['body'] = '<table border="0" cellspacing="0" cellpadding="0" width="600" style="border-collapse:collapse; border-spacing:0; margin:0; padding:0; width:600px; font-family: Arial, Sans-serif; font-size:12px;">
240 <td width="100%" valign="top" style="width:100%;">
241 Good Day ' . $profileEntry->firstName . ' ' . $profileEntry->familyName . ',
245 <td width="100%" valign="top" style="width:100%;">
250 <td width="100%" valign="top" style="width:100%;">
251 The bulk import for ' . $importType . ' is complete
255 <td width="100%" valign="top" style="width:100%;">
260 <td width="100%" valign="top" style="width:100%;">
261 Total records processed: ' . $this->recordCounter . '
263 Number of records successfully imported: ' . $this->successCounter . '
265 Number of records that could not be imported: ' . $this->successCounter . '
269 <td width="100%" valign="top" style="width:100%;">
274 <table border="0" cellspacing="0" cellpadding="0" width="800" style="border-collapse:collapse; border-spacing:0; margin:0; padding:0; width:800px; font-family: Arial, Sans-serif; font-size:12px;">';
276 foreach($this->exceptions as $exceptions)
278 $params['body'] .= '<tr>
279 <td width="180" valign="top" style="width:180px; font-family: Arial, Sans-serif; font-size:12px;">
284 <td width="180" valign="top" style="width:180px; font-family: Arial, Sans-serif; font-size:12px;">
285 ' . $exceptions['MmCode'] . '
289 <td width="180" valign="top" style="width:180px;">
295 if(is_array($exceptions['Error']))
297 foreach($exceptions['Error'] as $errors)
299 foreach($errors as $error)
303 <tr><td width="180" valign="top" style="width:180px; font-family: Arial, Sans-serif; font-size:12px;">
311 $params['body'] .= '<tr><td width="180" valign="top" style="width:180px; font-family: Arial, Sans-serif; font-size:12px;">
312 ' . $exceptions['Error'] . '
317 <td width="20" valign="top" style="width:20px;"> </td>
320 $params['body'] .= '</table>
321 <table border="0" cellspacing="0" cellpadding="0" width="600" style="border-collapse:collapse; border-spacing:0; margin:0; padding:0; width:600px; font-family: Arial, Sans-serif; font-size:12px;">
323 <td width="100%" valign="top" style="width:100%;">
328 <td width="100%" valign="top" style="width:100%;">
333 <td width="100%" valign="top" style="width:100%;">
340 $params['smsBody'] = '';
342 // \Utility\Debug::errorLog('email body', $params['body']);
344 $oNotify = new \Utility\Comms\Notification();
345 $oNotify->sendFromTemplate(
362 protected function prepareForCsvProcessing($filename)
364 #-> Establish new synchronization version to use.
365 $this->store->version = $this->util->getLatestSynchVersion(
366 'Stock\\Entity\\Type'
369 #-> Ensure that synchronization versions have a full sequence.
370 $this->helper->ensureSynchronizationVersionSequence();
372 #-> Prepare common variables.
373 $this->previousMmCode = false;
374 $this->em->beginTransaction();
378 * Process a csv line entry.
381 protected function processCsvEntryForPersistenceIfRequired($packet,$importType)
383 // \Utility\Debug::errorLog('$packet', $packet);
385 $this->helper->errors = array();
390 #-> Ensure null instead of empty string on numeric fields.
391 $packet = $this->helper->cleanupNumericInputFields($packet);
397 * prepare vehicle year data
399 $vehicleYearArray = explode('/',$packet['Registration Date']);
400 $vehicleYearArray = explode(' ',$vehicleYearArray[2]);
405 $stockNumber = $packet['Stock Number'];
406 $vehicleMmCode = $packet['MM Code'];
407 $vehicleYear = $vehicleYearArray[0];
408 $vehicleMake = $packet['Make'];
409 $vehicleModel = $packet['Model'];
410 $vehicleType = $packet['Specification'];
411 $vehicleTransmission = $packet['Transmission'];
412 $vehicleExteriorColour = $packet['Colour'];
413 $vehicleInteriorColour = '';
414 $vehicleUpholstery = $packet['Interior'];
415 $vehicleCondition = $packet[''];
416 $vehicleReg = $packet['Registration Number'];
417 $vehicleVin = $packet['VIN'];
418 $vehicleMileage = $packet['Odometer'];
419 $vehicleFuelType = $packet['Fuel Type'];
420 $vehicleEngineNumber = $packet['Engine Number'];
421 $empty = $packet[''];
428 $stockNumber = $packet['Suffix to Use'];
429 $vehicleMmCode = $packet['MM Code'];
430 $vehicleYear = $packet['Model Year'];
431 $vehicleMake = $packet['Fran'];
432 $vehicleModel = $packet['Model'];
433 $vehicleType = $packet['Description'];
434 $vehicleTransmission = '';
435 $vehicleExteriorColour = $packet['Colour'];
436 $vehicleInteriorColour = $packet['Trim'];
437 $vehicleUpholstery = '';
438 $vehicleCondition = $packet['Condition'];
439 $vehicleReg = $packet['Reg'];
440 $vehicleVin = $packet['VIN'];
441 $vehicleMileage = $packet['Mileage'];
442 $vehicleFuelType = '';
443 $vehicleEngineNumber = $packet['Engine'];
447 if('' == $vehicleType)
453 #-> Safety check for year range.
454 if ($vehicleYear < 1970)
459 $this->recordCounter++;
461 // \Utility\Debug::errorLog('$vehicleMmCode', $vehicleMmCode);
463 if('' != $vehicleMmCode && 0 != $vehicleMmCode)
466 $exteriorColourId = '';
467 $interiorColourId = '';
470 $transmissionId = '';
473 #-> Get vehicle type ID.
474 $typeId = $this->helper->getVehicleType($vehicleMmCode,$vehicleMake);
477 if('' != $vehicleYear)
479 #-> Get vehicle year ID.
480 $yearId = $this->helper->getYearEntry($vehicleYear);
483 if('' != $vehicleExteriorColour)
485 #-> Get vehicle exterior colour ID.
486 $exteriorColourId = $this->helper->getExteriorColourEntry($vehicleExteriorColour);
489 if('' != $vehicleInteriorColour)
491 #-> Get vehicle interior colour ID.
492 $interiorColourId = $this->helper->getInteriorColourEntry($vehicleInteriorColour);
495 if('' != $vehicleUpholstery)
497 #-> Get vehicle upholstery ID.
498 $upholsteryId = $this->helper->getUpholsteryEntry($vehicleUpholstery);
501 if('' != $vehicleCondition)
503 #-> Get vehicle condition ID.
504 $conditionId = $this->helper->getConditionEntry($vehicleCondition);
507 if('' != $vehicleTransmission)
509 #-> Get vehicle transmission ID.
510 $transmissionId = $this->helper->getTransmissionEntry($vehicleTransmission);
513 if('' != $vehicleFuelType)
515 #-> Get vehicle fuel type ID.
516 $fuelTypeId = $this->helper->getFuelTypeEntry($vehicleFuelType);
521 if(!empty($this->helper->errors))
523 array_push($this->exceptions,array('MmCode' => $vehicleMmCode,'Error' => $this->helper->errors));
524 $this->failedCounter++;
529 $data = \Utility\Comms\TransUnion::searchByMmCode(
538 \Utility\Debug::errorLog('TransUnion $data', $data);
540 if (is_array($data) && isset($data['VehicleDetails'])
541 && isset($data['VehicleDetails'][0])
542 && isset($data['VehicleDetails'][0]['Value'])
545 $retailPrice = isset($data['VehicleDetails'][0]['Value']['RetailPrice']) ? $data['VehicleDetails'][0]['Value']['RetailPrice'] : 0.0;
546 $tradePrice = isset($data['VehicleDetails'][0]['Value']['TradePrice']) ? $data['VehicleDetails'][0]['Value']['TradePrice'] : 0.0;
547 $listPrice = isset($data['VehicleDetails'][0]['Value']['NewPrice']) ? $data['VehicleDetails'][0]['Value']['NewPrice'] : 0.0;
550 // \Utility\Debug::errorLog('$this->userId', $this->userId);
551 // \Utility\Debug::errorLog('$this->companyId', $this->companyId);
553 // \Utility\Debug::errorLog('$typeId', $typeId);
554 // \Utility\Debug::errorLog('$categoryId', $categoryId);
555 // \Utility\Debug::errorLog('$modelId', $modelId);
556 // \Utility\Debug::errorLog('$makeId', $makeId);
557 // \Utility\Debug::errorLog('$yearId', $yearId);
558 // \Utility\Debug::errorLog('$exteriorColourId', $exteriorColourId);
559 // \Utility\Debug::errorLog('$interiorColourId', $interiorColourId);
560 // \Utility\Debug::errorLog('$upholsteryId', $upholsteryId);
561 // \Utility\Debug::errorLog('$conditionId', $conditionId);
562 // \Utility\Debug::errorLog('$transmissionId', $transmissionId);
563 // \Utility\Debug::errorLog('$fuelTypeId', $fuelTypeId);
565 // \Utility\Debug::errorLog('$retailPrice', $retailPrice);
566 // \Utility\Debug::errorLog('$tradePrice', $tradePrice);
567 \Utility\Debug::errorLog('$listPrice', $listPrice);
568 // \Utility\Debug::errorLog('$stockNumber', $stockNumber);
569 // \Utility\Debug::errorLog('$vehicleReg', $vehicleReg);
570 // \Utility\Debug::errorLog('$vehicleVin', $vehicleVin);
571 // \Utility\Debug::errorLog('$vehicleEngineNumber', $vehicleEngineNumber);
572 // \Utility\Debug::errorLog('$vehicleMileage', $vehicleMileage);
575 * insert into stock table
577 \Utility\Registry::set('IsBulkImport', true);
579 $stockEntry = $this->em->getRepository('\\Stock\\Entity\\Stock')
581 'stockNumber' => $stockNumber,
582 'createdBy' => $this->em->getRepository('\User\Entity\Profile')->find($this->userId),
583 'company' => $this->em->getRepository('\Company\Entity\Company')->find($this->companyId),
587 if(empty($stockEntry))
589 $stockEntry = new \Stock\Entity\Stock();
592 'stockNumber' => $stockNumber,
593 'stockNumber' => $stockNumber,
594 'jobState' => 'Stock',
595 'tradePriceDate' => new \DateTime('now'),
596 'tradePrice' => $tradePrice,
597 'retailPrice' => $retailPrice,
598 'listPriceDate' => new \DateTime('now'),
599 'listPrice' => $listPrice,
600 'registrationNumber'=> $vehicleReg,
601 'vinNumber' => $vehicleVin,
602 'engineNumber' => $vehicleEngineNumber,
603 'km' => $vehicleMileage,
606 $stockArray['createdBy'] = $this->em->getRepository('\User\Entity\Profile')->find($this->userId);
607 $stockArray['company'] = $this->em->getRepository('\Company\Entity\Company')->find($this->companyId);
609 if('' != $typeId){$stockArray['type'] = $this->em->getRepository('\Stock\Entity\Type')->find($typeId);}
610 // if('' != $categoryId){$stockArray[] = $categoryId;}
611 // if('' != $modelId){$stockArray[] = $modelId;}
612 // if('' != $makeId){$stockArray[] = $makeId;}
613 if('' != $yearId){$stockArray['vehicleYear'] = $this->em->getRepository('\Stock\Entity\Year')->find($yearId);}
614 if('' != $exteriorColourId){$stockArray['exteriorColour'] = $this->em->getRepository('\Stock\Entity\ExteriorColour')->find($exteriorColourId);}
615 if('' != $interiorColourId){$stockArray['interiorColour'] = $this->em->getRepository('\Stock\Entity\InteriorColour')->find($interiorColourId);}
616 if('' != $upholsteryId){$stockArray['upholstery'] = $this->em->getRepository('\Stock\Entity\Upholstery')->find($upholsteryId);}
617 if('' != $conditionId){$stockArray['condition'] = $this->em->getRepository('\Stock\Entity\Condition')->find($conditionId);}
618 if('' != $transmissionId){$stockArray['transmissionType'] = $this->em->getRepository('\Stock\Entity\TransmissionType')->find($transmissionId);}
619 if('' != $fuelTypeId){$stockArray['fuelType'] = $this->em->getRepository('\Stock\Entity\FuelType')->find($fuelTypeId);}
623 $stockEntry->fromArray($stockArray);
624 $this->em->persist($stockEntry);
628 catch (\Exception $e)
630 $this->failedCounter++;
631 array_push($this->exceptions,array('MmCode' => $vehicleMmCode,'Error' => 'Could not insert stock entry for MM Code ' . $vehicleMmCode));
634 $this->successCounter++;
638 $this->failedCounter++;
639 array_push($this->exceptions,array('MmCode' => $vehicleMmCode,'Error' => 'Could not insert stock entry for MM Code ' . $vehicleMmCode . ' stock number ' . $stockNumber . ' already exists.'));
646 $this->failedCounter++;
647 array_push($this->exceptions,array('MmCode' => $vehicleMmCode,'Error' => 'Could not find MM Code for vehicle ' . $vehicleType));
651 #-> Bump the version?
652 if ($this->store->numItems >= 200)
654 $this->store->version = $this->helper->processBatch();
660 protected function cleanupAfterCsvProcessing()
664 $this->importer = null;