Merge branch '655-import-yokohama-vehicle-battery-compatibility' into 'master'
Resolve "Import Yokohama vehicle battery compatibility" Closes #655 See merge request jankstudio/resq!767
This commit is contained in:
commit
d0d26e01e4
1 changed files with 404 additions and 0 deletions
404
src/Command/ImportYokohamaVehicleBatteryCompatibilityCommand.php
Normal file
404
src/Command/ImportYokohamaVehicleBatteryCompatibilityCommand.php
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||
use DateTime;
|
||||
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
|
||||
class ImportYokohamaVehicleBatteryCompatibilityCommand extends Command
|
||||
{
|
||||
const F_V_BRAND = 0;
|
||||
const F_V_MAKE = 1;
|
||||
const F_V_MODEL_YEAR = 2;
|
||||
const F_B_SIZE = 7;
|
||||
const F_B_MODEL = 8;
|
||||
//const F_B_ALT_PREM_MF = 10;
|
||||
//const F_B_ALT_PREM_LM = 11;
|
||||
//const F_B_ALT_SUPER_PREM_MF = 12;
|
||||
//const F_B_ALT_SUPREME_MF = 13;
|
||||
//const F_B_ALT_PLATINUM_MF = 14;
|
||||
// the rest of the fields are irrelevant
|
||||
|
||||
protected $em;
|
||||
protected $vmfg_index;
|
||||
protected $v_index;
|
||||
protected $batt_index;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->vmfg_index = [];
|
||||
$this->v_index = [];
|
||||
$this->batt_index = [];
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('yokohamavehicle:import')
|
||||
->setDescription('Import Yokohama data CSV file with vehicles and batteries.')
|
||||
->setHelp('Creates vehicles and batteries based on imported Yokohama CSV.')
|
||||
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file.')
|
||||
->addArgument('output_file', InputArgument::REQUIRED, 'Path to output file.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$csv_file = $input->getArgument('input_file');
|
||||
$output_file = $input->getArgument('output_file');
|
||||
|
||||
$this->populateVehicleIndex();
|
||||
$this->populateBatteryIndex();
|
||||
|
||||
// attempt to open file
|
||||
try
|
||||
{
|
||||
$fh = fopen($csv_file, "r");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $csv_file . '" could be read.');
|
||||
}
|
||||
|
||||
// get entity manager
|
||||
$em = $this->em;
|
||||
|
||||
$vbrands = [];
|
||||
$output_info = [];
|
||||
|
||||
// loop through rows
|
||||
$row_num = 1;
|
||||
$prem_mf_name = '';
|
||||
$prem_lm_name = '';
|
||||
$super_prem_mf_name = '';
|
||||
$supreme_mf_name = '';
|
||||
$platinum_mf_name = '';
|
||||
while (($fields = fgetcsv($fh)) !== false)
|
||||
{
|
||||
$output->writeln("Parsing row " . $row_num . "...");
|
||||
|
||||
// alternate brands are not in file, so we just comment out
|
||||
// get the alternate battery brand header names
|
||||
/*
|
||||
if ($row_num == 2)
|
||||
{
|
||||
$prem_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_PREM_MF]);
|
||||
$prem_lm_name = $this->normalizeName($fields[SELF::F_B_ALT_PREM_LM]);
|
||||
$super_prem_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_SUPER_PREM_MF]);
|
||||
$supreme_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_SUPREME_MF]);
|
||||
$platinum_mf_name = $this->normalizeName($fields[SELF::F_B_ALT_PLATINUM_MF]);
|
||||
}
|
||||
*/
|
||||
|
||||
// process row
|
||||
$output_info[] = $this->processRow($fields, $vbrands, $row_num, $prem_mf_name, $prem_lm_name,
|
||||
$super_prem_mf_name, $supreme_mf_name, $platinum_mf_name);
|
||||
|
||||
$row_num++;
|
||||
}
|
||||
|
||||
// save to db the valid ones
|
||||
foreach ($vbrands as $brand_name => $vbrand)
|
||||
{
|
||||
// vehicles
|
||||
foreach ($vbrand['vehicles'] as $row_num => $vdata)
|
||||
{
|
||||
$model = $vdata['model'];
|
||||
if ($model == 'NONE')
|
||||
{
|
||||
$m_year_from = 0;
|
||||
$m_year_to = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ex_model = explode('-', $model);
|
||||
$m_year_from = trim($ex_model[0]);
|
||||
|
||||
if (isset($ex_model[1]))
|
||||
$m_year_to = trim($ex_model[1]);
|
||||
else
|
||||
$m_year_to = 0;
|
||||
}
|
||||
|
||||
$vehicle = $this->v_index[$brand_name][$vdata['make'] . '|' . intval($m_year_from) . '|' . intval($m_year_to)];
|
||||
|
||||
// recommended battery
|
||||
$vdata['battery']->addVehicle($vehicle);
|
||||
|
||||
// alt_batteries
|
||||
// alternate brands are not in file, so we just comment out
|
||||
/*
|
||||
if (isset($vdata['alt_battery_prem_mf']))
|
||||
$vdata['alt_battery_prem_mf']->addVehicle($vehicle);
|
||||
if (isset($vdata['alt_battery_prem_lm']))
|
||||
$vdata['alt_battery_prem_lm']->addVehicle($vehicle);
|
||||
if (isset($vdata['alt_battery_super_prem_mf']))
|
||||
$vdata['alt_battery_super_prem_mf']->addVehicle($vehicle);
|
||||
if (isset($vdata['alt_battery_supreme_mf']))
|
||||
$vdata['alt_battery_supreme_mf']->addVehicle($vehicle);
|
||||
if (isset($vdata['alt_battery_platinum_mf']))
|
||||
$vdata['alt_battery_platinum_mf']->addVehicle($vehicle);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
|
||||
// write to output file
|
||||
// error_log(print_r($output_info, true));
|
||||
$this->outputVehicleBatteryInfo($output_file, $output_info);
|
||||
|
||||
fclose($fh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function processRow($fields, &$vbrands, $row_num, $prem_mf_name, $prem_lm_name,
|
||||
$super_prem_mf_name, $supreme_mf_name, $platinum_mf_nam)
|
||||
{
|
||||
$output_info = [];
|
||||
$brand = $this->normalizeName($fields[0]);
|
||||
$make = $this->normalizeName($fields[1]);
|
||||
$model = trim($fields[2]);
|
||||
$bsize = $this->normalizeName($fields[self::F_B_SIZE]);
|
||||
$bmodel = $this->normalizeName($fields[self::F_B_MODEL]);
|
||||
|
||||
// checking for valid vehicles and batteries should be done here so that only valid entries
|
||||
// go into the vbrands array
|
||||
$output_info = $this->validateManufacturerVehicle($fields, $brand, $make, $model, $bsize, $bmodel);
|
||||
|
||||
if (!empty($output_info))
|
||||
return $output_info;
|
||||
|
||||
if (!isset($vbrands[$brand]))
|
||||
{
|
||||
// build array
|
||||
$vbrands[$brand] = [
|
||||
'vehicles' => [],
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($model))
|
||||
$model = 'NONE';
|
||||
|
||||
$vbrands[$brand]['vehicles'][$row_num] = [
|
||||
'make' => $make,
|
||||
'model' => $model,
|
||||
];
|
||||
|
||||
// at this point we are sure we have battery
|
||||
$batt_key = $this->getBatteryKey($bsize, $bmodel);
|
||||
$vbrands[$brand]['vehicles'][$row_num]['battery'] = $this->batt_index[$batt_key];
|
||||
|
||||
// alternate brands are not in file, so we just comment out
|
||||
// need to check alternate brands if battery exists
|
||||
// go through the alternate fields, look for 'P'. Not kidding. It's what is in the csv file.
|
||||
/*
|
||||
if ($this->normalizeName($fields[SELF::F_B_ALT_PREM_MF]) == 'P')
|
||||
{
|
||||
// check if we have battery for name + size combo
|
||||
$alt_batt_key = $this->getBatteryKey($field_bsize, $prem_mf_name);
|
||||
if (isset($this->batt_index[$alt_batt_key]))
|
||||
{
|
||||
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_prem_mf'] = $this->batt_index[$alt_batt_key];
|
||||
}
|
||||
}
|
||||
if ($this->normalizeName($fields[SELF::F_B_ALT_PREM_LM]) == 'P')
|
||||
{
|
||||
// check if we have battery for name + size combo
|
||||
$alt_batt_key = $this->getBatteryKey($field_bsize, $prem_lm_name);
|
||||
if (isset($this->batt_index[$alt_batt_key]))
|
||||
{
|
||||
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_prem_lm'] = $this->batt_index[$alt_batt_key];
|
||||
}
|
||||
}
|
||||
if ($this->normalizeName($fields[SELF::F_B_ALT_SUPER_PREM_MF]) == 'P')
|
||||
{
|
||||
// check if we have battery for name + size combo
|
||||
$alt_batt_key = $this->getBatteryKey($field_bsize, $super_prem_mf_name);
|
||||
if (isset($this->batt_index[$alt_batt_key]))
|
||||
{
|
||||
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_super_prem_mf'] = $this->batt_index[$alt_batt_key];
|
||||
}
|
||||
}
|
||||
if ($this->normalizeName($fields[SELF::F_B_ALT_SUPREME_MF]) == 'P')
|
||||
{
|
||||
// check if we have battery for name + size combo
|
||||
$alt_batt_key = $this->getBatteryKey($field_bsize, $supreme_mf_name);
|
||||
if (isset($this->batt_index[$alt_batt_key]))
|
||||
{
|
||||
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_supreme_mf'] = $this->batt_index[$alt_batt_key];
|
||||
}
|
||||
}
|
||||
if ($this->normalizeName($fields[SELF::F_B_ALT_PLATINUM_MF]) == 'P')
|
||||
{
|
||||
// check if we have battery for name + size combo
|
||||
$alt_batt_key = $this->getBatteryKey($field_bsize, $platinum_mf_name);
|
||||
if (isset($this->batt_index[$alt_batt_key]))
|
||||
{
|
||||
$vbrands[$brand]['vehicles'][$row_num]['alt_battery_platinum_mf'] = $this->batt_index[$alt_batt_key];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
protected function validateManufacturerVehicle($fields, $brand, $make, $model, $bsize, $bmodel)
|
||||
{
|
||||
$output_info = [];
|
||||
// process model year data
|
||||
if ($model == 'NONE')
|
||||
{
|
||||
$m_year_from = 0;
|
||||
$m_year_to = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ex_model = explode('-', $model);
|
||||
$m_year_from = trim($ex_model[0]);
|
||||
|
||||
if (isset($ex_model[1]))
|
||||
$m_year_to = trim($ex_model[1]);
|
||||
else
|
||||
$m_year_to = 0;
|
||||
}
|
||||
|
||||
if (!isset($this->v_index[$brand][$make . '|' . intval($m_year_from) . '|' . intval($m_year_to)]))
|
||||
{
|
||||
$message = 'Invalid vehicle';
|
||||
$output_info = $this->setOutputInfo($fields, 'NOT ADDED', $message);
|
||||
return $output_info;
|
||||
}
|
||||
|
||||
// recommended battery
|
||||
$batt_key = $this->getBatteryKey($bsize, $bmodel);
|
||||
if (!isset($this->batt_index[$batt_key]))
|
||||
{
|
||||
$message = 'Could not find battery - ' . $bsize . ' - ' . $bmodel;
|
||||
$output_info = $this->setOutputInfo($fields, 'NOT ADDED', $message);
|
||||
return $output_info;
|
||||
}
|
||||
|
||||
return $output_info;
|
||||
}
|
||||
|
||||
protected function setOutputInfo($fields, $status, $reason)
|
||||
{
|
||||
$mfg_name = trim($fields[SELF::F_V_BRAND]);
|
||||
$model_name = trim($fields[SELF::F_V_MAKE]);
|
||||
$model_year = trim($fields[SELF::F_V_MODEL_YEAR]);
|
||||
$bsize = trim($fields[SELF::F_B_SIZE]);
|
||||
$bmodel = trim($fields[SELF::F_B_MODEL]);
|
||||
// alternate brands are not in file, so we just comment out
|
||||
/*
|
||||
$alt_prem_mf = trim($fields[SELF::F_B_ALT_PREM_MF]);
|
||||
$alt_prem_lm = trim($fields[SELF::F_B_ALT_PREM_LM]);
|
||||
$alt_super_prem_mf = trim($fields[SELF::F_B_ALT_SUPER_PREM_MF]);
|
||||
$alt_supreme_mf = trim($fields[SELF::F_B_ALT_SUPREME_MF]);
|
||||
$alt_platinum_mf = trim($fields[SELF::F_B_ALT_PLATINUM_MF]);
|
||||
*/
|
||||
|
||||
return [
|
||||
$mfg_name,
|
||||
$model_name,
|
||||
$model_year,
|
||||
$bsize,
|
||||
$bmodel,
|
||||
$status,
|
||||
$reason
|
||||
];
|
||||
}
|
||||
|
||||
protected function outputVehicleBatteryInfo($output_file, $entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
$fh = fopen($output_file, "w");
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception('The file "' . $report_file . '" could be opened.');
|
||||
}
|
||||
|
||||
// write the headers
|
||||
fputcsv($fh, [
|
||||
'Manufacturer',
|
||||
'Vehicle Model',
|
||||
'Year Model',
|
||||
'Battery Size',
|
||||
'Battery Model',
|
||||
'Status',
|
||||
'Reason',
|
||||
]);
|
||||
|
||||
foreach($entries as $row)
|
||||
{
|
||||
if ($row != null)
|
||||
fputcsv($fh, $row);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
protected function populateVehicleIndex()
|
||||
{
|
||||
$vs = $this->em->getRepository(Vehicle::class)->findAll();
|
||||
|
||||
$this->v_index = [];
|
||||
$this->vmfg_index = [];
|
||||
foreach ($vs as $v)
|
||||
{
|
||||
$mfg_name = $this->normalizeName($v->getManufacturer()->getName());
|
||||
$this->vmfg_index[$mfg_name] = $v->getManufacturer();
|
||||
if (!isset($this->v_index[$mfg_name]))
|
||||
$this->v_index[$mfg_name] = [];
|
||||
|
||||
$this->v_index[$mfg_name][$this->normalizeName($v->getMake()) . '|' . $v->getModelYearFrom() . '|' . $v->getModelYearTo()] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
protected function populateBatteryIndex()
|
||||
{
|
||||
$bs = $this->em->getRepository(Battery::class)->findAll();
|
||||
|
||||
$this->batt_index = [];
|
||||
foreach ($bs as $b)
|
||||
{
|
||||
// get the battery size
|
||||
$bsize = $b->getSize()->getName();
|
||||
|
||||
$key = $this->getBatteryKey($bsize, $b->getModel()->getName());
|
||||
|
||||
$this->batt_index[$key] = $b;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getBatteryKey($size_name, $model_name)
|
||||
{
|
||||
return $this->normalizeName(str_replace(' ', '', $size_name)) .
|
||||
'|' .
|
||||
$this->normalizeName(str_replace(' ', '', $model_name));
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
$normalized_key = trim(strtoupper($name));
|
||||
|
||||
return $normalized_key;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue