Fix legacy import command to populate plate_number table via load data infile #168

This commit is contained in:
Kendrick Chan 2018-12-30 00:27:52 +08:00
parent cdbc7897ca
commit 1f0060d6c5
4 changed files with 459 additions and 33 deletions

View file

@ -12,8 +12,13 @@ use Doctrine\Common\Persistence\ObjectManager;
use App\Entity\Warranty;
use App\Entity\BatterySize;
use App\Entity\BatteryModel;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
use App\Entity\PlateNumber;
use App\Ramcar\LegacyBattery;
use App\Ramcar\LegacyVehicleManufacturer;
use App\Ramcar\LegacyVehicle;
class ImportLegacyJobOrderCommand extends Command
@ -21,6 +26,8 @@ class ImportLegacyJobOrderCommand extends Command
protected $em;
protected $bmodel_hash;
protected $bsize_hash;
protected $vmfg_hash;
protected $vehicle_hash;
public function __construct(ObjectManager $om)
{
@ -28,6 +35,8 @@ class ImportLegacyJobOrderCommand extends Command
$this->loadBatteryModels();
$this->loadBatterySizes();
$this->loadVehicleManufacturers();
$this->loadVehicles();
parent::__construct();
}
@ -232,7 +241,10 @@ class ImportLegacyJobOrderCommand extends Command
$service_types = [];
$no_sizes = [];
$outfile = fopen('/tmp/plate_numbers.csv', 'a');
// loop through rows
$save_plates = [];
$row_num = 0;
while (($fields = fgetcsv($fh)) !== false)
{
@ -258,40 +270,26 @@ class ImportLegacyJobOrderCommand extends Command
exit;
}
// split battery into model and size
// echo "trying match - " . $fields[92] . "\n";
$res = preg_match("/^(.+)(GOLD|EXCEL|ENDURO|\(Trade-In\))/", $fields[92], $matches);
if (!$res)
{
// echo "no match - " . $fields[92] . "\n";
continue;
}
// check if we have the size
$found_size = $this->simplifyName($matches[1]);
if (!isset($this->bsize_hash[$found_size]))
{
// try legacy battery lookup
$legacy_size = LegacyBattery::translate($found_size);
if ($legacy_size == null)
{
// echo "no size - $found_size\n";
if (isset($no_sizes[$found_size]))
$no_sizes[$found_size]++;
else
$no_sizes[$found_size] = 1;
continue;
}
$found_size = $legacy_size;
}
// let's track purchases first
if ($fields[5] != 'PURCHASE')
continue;
// check if battery is found
$found_battery = $this->findBattery($fields[92], $batt_model, $batt_size);
if (!$found_battery)
{
$output->writeln('battery not found - ' . $fields[92]);
continue;
}
// find matching vehicle
$found_vehicle = $this->findVehicle($fields[15], $fields[16], $fields[17], $vehicle);
if (!$found_vehicle)
{
$output->writeln('vehicle not found - ' . $fields[15] . ' - ' . $fields[16]);
continue;
}
// consolidate transaction and service types
$trans_types[$fields[5]] = 1;
$service_types[$fields[7]] = $fields[5];
@ -304,6 +302,30 @@ class ImportLegacyJobOrderCommand extends Command
continue;
}
fwrite($outfile, $plate_num . ',' . $vehicle['id'] . "\n");
/*
// check if we marked it already
if (isset($save_plates[$plate_num]))
continue;
// check if already there
$find_plate = $em->getRepository(PlateNumber::class)->find($plate_num);
if ($find_plate)
{
continue;
}
// save to db
$o_plate = new PlateNumber();
$o_plate->setID($plate_num)
->setVehicle($vehicle['object']);
$em->persist($o_plate);
$save_plates[$plate_num] = true;
*/
/*
// plate
@ -354,14 +376,20 @@ class ImportLegacyJobOrderCommand extends Command
*/
}
// $em->flush();
// print_r($trans_types);
// print_r($service_types);
print_r($no_sizes);
// print_r($no_sizes);
// print_r($b_models);
// print_r($batteries);
// save to db
// print_r($batteries);
// print_r($this->vehicle_hash);
// print_r($no_makes);
fclose($outfile);
}
protected function loadBatteryModels()
@ -394,8 +422,192 @@ class ImportLegacyJobOrderCommand extends Command
}
}
protected function simplifyName($text)
protected function loadVehicleManufacturers()
{
return strtoupper(trim(str_replace(' ', '', $text)));
$this->vmfg_hash = [];
$mfgs = $this->em->getRepository(VehicleManufacturer::class)->findAll();
foreach ($mfgs as $mfg)
{
$name = $this->simplifyName($mfg->getName(), false);
$this->vmfg_hash[$name] = $mfg->getID();
}
}
protected function loadVehicles()
{
$this->vehicle_hash = [];
$vs = $this->em->getRepository(Vehicle::class)->findAll();
foreach ($vs as $v)
{
$make = $this->simplifyName($v->getMake(), false);
$mfg_id = $v->getManufacturer()->getID();
if (!isset($this->vehicle_hash[$mfg_id]))
$this->vehicle_hash[$mfg_id] = [];
if (!isset($this->vehicle_hash[$mfg_id][$make]))
$this->vehicle_hash[$mfg_id][$make] = [];
$this->vehicle_hash[$mfg_id][$make][] = [
'id' => $v->getID(),
'year_from' => $v->getModelYearFrom(),
'year_to' => $v->getModelYearTo(),
'object' => $v,
];
}
}
protected function simplifyName($text, $replace_spaces = true)
{
if ($replace_spaces)
$clean_text = strtoupper(trim(str_replace(' ', '', $text)));
else
$clean_text = strtoupper(trim($text));
return $clean_text;
}
protected function findBattery($batt_field, &$batt_model, &$batt_size)
{
// split battery into model and size
// echo "trying match - " . $fields[92] . "\n";
$res = preg_match("/^(.+)(GOLD|EXCEL|ENDURO|\(Trade-In\))/", $batt_field, $matches);
if (!$res)
{
// echo "no match - " . $fields[92] . "\n";
return false;
}
$batt_model = $matches[2];
// TODO: what to do about (Trade-In)
// check if we have the size
$found_size = $this->simplifyName($matches[1]);
if (!isset($this->bsize_hash[$found_size]))
{
// try legacy battery lookup
$legacy_size = LegacyBattery::translate($found_size);
if ($legacy_size == null)
{
// echo "no size - $found_size\n";
if (isset($no_sizes[$found_size]))
$no_sizes[$found_size]++;
else
$no_sizes[$found_size] = 1;
return false;
}
$found_size = $legacy_size;
}
$batt_size = $found_size;
return true;
}
protected function findVehicle($vmfg_field, $vmake_field, $vmodel_field, &$vehicle)
{
// debug vehicles with no matching makes
$no_makes = [];
// vehicle manufacturers
$found_vmfg = $this->simplifyName($vmfg_field, false);
if (!isset($this->vmfg_hash[$found_vmfg]))
{
$legacy_vmfg = LegacyVehicleManufacturer::translate($found_vmfg);
if ($legacy_vmfg == null)
{
echo "vmfg not found - $vmfg_field\n";
return false;
}
$found_vmfg = $legacy_vmfg;
}
$vmfg_id = $this->vmfg_hash[$found_vmfg];
// vehicle make
$found_make = $this->simplifyName($vmake_field, false);
if (!isset($this->vehicle_hash[$vmfg_id][$found_make]))
{
$legacy_make = LegacyVehicle::translate($found_vmfg, $found_make);
if ($legacy_make == null)
{
$no_makes[$found_make] = $found_vmfg . ' - ' . $found_make;
echo "vmake not found - $vmfg_field - $vmake_field\n";
return false;
}
$found_make = $legacy_make;
// need to do this again because translate could change vmfg
$vmfg_id = $this->vmfg_hash[$found_vmfg];
}
$make_list = $this->vehicle_hash[$vmfg_id][$found_make];
// check if there's only one in the make list
if (count($make_list) == 1)
{
$vehicle = $make_list[0];
return true;
}
// see which model matches
$clean_model = trim(strtoupper($vmodel_field));
// no model specified, take first one
$model_length = strlen($clean_model);
if ($model_length == 0 || $clean_model == 'NONE')
{
$vehicle = $make_list[0];
return true;
}
// one year or range specified
// we only take the first
$cut_model = substr($clean_model, 0, 4);
foreach ($make_list as $make)
{
// no year
if ($make['year_from'] == 0 && $make['year_to'] == 0)
{
$vehicle = $make;
return true;
}
// no year from
if ($make['year_from'] == 0)
{
if ($make['year_to'] >= $cut_model)
{
$vehicle = $make;
return true;
}
}
// no year to
if ($make['year_to'] == 0)
{
if ($make['year_from'] <= $cut_model)
{
$vehicle = $make;
return true;
}
}
// has year from and to
if ($make['year_from'] <= $cut_model && $make['year_to'] >= $cut_model)
{
$vehicle = $make;
return true;
}
}
// echo "model search - $vmfg_id - $found_vmfg - $found_make - $vmodel_field\n";
// we get the first one, because we have no idea where it falls under
$vehicle = $make_list[0];
return true;
}
}

View file

@ -0,0 +1,52 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="plate_number")
*/
class PlateNumber
{
// the plate number
/**
* @ORM\Id
* @ORM\Column(type="string", length=20)
*/
protected $id;
// the vehicle entity
/**
* @ORM\ManyToOne(targetEntity="Vehicle")
* @ORM\JoinColumn(name="vehicle_id", referencedColumnName="id", nullable=true)
*/
protected $vehicle;
// the batteries under this plate number
protected $batteries;
public function setID($id)
{
$this->id = $id;
return $this;
}
public function getID()
{
return $this->id;
}
public function setVehicle(Vehicle $vehicle)
{
$this->vehicle = $vehicle;
return $this;
}
public function getVehicle()
{
return $this->vehicle;
}
}

View file

@ -0,0 +1,139 @@
<?php
namespace App\Ramcar;
class LegacyVehicle
{
static public function translate(&$mfg, $make)
{
// specific cases
if ($mfg == 'PROTON')
{
if ($make == '1.6')
return 'WIRA 1.6';
}
if ($mfg == 'DODGE' && $make == 'RAM')
{
$mfg = 'CHRYSLER';
return 'RAM';
}
if ($mfg == 'GMC' && $make == 'TAHOE')
{
$mfg = 'CHEVROLET';
return 'TAHOE 5.3 V8 4X2 AT';
}
// general cases
switch($make)
{
// Toyota
case 'INNOVA GAS E':
return 'INNOVA (E-TYPE)';
case 'INNOVA GAS G':
return 'INNOVA (G-TYPE)';
case 'INNOVA GAS V':
return 'INNOVA (V-TYPE)';
case 'INNOVA GAS J':
return 'INNOVA (J-TYPE)';
case 'RAV-4':
return 'RAV 4';
case 'PRADO':
return 'LAND CRUISER / PRADO (GASOLINE)';
case 'STARLET':
return 'STARLET (STARLET)';
case 'COROLLA':
return 'COROLLA ALL MODELS / ALTIS*';
case 'TOYOTA BB':
return 'BB';
// Isuzu
case 'MUX':
return 'MU-X 2.5LI 4X2/3.0LI 4X4';
// Mazda
case 'CX-5':
return 'CX5';
case 'MAZADA 3 / 2 / 6 ISTOP':
return 'MAZDA 3 / 2 / 6 ISTOP';
// Chevrolet
case 'SUBURVAN 5.3 V9 4X2 AT':
return 'SUBURBAN 5.3 V9 4X2 AT';
case 'SUBURVAN 5.3 V8 4X2 AT':
return 'SUBURBAN 5.3 V8 4X2 AT';
case 'TRAILBLAZER 2014':
case 'TRAILBLAZER 2013 LOW':
return 'TRAILBLAZER';
// Subaru
case 'FORESTER 2.0 AND 2.5':
return 'FORESTER 2.0';
// Chery
case 'CHERY QQ3':
return 'CHERRY QQ3';
case 'CHERY A5':
return 'CHERRY A5';
// Mitsubishi
case 'ADVENTURE GAS':
return 'ADVENTURE GX';
case 'MIRAGE':
return 'MIRAGE G4';
case 'L300 (DIESEL)':
return 'L300 FB (DIESEL)';
// Kia
case 'SORENTO 7-SEATER AT':
return 'SORENTO';
// Honda
case 'ACCORD 3.5 S - V AT V6 (BRILLIANT WHITE PEARL)':
return 'ACCORD 3.5 S - V AT V6';
case 'BRIO-AMAZE':
return 'BRIO';
case 'NEW CIVIC 1.8 V AT':
return 'CIVIC 1.8';
case 'STEPWGN':
return 'WAGON';
case 'CR-V 1.5 I-DTEC':
return 'CRV';
case 'NEW CIVIC 1.8 V MT':
return 'CIVIC 1.8';
// Nissan
case 'ALMIRA':
return 'ALMERA';
// Volkswagen
case 'POLO HATCH 1.6 MPI AT (GAS)':
return 'POLO NOTCH 1.6 MPI AT (GAS)';
// Hyundai
case 'MATRIX 1.6 GAS':
return 'MATRIX (1.6 GAS)';
case 'GETZ 1.1 GAS':
return 'GETZ GAS 1.1 MT';
// Mini
case 'MINI COOPER':
return 'COOPER';
// Bentley
case 'CONTINENTAL GT/GTC':
return 'CONTINENTAL GT/GTC 6.0 W12';
// Ford
case 'ECOSPORT':
return 'ECOSPORT 1.5';
default:
return null;
}
return null;
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Ramcar;
class LegacyVehicleManufacturer
{
static public function translate($id)
{
switch($id)
{
case 'PROTONWIRA':
case 'PROTON WIRA':
return 'PROTON';
case 'CHERRY CARS':
case 'CHERY CARS':
return 'CHERY';
default:
return null;
}
return null;
}
}