diff --git a/src/Command/ImportYokohamaVehicleBatteryCompatibilityCommand.php b/src/Command/ImportYokohamaVehicleBatteryCompatibilityCommand.php new file mode 100644 index 00000000..50296cad --- /dev/null +++ b/src/Command/ImportYokohamaVehicleBatteryCompatibilityCommand.php @@ -0,0 +1,404 @@ +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; + } + +}