Merge branch '460-cmb-data-migration-for-carfix-data' into '472-cmb-release'

Resolve "CMB - Data migration for Carfix data"

See merge request jankstudio/resq!565
This commit is contained in:
Korina Cordero 2020-09-07 02:42:34 +00:00
commit 399cf23f29
10 changed files with 1970 additions and 467 deletions

View file

@ -126,7 +126,7 @@ class MapEventHandler {
// console.log("got location for rider " + chan_split[1] + " - " + payload
var pl_split = payload.split(':');
// console.log(pl_split);
// check for correct format
if (pl_split.length != 2)
break;

View file

@ -70,8 +70,8 @@ class ImportCMBBatteryDataCommand extends Command
error_log('Processing battery csv file...');
while (($fields = fgetcsv($fh)) !== false)
{
// data starts at row 2
if ($row_num < 2)
// data starts at row 1
if ($row_num < 1)
{
$row_num++;
continue;
@ -90,22 +90,42 @@ class ImportCMBBatteryDataCommand extends Command
// [0] = battery manufacturer
// [1] = battery model
// [2] = battery size
// if only 2, get both
// [0] = battery manufacturer and battery model
// [1] = battery size
// if 4,
// [0] = battery manufacturer
// concatenate [1] and [2] for the battery model
// [1] = battery model
// [2] = extra info
// [3] = battery size
// OR
// [0] = battery manufacturer
// [1] = battery model
// [2] = battery size
// [3] = battery size --> this one would have ()
// if 5,
// [0] = battery manufacturer
// [1] = battery model
// [2] = extra info
// [3] = extra info
// [4] = battery size
$battery_manufacturer = '';
$battery_model = '';
$battery_size = '';
if (count($battery_info) == 3)
{
// sample: Century Marathoner 120-7L
// sample: Century Marathoner M42(60B20L)
$battery_manufacturer = trim($battery_info[0]);
$battery_model = trim($battery_info[1]);
$battery_size = trim($battery_info[2]);
// check for parenthesis in battery_info[2]
if (strpos($battery_info[2], '(') === false)
{
// no parenthesis found
$battery_size = trim($battery_info[2]);
}
else
{
$battery_size = trim(str_replace('(', ' (', $battery_info[2]));
}
}
if (count($battery_info) == 2)
{
@ -117,13 +137,32 @@ class ImportCMBBatteryDataCommand extends Command
if (count($battery_info) == 4)
{
// sample: Motolite Classic Wetcharged DIN100L
// sample: Century Excel NS60LS (60B24LS)
$battery_manufacturer = trim($battery_info[0]);
$battery_model = trim($battery_info[1]) . ' ' . trim($battery_info[2]);
$battery_size = trim($battery_info[3]);
$battery_model = trim($battery_info[1]);
// check for parenthesis in battery_info[3]
if (strpos($battery_info[3], '(') === false)
{
// no parenthesis found
$battery_size = trim($battery_info[3]);
}
else
{
// need to concatenate [2] and [3]
$battery_size = trim($battery_info[2]) . ' ' . trim($battery_info[3]);
}
}
if (count($battery_info) == 5)
{
// sample: Century Marathoner Max Wet NS40ZL
$battery_manufacturer = trim($battery_info[0]);
$battery_model = trim($battery_info[1]);
$battery_size = trim($battery_info[4]);
}
// check if battery size has ()
// if so, trim it to ignore the parenthesis and what's after (.
/*
$pos = stripos($battery_size, '(');
if ($pos == true)
{
@ -133,7 +172,7 @@ class ImportCMBBatteryDataCommand extends Command
else
{
$clean_size = $battery_size;
}
} */
//error_log('battery manufacturer ' . $battery_manufacturer);
//error_log('battery model ' . $battery_model);
@ -143,24 +182,24 @@ class ImportCMBBatteryDataCommand extends Command
// when we add to db for manufacturer, model, and size, we do not use the normalized versions
$normalized_manu = $this->normalizeName($battery_manufacturer);
$normalized_model = $this->normalizeName($battery_model);
$normalized_size = $this->normalizeName($clean_size);
$normalized_size = $this->normalizeName($battery_size);
// save battery manufacturer if not yet in system
if (!isset($this->bmanu_hash[$normalized_manu]))
{
$this->addBatteryManufacturer($battery_manufacturer);
$this->addBatteryManufacturer(strtoupper($battery_manufacturer));
}
// save battery model if not yet in system
if (!isset($this->bmodel_hash[$normalized_model]))
{
$this->addBatteryModel($battery_model);
$this->addBatteryModel(strtoupper($battery_model));
}
// save battery size if not yet in system
if (!isset($this->bsize_hash[$normalized_size]))
{
$this->addBatterySize($clean_size);
$this->addBatterySize(strtoupper($battery_size));
}
// save battery if not yet in system

View file

@ -0,0 +1,365 @@
<?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 App\Entity\BatteryManufacturer;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\Battery;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
class ImportCMBBatteryModelSizeCommand extends Command
{
// CENTURY MARATHONER BATTERY
const F_BATT_MARATHONER_SIZE = 4;
const F_BATT_MARATHONER_PRICE = 5;
const F_BATT_MARATHONER_TRADEIN_PRICE = 6;
const F_BATT_MARATHONER_DISCOUNT = 7;
// MOTOLITE CLASSIC BATTERY
const F_BATT_CLASSIC_SIZE = 8;
const F_BATT_CLASSIC_PRICE = 9;
const F_BATT_CLASSIC_TRADEIN_PRICE = 10;
const F_BATT_CLASSIC_DISCOUNT = 11;
// CENTURY EXCEL BATTERY
const F_BATT_EXCEL_SIZE = 12;
const F_BATT_EXCEL_PRICE = 13;
const F_BATT_EXCEL_TRADEIN_PRICE = 14;
const F_BATT_EXCEL_DISCOUNT = 15;
// CENTURY SDFC BATTERY
const F_BATT_SDFC_SIZE = 16;
const F_BATT_SDFC_PRICE = 17;
const F_BATT_SDFC_TRADEIN_PRICE = 18;
const F_BATT_SDFC_DISCOUNT = 19;
protected $em;
protected $bmanu_hash;
protected $bmodel_hash;
protected $bsize_hash;
protected $batt_hash;
// array for battery manufacturer
protected $batt_manufacturers = [
'CENTURY',
'MOTOLITE',
];
// array for battery models
protected $batt_models = [
'EXCEL', // CENTURY
'SDFC', // CENTURY
'MARATHONER', // CENTURY
'CLASSIC', // MOTOLITE
];
public function __construct(EntityManagerInterface $om)
{
$this->em = $om;
// load existing battery data
$this->loadBatteryManufacturers();
$this->loadBatteryModels();
$this->loadBatterySizes();
$this->loadBatteries();
parent::__construct();
}
protected function configure()
{
$this->setName('cmbbatterymodelsize:import')
->setDescription('Retrieve from a CSV file battery information.')
->setHelp('Creates battery manufacturers, models, sizes based on data from imported CSV.')
->addArgument('input_file', InputArgument::REQUIRED, 'Path to the CSV file.')
->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file for entries not added.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// check if battery manufacturers have been created
if (count($this->bmanu_hash) == 0)
{
// create the manufacturers
$this->createBatteryManufacturerData();
// reload the hash
$this->loadBatteryManufacturers();
}
// check if battery models have been created
if (count($this->bmodel_hash) == 0)
{
// create the battery models
$this->createBatteryModelData();
// reload the hash
$this->loadBatteryModels();
}
// get the sizes, vehicles, battery prices from the csv file
$csv_file = $input->getArgument('input_file');
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could not be read.');
}
$output_file = $input->getArgument('output_file');
// attempt to open file
try
{
$out_fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $output_file . '" could not be read.');
}
// get entity manager
$em = $this->em;
$row_num = 0;
$not_added = [];
error_log('Processing battery model and size file...');
while (($fields = fgetcsv($fh)) !== false)
{
if ($row_num < 2)
{
$row_num++;
continue;
}
// get battery info from file
$marathoner_size = $this->normalizeName(trim($fields[self::F_BATT_MARATHONER_SIZE]));
$marathoner_price = trim($fields[self::F_BATT_MARATHONER_PRICE]);
$marathoner_tradein_price = trim($fields[self::F_BATT_MARATHONER_TRADEIN_PRICE]);
$classic_size = $this->normalizeName(trim($fields[self::F_BATT_CLASSIC_SIZE]));
$classic_price = trim($fields[self::F_BATT_CLASSIC_PRICE]);
$classic_tradein_price = trim($fields[self::F_BATT_CLASSIC_TRADEIN_PRICE]);
$excel_size = $this->normalizeName(trim($fields[self::F_BATT_EXCEL_SIZE]));
$excel_price = trim($fields[self::F_BATT_EXCEL_PRICE]);
$excel_tradein_price = trim($fields[self::F_BATT_EXCEL_TRADEIN_PRICE]);
$sdfc_size = $this->normalizeName(trim($fields[self::F_BATT_SDFC_SIZE]));
$sdfc_price = trim($fields[self::F_BATT_SDFC_PRICE]);
$sdfc_tradein_price = trim($fields[self::F_BATT_SDFC_TRADEIN_PRICE]);
// add the battery sizes
// check if size is empty or if price and tradein prices are N/A
if (!isset($this->bsize_hash[$marathoner_size]))
{
// ignore blank sizes
if ((strlen($marathoner_size) > 0) &&
(strlen($marathoner_price) > 0))
{
// non-numeric entries are ignored since these are N/A == they don't sell it
if ((is_numeric($marathoner_price)) &&
(is_numeric($marathoner_tradein_price)))
{
$this->addBatterySize($marathoner_size, $marathoner_price, $marathoner_tradein_price);
}
}
}
if (!isset($this->bsize_hash[$classic_size]))
{
if ((strlen($classic_size) > 0) &&
(strlen($classic_price) > 0))
{
// non-numeric entries are ignored since these are N/A == they don't sell it
if ((is_numeric($classic_price)) &&
(is_numeric($classic_tradein_price)))
{
$this->addBatterySize($classic_size, $classic_price, $classic_tradein_price);
}
}
}
if (!isset($this->bsize_hash[$excel_size]))
{
if ((strlen($excel_size) > 0) &&
(strlen($excel_price) > 0))
{
// non-numeric entries are ignored since these are N/A == they don't sell it
if ((is_numeric($excel_price)) &&
(is_numeric($excel_tradein_price)))
{
$this->addBatterySize($excel_size, $excel_price, $excel_tradein_price);
}
}
}
if (!isset($this->bsize_hash[$sdfc_size]))
{
if ((strlen($sdfc_size) > 0) &&
(strlen($sdfc_price) > 0))
{
// non-numeric entries are ignored since these are N/A == they don't sell it
if ((is_numeric($sdfc_price)) &&
(is_numeric($sdfc_tradein_price)))
{
$this->addBatterySize($sdfc_size, $sdfc_price, $sdfc_tradein_price);
}
}
}
$row_num++;
}
// output the battery sizes that were not added
if (count($not_added) > 0)
{
fputcsv($out_fh, [
'Battery Model',
'Battery Size',
'Price',
'Trade In Price',
'Reason',
]);
foreach($not_added as $row)
{
fputcsv($out_fh, $row);
}
}
fclose($out_fh);
}
protected function createBatteryManufacturerData()
{
foreach ($this->batt_manufacturers as $name)
{
$new_bmanu = new BatteryManufacturer();
$new_bmanu->setName($name);
$this->em->persist($new_bmanu);
}
$this->em->flush();
}
protected function createBatteryModelData()
{
foreach ($this->batt_models as $name)
{
$new_bmodel = new BatteryModel();
$new_bmodel->setName($name);
$this->em->persist($new_bmodel);
}
$this->em->flush();
}
protected function addBatterySize($size, $price, $tradein_price)
{
$new_bsize = new BatterySize();
$clean_size = strtoupper($size);
// check if size is M-42, if so, we need to change it to M42
if (strpos($clean_size, 'M-42') !== false)
{
$clean_size = strtoupper(str_replace('-', '', $size));
}
$new_bsize->setName(strtoupper($clean_size));
$new_bsize->setTIPriceMotolite($tradein_price);
$this->em->persist($new_bsize);
// add to hash
$this->bsize_hash[$size] = $new_bsize;
$this->em->flush();
}
protected function addInvalidEntry($model, $size, $price,
$tradein_price, $reason)
{
$entry = [
$model,
$size,
$price,
$tradein_price,
$reason,
];
return $entry;
}
protected function loadBatteryManufacturers()
{
$this->bmanu_hash = [];
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
foreach ($batt_manufacturers as $batt_manu)
{
$name = $this->normalizeName($batt_manu->getName());
$this->bmanu_hash[$name] = $batt_manu;
}
}
protected function loadBatteryModels()
{
$this->bmodel_hash = [];
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
foreach ($batt_models as $batt_model)
{
$name = $this->normalizeName($batt_model->getName());
$this->bmodel_hash[$name] = $batt_model;
}
}
protected function loadBatterySizes()
{
$this->bsize_hash = [];
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
foreach ($batt_sizes as $batt_size)
{
$name = $this->normalizeName($batt_size->getName());
$this->bsize_hash[$name] = $batt_size;
}
}
protected function loadBatteries()
{
$this->batt_hash = [];
$batts = $this->em->getRepository(Battery::class)->findAll();
foreach ($batts as $batt)
{
$brand = $this->normalizeName($batt->getManufacturer()->getName());
$model = $this->normalizeName($batt->getModel()->getName());
$size = $this->normalizeName($batt->getSize()->getName());
$this->batt_hash[$brand][$model][$size] = $batt;
}
}
protected function normalizeName($name)
{
$normalized_key = trim(strtolower($name));
return $normalized_key;
}
}

View file

@ -0,0 +1,373 @@
<?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 App\Entity\BatteryManufacturer;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\Battery;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
class ImportCMBBatteryVehicleCompatibilityCommand extends Command
{
// field index in csv file
// vehicle info
const F_VEHICLE_MANUFACTURER = 1;
const F_VEHICLE_MAKE = 2;
const F_VEHICLE_YEAR = 3;
// CENTURY MARATHONER BATTERY
const F_BATT_MARATHONER_SIZE = 4;
const F_BATT_MARATHONER_PRICE = 5;
const F_BATT_MARATHONER_TRADEIN_PRICE = 6;
const F_BATT_MARATHONER_DISCOUNT = 7;
// MOTOLITE CLASSIC BATTERY
const F_BATT_CLASSIC_SIZE = 8;
const F_BATT_CLASSIC_PRICE = 9;
const F_BATT_CLASSIC_TRADEIN_PRICE = 10;
const F_BATT_CLASSIC_DISCOUNT = 11;
// CENTURY EXCEL BATTERY
const F_BATT_EXCEL_SIZE = 12;
const F_BATT_EXCEL_PRICE = 13;
const F_BATT_EXCEL_TRADEIN_PRICE = 14;
const F_BATT_EXCEL_DISCOUNT = 15;
// CENTURY SDFC BATTERY
const F_BATT_SDFC_SIZE = 16;
const F_BATT_SDFC_PRICE = 17;
const F_BATT_SDFC_TRADEIN_PRICE = 18;
const F_BATT_SDFC_DISCOUNT = 19;
// constants for battery manufacturer names
const STR_CENTURY = 'century';
const STR_MOTOLITE = 'motolite';
// constants for battery models
const STR_MARATHONER = 'marathoner';
const STR_CLASSIC = 'classic';
const STR_EXCEL = 'excel';
const STR_SDFC = 'sdfc';
// special case for battery size
const STR_M_42 = 'M-42';
const STR_M42 = 'M42';
// for the model year
const STR_PRESENT = 'Present';
protected $em;
protected $bmanu_hash;
protected $bmodel_hash;
protected $bsize_hash;
protected $batt_hash;
protected $vmanu_hash;
protected $vmake_hash;
public function __construct(EntityManagerInterface $om)
{
$this->em = $om;
// load existing battery data
$this->loadBatteryManufacturers();
$this->loadBatteryModels();
$this->loadBatterySizes();
$this->loadBatteries();
// load existing vehicle data
$this->loadVehicleManufacturers();
$this->loadVehicleMakes();
parent::__construct();
}
protected function configure()
{
$this->setName('cmbbatteryvehiclecompatibility:import')
->setDescription('Retrieve from a CSV file vehicle and battery compatibility information.')
->setHelp('Creates vehicles and their compatible batteries based on data from imported CSV.')
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.')
->addArgument('output_file', InputArgument::REQUIRED, 'Path to output file for vehicles not added.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// get the sizes, vehicles, battery prices from the csv file
$csv_file = $input->getArgument('file');
// attempt to open file
try
{
$fh = fopen($csv_file, "r");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be read.');
}
$output_file = $input->getArgument('output_file');
// attempt to open file
try
{
$output_fh = fopen($output_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $output_file . '" could be read.');
}
// get entity manager
$em = $this->em;
$row_num = 0;
error_log('Processing vehicle and battery compatibility file...');
while (($fields = fgetcsv($fh)) !== false)
{
$comp_batteries = [];
if ($row_num < 2)
{
$row_num++;
continue;
}
// get vehicle info from file
$manufacturer = trim(strtolower($fields[self::F_VEHICLE_MANUFACTURER]));
$make = trim(strtolower($fields[self::F_VEHICLE_MAKE]));
$year = trim($fields[self::F_VEHICLE_YEAR]);
// get battery info from file
$marathoner_size = $this->normalizeName(trim($fields[self::F_BATT_MARATHONER_SIZE]));
$marathoner_price = trim($fields[self::F_BATT_MARATHONER_PRICE]);
$marathoner_tradein_price = trim($fields[self::F_BATT_MARATHONER_TRADEIN_PRICE]);
$classic_size = $this->normalizeName(trim($fields[self::F_BATT_CLASSIC_SIZE]));
$classic_price = trim($fields[self::F_BATT_CLASSIC_PRICE]);
$classic_tradein_price = trim($fields[self::F_BATT_CLASSIC_TRADEIN_PRICE]);
$excel_size = $this->normalizeName(trim($fields[self::F_BATT_EXCEL_SIZE]));
$excel_price = trim($fields[self::F_BATT_EXCEL_PRICE]);
$excel_tradein_price = trim($fields[self::F_BATT_EXCEL_TRADEIN_PRICE]);
$sdfc_size = $this->normalizeName(trim($fields[self::F_BATT_SDFC_SIZE]));
$sdfc_price = trim($fields[self::F_BATT_SDFC_PRICE]);
$sdfc_tradein_price = trim($fields[self::F_BATT_SDFC_TRADEIN_PRICE]);
// get the compatible batteries
// get marathoner battery
if (strlen($marathoner_size) > 0)
{
// check if battery in system
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_MARATHONER][$marathoner_size]))
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_MARATHONER][$marathoner_size];
}
// get classic battery
if (strlen($classic_size) > 0)
{
// check if battery in system
if (isset($this->batt_hash[self::STR_MOTOLITE][self::STR_CLASSIC][$classic_size]))
$comp_batteries[] = $this->batt_hash[self::STR_MOTOLITE][self::STR_CLASSIC][$classic_size];
}
// get excel battery
if (strlen($excel_size) > 0)
{
// check if battery in system
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_EXCEL][$excel_size]))
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_EXCEL][$excel_size];
}
// get sdfc battery
if (strlen($sdfc_size) > 0)
{
// check if battery in system
if (isset($this->batt_hash[self::STR_CENTURY][self::STR_SDFC][$sdfc_size]))
$comp_batteries[] = $this->batt_hash[self::STR_CENTURY][self::STR_SDFC][$sdfc_size];
}
// check if vehicle manufacturer has been added
if (!isset($this->vmanu_hash[$manufacturer]))
$this->addVehicleManufacturer($manufacturer);
// check if vehicle make has been added
if (!isset($this->vmake_hash[$manufacturer][$make]))
{
$this->addVehicleMake($manufacturer, $make, $year, $comp_batteries);
}
$row_num++;
}
$em->flush();
}
protected function addVehicleManufacturer($name)
{
// save to db
$vehicle_manufacturer = new VehicleManufacturer();
$vehicle_manufacturer->setName(strtoupper($name));
$this->em->persist($vehicle_manufacturer);
$this->em->flush();
// add to hash
$this->vmanu_hash[$name] = $vehicle_manufacturer;
}
protected function addVehicleMake($manufacturer, $make, $year, $batteries)
{
// save to db
$vehicle = new Vehicle();
$vmanu = $this->vmanu_hash[$manufacturer];
// parse year from and year to
$year_from = '';
$year_to = '';
if (!empty($year))
{
$model_years = explode('-', $year);
$year_from = $model_years[0];
if (!empty($year_to))
$year_to = $model_years[1];
// check if $year_to is the string "Present"
// if so, set to 0, for now
if ($year_to == self::STR_PRESENT)
$year_to = 0;
}
$vehicle->setManufacturer($vmanu)
->setMake(strtoupper($make))
->setModelYearFrom($year_from)
->setModelYearTo($year_to);
// add vehicle to battery
foreach ($batteries as $battery)
{
$battery->addVehicle($vehicle);
$this->em->persist($battery);
}
// add vehicle to manufacturer
$vmanu->addVehicle($vehicle);
$this->em->persist($vmanu);
$this->em->persist($vehicle);
$this->em->flush();
// add to hash
$this->vmake_hash[$manufacturer][$make] = $vehicle;
}
protected function loadBatteryManufacturers()
{
$this->bmanu_hash = [];
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
foreach ($batt_manufacturers as $batt_manu)
{
$name = $this->normalizeName($batt_manu->getName());
$this->bmanu_hash[$name] = $batt_manu;
}
}
protected function loadBatteryModels()
{
$this->bmodel_hash = [];
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
foreach ($batt_models as $batt_model)
{
$name = $this->normalizeName($batt_model->getName());
$this->bmodel_hash[$name] = $batt_model;
}
}
protected function loadBatterySizes()
{
$this->bsize_hash = [];
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
foreach ($batt_sizes as $batt_size)
{
$name = $this->normalizeName($batt_size->getName());
$this->bsize_hash[$name] = $batt_size;
}
}
protected function loadBatteries()
{
$this->batt_hash = [];
$batts = $this->em->getRepository(Battery::class)->findAll();
foreach ($batts as $batt)
{
$brand = $this->normalizeName($batt->getManufacturer()->getName());
$model = $this->normalizeName($batt->getModel()->getName());
$size = $this->normalizeName($batt->getSize()->getName());
$this->batt_hash[$brand][$model][$size] = $batt;
}
}
protected function loadVehicleManufacturers()
{
$this->vmanu_hash = [];
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
foreach ($vmanus as $vmanu)
{
$name = $this->normalizeName($vmanu->getName());
$this->vmanu_hash[$name] = $vmanu;
}
}
protected function loadVehicleMakes()
{
$this->vmake_hash = [];
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
foreach ($vmakes as $vmake)
{
$manufacturer = $vmake->getManufacturer()->getName();
$make = $this->normalizeName($vmake->getMake());
$this->vmake_hash[$manufacturer][$make] = $vmake;
}
}
protected function normalizeName($name)
{
// check if name contains M-42. Need to convert to M42
if (strpos($name, self::STR_M_42) !== false)
{
// contains M-42
$changed_name = str_replace(self::STR_M_42, self::STR_M42, $name);
$normalized_key = strtolower($changed_name);
}
else
{
$normalized_key = trim(strtolower($name));
}
$normalized_key = trim(strtolower($name));
return $normalized_key;
}
}

View file

@ -0,0 +1,164 @@
<?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 App\Entity\CMBLegacyJobOrderRow;
class ImportCMBLegacyJobOrderCommand extends Command
{
// field index in csv file
const F_INDEX = 0;
const F_CREATED_DATE = 1;
const F_CASE_NO = 2;
const F_INSURER = 3;
const F_VEHICLE_NO = 4;
const F_CAR_MODEL = 5;
const F_NATURE_OF_CALL = 6;
const F_SERVICE_NEEDED = 7;
const F_LOCATION = 8;
const F_STATE = 9;
const F_DRIVER = 10;
const F_TRUCK = 11;
const F_WORKSHOP_ARRIVAL_TIME = 12;
const F_STATUS = 13;
const F_CUSTOMER_NAME = 14;
const F_CUSTOMER_PHONE_NO = 15;
const F_OUR_REFERENCE = 16;
const F_ODOMETER = 17;
const F_BATT_MODEL = 18;
const F_BATT_SIZE = 19;
const F_BATT_TRADE_IN = 20;
const F_REPLACED_BY = 21;
const F_REMARK = 22;
const F_SATISFACTION = 23;
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
public function configure()
{
$this->setName('cmblegacyjoborderdata:import')
->setDescription('Retrieve from a CSV file CarFix data.')
->setHelp('Creates legacy job order entries based on data from imported CSV.')
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.');
}
public function execute(InputInterface $input, OutputInterface $output)
{
$csv_file = $input->getArgument('file');
// 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;
$row_num = 0;
error_log('Processing CarFix data csv file...');
while (($fields = fgetcsv($fh)) !== false)
{
if ($row_num < 1)
{
$row_num++;
continue;
}
// get the information
$entry_num = trim($fields[self::F_INDEX]);
$date_create = trim($fields[self::F_CREATED_DATE]);
$case_number = trim($fields[self::F_CASE_NO]);
$insurer = trim($fields[self::F_INSURER]);
$vehicle_number = trim($fields[self::F_VEHICLE_NO]);
$car_model = trim($fields[self::F_CAR_MODEL]);
$nature_of_call = trim($fields[self::F_NATURE_OF_CALL]);
$service_needed = trim($fields[self::F_SERVICE_NEEDED]);
$location = trim($fields[self::F_LOCATION]);
$state = trim($fields[self::F_STATE]);
$driver = trim($fields[self::F_DRIVER]);
$truck = trim($fields[self::F_TRUCK]);
$workshop_arrival_time = trim($fields[self::F_WORKSHOP_ARRIVAL_TIME]);
$status = trim($fields[self::F_STATUS]);
$customer_name = trim($fields[self::F_CUSTOMER_NAME]);
$customer_mobile = trim($fields[self::F_CUSTOMER_PHONE_NO]);
$reference = trim($fields[self::F_OUR_REFERENCE]);
$odometer = trim($fields[self::F_ODOMETER]);
$batt_model = trim($fields[self::F_BATT_MODEL]);
$batt_size = trim($fields[self::F_BATT_SIZE]);
$trade_in = trim($fields[self::F_BATT_TRADE_IN]);
$replaced_by = trim($fields[self::F_REPLACED_BY]);
$remark = trim($fields[self::F_REMARK]);
$satisfaction = trim($fields[self::F_SATISFACTION]);
$data_entry = $this->processEntry($entry_num, $date_create, $case_number, $insurer, $vehicle_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$trade_in, $replaced_by, $remark, $satisfaction);
$legacy_data = new CMBLegacyJobOrderRow();
$legacy_data->setData($data_entry);
$this->em->persist($legacy_data);
}
$this->em->flush();
$this->em->clear();
return 0;
}
protected function processEntry($entry_num, $date_create, $case_number, $insurer, $vehicle_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$trade_in, $replaced_by, $remark, $satisfaction)
{
$data_entry = [
'entry_num' => $entry_num,
'created_date' => $date_create,
'case_number' => $case_number,
'insurer' => $insurer,
'vehicle_number' => $vehicle_number,
'car_model' => $car_model,
'nature_of_call' => $nature_of_call,
'service_needed' => $service_needed,
'location' => $location,
'state' => $state,
'driver' => $driver,
'truck' => $truck,
'workshop_arrival_time' => $workshop_arrival_time,
'status' => $status,
'customer_name' => $customer_name,
'customer_phone_number' => $customer_mobile,
'reference' => $reference,
'odometer' => $odometer,
'batt_model' => $batt_model,
'batt_size' => $batt_size,
'batt_trade_in' => $trade_in,
'replaced_by' => $replaced_by,
'remark' => $remark,
'satisfaction' => $satisfaction,
];
return $data_entry;
}
}

View file

@ -1,449 +0,0 @@
<?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 App\Entity\BatteryManufacturer;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\Battery;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
class ImportCMBVehicleCompatibilityCommand extends Command
{
// field index in csv file
const F_VEHICLE_MANUFACTURER = 1;
const F_VEHICLE_MAKE = 2;
const F_VEHICLE_YEAR = 3;
const F_BATT_SDFC = 4;
const F_BATT_ULTRAMAX = 5;
const F_BATT_MOTOLITE = 6;
const F_BATT_MARATHONER = 7;
const F_BATT_EXCEL = 8;
const STR_CENTURY = 'Century';
const STR_MOTOLITE = 'Motolite';
const STR_MARSHALL = 'Marshall';
const STR_SDFC = 'SDFC';
const STR_MARATHONER = 'Marathoner';
const STR_WETCHARGED = 'Classic WetCharged';
const STR_ULTRAMAX = 'ULTRAMAX';
const STR_EXCEL = 'Excel';
const STR_PRESENT = 'Present';
const STR_M_42 = 'M-42';
const STR_M42 = 'M42';
protected $em;
protected $bmanu_hash;
protected $bmodel_hash;
protected $bsize_hash;
protected $batt_hash;
protected $vmanu_hash;
protected $vmake_hash;
public function __construct(EntityManagerInterface $om)
{
$this->em = $om;
// load existing battery data
$this->loadBatteryManufacturers();
$this->loadBatteryModels();
$this->loadBatterySizes();
$this->loadBatteries();
// load existing vehicle data
$this->loadVehicleManufacturers();
$this->loadVehicleMakes();
parent::__construct();
}
protected function configure()
{
$this->setName('cmbvehiclecompatibility:import')
->setDescription('Retrieve from a CSV file battery and vehicle information.')
->setHelp('Creates battery manufacturers, models, sizes, vehicle makes, and models based on data from imported CSV.')
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$csv_file = $input->getArgument('file');
// 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;
$row_num = 0;
error_log('Processing vehicle compatibility csv file...');
while (($fields = fgetcsv($fh)) !== false)
{
$comp_batteries = [];
if ($row_num < 2)
{
$row_num++;
continue;
}
// initialize size battery array for cases where the battery size has '/'
$sdfc_sizes = [];
$ultramax_sizes = [];
$motolite_sizes = [];
$marathoner_sizes = [];
$excel_sizes = [];
// battery info
$sdfc_size = trim($fields[self::F_BATT_SDFC]);
$ultramax_size = trim($fields[self::F_BATT_ULTRAMAX]);
$motolite_size = trim($fields[self::F_BATT_MOTOLITE]);
$marathoner_size = trim($fields[self::F_BATT_MARATHONER]);
$excel_size = trim($fields[self::F_BATT_EXCEL]);
// check the sizes for '/'
$pos = stripos($sdfc_size, '/');
if ($pos == false)
{
// no '/' in size
$sdfc_sizes[] = $this->normalizeName($sdfc_size);
}
else
{
// we have '/' in size so we have to explode
$sizes = explode('/', $sdfc_size);
foreach ($sizes as $size)
{
$sdfc_sizes[] = $this->normalizeName($size);
}
}
$pos = stripos($motolite_size, '/');
if ($pos == false)
{
// no '/' in size
$motolite_sizes[] = $this->normalizeName($motolite_size);
}
else
{
// we have '/' in size so we have to explode
$sizes = explode('/', $motolite_size);
foreach ($sizes as $size)
{
$motolite_sizes[] = $this->normalizeName($size);
}
}
$pos = stripos($marathoner_size, '/');
if ($pos == false)
{
// no '/' in size
$marathoner_sizes[] = $this->normalizeName($marathoner_size);
}
else
{
// we have '/' in size so we have to explode
$sizes = explode('/', $marathoner_size);
foreach ($sizes as $size)
{
$marathoner_sizes[] = $this->normalizeName($size);
}
}
$pos = stripos($ultramax_size, '/');
if ($pos == false)
{
// no '/' in size
$ultramax_sizes[] = $this->normalizeName($ultramax_size);
}
else
{
// we have '/' in size so we have to explode
$sizes = explode('/', $ultramax_size);
foreach ($sizes as $size)
{
$ultramax_sizes[] = $this->normalizeName($size);
}
}
$pos = stripos($excel_size, '/');
if ($pos == false)
{
// no '/' in size
$excel_sizes[] = $this->normalizeName($excel_size);
}
else
{
// we have '/' in size so we have to explode
$sizes = explode('/', $excel_size);
foreach ($sizes as $size)
{
$excel_sizes[] = $this->normalizeName($size);
}
}
// normalize the battery manufacturers and battery models
$norm_century = $this->normalizeName(self::STR_CENTURY);
$norm_sdfc = $this->normalizeName(self::STR_SDFC);
$norm_motolite = $this->normalizeName(self::STR_MOTOLITE);
$norm_wetcharged = $this->normalizeName(self::STR_WETCHARGED);
$norm_marathoner = $this->normalizeName(self::STR_MARATHONER);
$norm_ultramax = $this->normalizeName(self::STR_ULTRAMAX);
$norm_excel = $this->normalizeName(self::STR_EXCEL);
//foreach($sdfc_sizes as $size)
//{
// error_log('sdfc size ' . $size);
//}
//foreach($motolite_sizes as $size)
//{
// error_log('motolite size ' . $size);
//}
//foreach($marathoner_sizes as $size)
//{
// error_log('marathoner size ' . $size);
//}
// vehicle info
$manufacturer = trim($fields[self::F_VEHICLE_MANUFACTURER]);
$make = trim($fields[self::F_VEHICLE_MAKE]);
$year = trim($fields[self::F_VEHICLE_YEAR]);
// vehicle data
// check if vehicle manufacturer has been added
if (!isset($this->vmanu_hash[$manufacturer]))
$this->addVehicleManufacturer($manufacturer);
// check if vehicle make has been added
if (!isset($this->vmake_hash[$manufacturer][$make]))
{
foreach($sdfc_sizes as $size)
{
if (!(empty($size)))
{
if (isset($this->batt_hash[$norm_century][$norm_sdfc][$size]))
$comp_batteries[] = $this->batt_hash[$norm_century][$norm_sdfc][$size];
else
error_log('Not in the system: ' . $norm_century . ' ' . $norm_sdfc . ' ' . $size);
}
}
foreach($ultramax_sizes as $size)
{
if (!(empty($size)))
{
if (isset($this->batt_hash[$norm_ultramax][$norm_ultramax][$size]))
$comp_batteries[] = $this->batt_hash[$norm_ultramax][$norm_ultramax][$size];
else
error_log('Not in the system: ' . $norm_ultramax . ' ' . $norm_ultramax . ' ' . $size);
}
}
foreach($motolite_sizes as $size)
{
if (!(empty($size)))
{
if (isset($this->batt_hash[$norm_motolite][$norm_wetcharged][$size]))
$comp_batteries[] = $this->batt_hash[$norm_motolite][$norm_wetcharged][$size];
else
error_log('Not in the system: ' . $norm_motolite . ' ' . $norm_wetcharged . ' ' . $size);
}
}
foreach($marathoner_sizes as $size)
{
if (!(empty($size)))
{
if (isset($this->batt_hash[$norm_century][$norm_marathoner][$size]))
$comp_batteries[] = $this->batt_hash[$norm_century][$norm_marathoner][$size];
else
error_log('Not in the system: ' . $norm_century . ' ' . $norm_marathoner . ' ' . $size);
}
}
foreach($excel_sizes as $size)
{
if (!(empty($size)))
{
if (isset($this->batt_hash[$norm_excel][$norm_excel][$size]))
$comp_batteries[] = $this->batt_hash[$norm_excel][$norm_excel][$size];
else
error_log('Not in the system: ' . $norm_excel . ' ' . $norm_excel . ' ' . $size);
}
}
$this->addVehicleMake($manufacturer, $make, $year, $comp_batteries);
}
$row_num++;
}
return 0;
}
protected function addVehicleManufacturer($name)
{
// save to db
$vehicle_manufacturer = new VehicleManufacturer();
$vehicle_manufacturer->setName($name);
$this->em->persist($vehicle_manufacturer);
$this->em->flush();
// add to hash
$this->vmanu_hash[$name] = $vehicle_manufacturer;
}
protected function addVehicleMake($manufacturer, $make, $year, $batteries)
{
// save to db
$vehicle = new Vehicle();
$vmanu = $this->vmanu_hash[$manufacturer];
// parse year from and year to
$year_from = '';
$year_to = '';
if (!empty($year))
{
$model_years = explode('-', $year);
$year_from = $model_years[0];
if (!empty($year_to))
$year_to = $model_years[1];
// check if $year_to is the string "Present"
// if so, set to 0, for now
if ($year_to == self::STR_PRESENT)
$year_to = 0;
}
$vehicle->setManufacturer($vmanu)
->setMake($make)
->setModelYearFrom($year_from)
->setModelYearTo($year_to);
// add vehicle to battery
foreach ($batteries as $battery)
{
$battery->addVehicle($vehicle);
$this->em->persist($battery);
}
// add vehicle to manufacturer
$vmanu->addVehicle($vehicle);
$this->em->persist($vmanu);
$this->em->persist($vehicle);
$this->em->flush();
// add to hash
$this->vmake_hash[$manufacturer][$make] = $vehicle;
}
protected function loadBatteryManufacturers()
{
$this->bmanu_hash = [];
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
foreach ($batt_manufacturers as $batt_manu)
{
$name = $this->normalizeName($batt_manu->getName());
$this->bmanu_hash[$name] = $batt_manu;
}
}
protected function loadBatteryModels()
{
$this->bmodel_hash = [];
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
foreach ($batt_models as $batt_model)
{
$name = $this->normalizeName($batt_model->getName());
$this->bmodel_hash[$name] = $batt_model;
}
}
protected function loadBatterySizes()
{
$this->bsize_hash = [];
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
foreach ($batt_sizes as $batt_size)
{
$name = $this->normalizeName($batt_size->getName());
$this->bsize_hash[$name] = $batt_size;
}
}
protected function loadBatteries()
{
$this->batt_hash = [];
$batts = $this->em->getRepository(Battery::class)->findAll();
foreach ($batts as $batt)
{
$brand = $this->normalizeName($batt->getManufacturer()->getName());
$model = $this->normalizeName($batt->getModel()->getName());
$size = $this->normalizeName($batt->getSize()->getName());
$this->batt_hash[$brand][$model][$size] = $batt;
}
}
protected function loadVehicleManufacturers()
{
$this->vmanu_hash = [];
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
foreach ($vmanus as $vmanu)
{
$name = $vmanu->getName();
$this->vmanu_hash[$name] = $vmanu;
}
}
protected function loadVehicleMakes()
{
$this->vmake_hash = [];
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
foreach ($vmakes as $vmake)
{
$manufacturer = $vmake->getManufacturer()->getName();
$make = $vmake->getMake();
$this->vmake_hash[$manufacturer][$make] = $vmake;
}
}
protected function normalizeName($name)
{
// check for M-42. Need to convert to M42
if (strcasecmp($name, self::STR_M_42) == 0)
{
$normalized_key = strtolower(self::STR_M42);
}
else
{
$normalized_key = trim(strtolower($name));
}
return $normalized_key;
}
}

View file

@ -0,0 +1,560 @@
<?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 App\Entity\CMBLegacyJobOrderRow;
use App\Entity\CMBLegacyJobOrder;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
use App\Entity\BatteryManufacturer;
use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\Battery;
use App\Entity\Customer;
use App\Entity\CustomerVehicle;
use App\Ramcar\CMBServiceType;
use App\Ramcar\JOStatus;
use App\Ramcar\FuelType;
use App\Ramcar\VehicleStatusCondition;
use DateTime;
class MigrateCMBLegacyJobOrderCommand extends Command
{
/*
id = 'entry_num'
trans_date = 'created_date'
case_number = 'case_number'
insurer = 'insurer'
plate_number = 'vehicle_number'
car_brand and car_make = split the 'car_model'
nature_of_call = nature_of_call
trans_type = 'service_needed'
address = 'location'
address = 'state'
driver = 'driver'
truck = 'truck'
workshop_arrival_time => 'workshop_arrival_time'
status = 'status'
cust_name = 'customer_name'
cust_mobile = 'customer_phone_number'
reference = 'reference'
odometer = 'odometer'
batt_model = 'batt_model'
batt_size = 'batt_size'
is_trade_in = 'batt_trade_in'
replaced_by = 'replaced_by'
remarks = 'remark'
satisfaction => 'satisfaction'
*/
protected $em;
protected $bmanu_hash;
protected $bmodel_hash;
protected $bsize_hash;
protected $batt_hash;
protected $vmanu_hash;
protected $vmake_hash;
protected $cv_hash;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
// load existing battery data
$this->loadBatteryManufacturers();
$this->loadBatteryModels();
$this->loadBatterySizes();
$this->loadBatteries();
// load existing vehicle data
$this->loadVehicleManufacturers();
$this->loadVehicleMakes();
// load existing customer vehicle data
$this->loadCustomerVehicles();
parent::__construct();
}
public function configure()
{
$this->setName('cmblegacyjoborderdata:migrate')
->setDescription('Retrieve database cmb legacy job orders and insert into job order.')
->setHelp('Creates job orders based on data from imported CSV.')
->addArgument('output_file', InputArgument::REQUIRED, 'Path to the output CSV file of the entries not added.');
}
public function execute(InputInterface $input, OutputInterface $output)
{
$csv_file = $input->getArgument('output_file');
// attempt to open file
try
{
$fh = fopen($csv_file, "w");
}
catch (Exception $e)
{
throw new Exception('The file "' . $csv_file . '" could be opened.');
}
// get all legacy job orders
$query = $this->em->createQuery('SELECT legacy_jo_row FROM App\Entity\CMBLegacyJobOrderRow legacy_jo_row');
$result = $query->iterate();
$invalid_entries = [];
$added_entries = 0;
$total_entries = 0;
$total_inv_entries = 0;
foreach ($result as $row)
{
$entry = $row[0];
$jo_entry = $entry->getData();
$total_entries++;
// get the entry information
$entry_num = $jo_entry['entry_num'];
$date_create = $jo_entry['created_date'];
$case_number = $jo_entry['case_number'];
$insurer = $jo_entry['insurer'];
$plate_number = $this->cleanPlateNumber($jo_entry['vehicle_number']);
$car_model = $this->normalizeName($jo_entry['car_model']);
$nature_of_call = $jo_entry['nature_of_call'];
$service_needed = $jo_entry['service_needed'];
$location = $jo_entry['location'];
$state = $jo_entry['state'];
$driver = $jo_entry['driver'];
$truck = $jo_entry['truck'];
$workshop_arrival_time = $jo_entry['workshop_arrival_time'];
$status = $jo_entry['status'];
$customer_name = $jo_entry['customer_name'];
$customer_mobile = $jo_entry['customer_phone_number'];
$reference = $jo_entry['reference'];
$odometer = $jo_entry['odometer'];
$batt_model = $this->normalizeName($jo_entry['batt_model']);
$batt_size = $this->normalizeName($jo_entry['batt_size']);
$batt_trade_in = $jo_entry['batt_trade_in'];
$replaced_by = $jo_entry['replaced_by'];
$remark = $jo_entry['remark'];
$satisfaction = $jo_entry['satisfaction'];
// check vehicle info if valid
$v_status = $this->processVehicleInfo($car_model);
if ($v_status != null)
{
//error_log($v_status . ' ' . $car_model);
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$batt_trade_in, $replaced_by, $remark, $satisfaction, $v_status);
$total_inv_entries++;
// move to next entry
continue;
}
// check battery info if valid
$batt_status = $this->processBatteryInfo($batt_model, $batt_size);
if ($batt_status != null)
{
//error_log($batt_status . ' ' . $batt_model . ' ' . $batt_size);
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$batt_trade_in, $replaced_by, $remark, $satisfaction, $batt_status);
$total_inv_entries++;
// move to next entry
continue;
}
// check if mobile phone number has letters or spaces or special characters
if (!(preg_match('/^\d+$/', $customer_mobile)))
{
// not a valid mobile number
//error_log('invalid number ' . $customer_mobile);
$invalid_entries[] = $this->addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$batt_trade_in, $replaced_by, $remark, $satisfaction, 'Invalid mobile number');
$total_inv_entries++;
// move to next entry
continue;
}
// create job order
$cmb_legacy_jo = new CMBLegacyJobOrder();
// date_create
$created_date = DateTime::createFromFormat("d-m-Y H:i", $date_create);
$cmb_legacy_jo->setTransDate($created_date);
// parse vehicle info
// get vehicle from hash
$v_array = explode(' ', $car_model);
// manufacturer
$v_manufacturer = trim($v_array[0]);
// get model
$model_info = '';
$v_model = '';
for ($i = 1; $i < count($v_array); $i++)
{
$model_info = $model_info . ' ' . trim($v_array[$i]);
}
$v_model = trim($model_info);
// delivery address = location + state
$delivery_address = $location . ', ' . $state;
// check if trade in
$trade_in = false;
if (strtolower($batt_trade_in) == 'yes')
$trade_in = true;
$cmb_legacy_jo->setCaseNumber($case_number)
->setInsurer($insurer)
->setNatureOfCall($nature_of_call)
->setTransType($service_needed)
->setCarBrand(strtoupper($v_manufacturer))
->setCarMake(strtoupper($v_model))
->setCustName($customer_name)
->setCustMobile($customer_mobile)
->setAddress($delivery_address)
->setDriver($driver)
->setTruck($truck)
->setWorkshopArrivalTime($workshop_arrival_time)
->setPlateNumber($plate_number)
->setStatus($status)
->setReference($reference)
->setOdometer($odometer)
->setBatteryModel(strtoupper($batt_model))
->setBatterySize(strtoupper($batt_size))
->setIsTradeIn($trade_in)
->setReplacedBy($replaced_by)
->setSatisfaction($satisfaction);
// plate number == vehicle_number. Use as key to cv_hash
// check if plate number has been added
if (!isset($this->cv_hash[$plate_number]))
{
$cust = $this->addCustomer($customer_name, $customer_mobile);
$cv = $this->addCustomerVehicle($plate_number, $car_model, $cust);
}
$this->em->persist($cmb_legacy_jo);
$this->em->detach($row[0]);
$added_entries++;
}
$this->em->flush();
$this->em->clear();
// output the entries that were not added
if (count($invalid_entries) > 0)
{
fputcsv($fh, [
'Entry Num',
'Created Date',
'Case Number',
'Insurer',
'Vehicle Number',
'Car Model',
'Nature of Call',
'Service Needed',
'Location',
'State',
'Driver',
'Truck',
'Workshop Arrival Time',
'Status',
'Customer Name',
'Customer Phone Number',
'Reference',
'Odometer',
'Batt Model',
'Batt Size',
'Batt Trade In',
'Replaced By',
'Remark',
'Satisfaction',
'Reason',
]);
foreach($invalid_entries as $row)
{
fputcsv($fh, $row);
}
}
fclose($fh);
error_log('Processed ' . $total_entries . ' entries.');
error_log('Added ' . $added_entries . ' entries.');
error_log('Did not add ' . $total_inv_entries . ' entries.');
return 0;
}
protected function processVehicleInfo($car_model)
{
// vehicle manufacturer is the first entry
// vehicle model is the 2nd entry + whatever follows
$v_array = explode(' ', $car_model);
// manufacturer
$v_manufacturer = trim($v_array[0]);
// get model
$model_info = '';
$v_model = '';
for ($i = 1; $i < count($v_array); $i++)
{
$model_info = $model_info . ' ' . trim($v_array[$i]);
}
$v_model = trim($model_info);
//error_log($v_manufacturer . ' ' . $v_model);
// check if manufacturer is in hash
if (!isset($this->vmanu_hash[$v_manufacturer]))
{
//error_log($v_manufacturer . ' invalid.');
return 'Vehicle manufacturer not in system.';
}
// check if manufacturer and make is in hash
if (!isset($this->vmake_hash[$v_manufacturer][$v_model]))
{
//error_log($v_model . ' invalid.');
return 'Vehicle model not in system.';
}
// car model info valid
return null;
}
protected function processBatteryInfo($batt_model, $batt_size)
{
// check if battery model is in hash
if (!isset($this->bmodel_hash[$batt_model]))
return 'Battery model not in system.';
// check if battery size is in hash
if (!isset($this->bsize_hash[$batt_size]))
return 'Battery size not in system.';
// battery info valid
return null;
}
protected function addInvalidEntry($entry_num, $date_create, $case_number, $insurer, $plate_number, $car_model,
$nature_of_call, $service_needed, $location, $state, $driver, $truck, $workshop_arrival_time,
$status, $customer_name, $customer_mobile, $reference, $odometer, $batt_model, $batt_size,
$batt_trade_in, $replaced_by, $remark, $satisfaction, $v_status)
{
$inv_entry = [
'number' => $entry_num,
'created_date' => $date_create,
'case_number' => $case_number,
'insurer' => $insurer,
'vehicle_number' => $plate_number,
'car_model' => $car_model,
'nature_of_call' => $nature_of_call,
'service_needed' => $service_needed,
'location' => $location,
'state' => $state,
'driver' => $driver,
'truck' => $truck,
'workshop_arrival_time' => $workshop_arrival_time,
'status' => $status,
'customer_name' => $customer_name,
'customer_phone_number' => $customer_mobile,
'reference' => $reference,
'odometer' => $odometer,
'batt_model' => $batt_model,
'batt_size' => $batt_size,
'batt_trade_in' => $batt_trade_in,
'replaced_by' => $replaced_by,
'remark' => $remark,
'satisfaction' => $satisfaction,
'reason' => $v_status,
];
return $inv_entry;
}
protected function addCustomer($name, $mobile)
{
$new_cust = new Customer();
$new_cust->setFirstName($name)
->setLastName('')
->setPhoneMobile($mobile);
$this->em->persist($new_cust);
return $new_cust;
}
protected function addCustomerVehicle($plate_num, $car_model, $customer)
{
$new_cv = new CustomerVehicle();
// get vehicle from hash
$v_array = explode(' ', $car_model);
// manufacturer
$v_manufacturer = trim($v_array[0]);
// get model
$model_info = '';
$v_model = '';
for ($i = 1; $i < count($v_array); $i++)
{
$model_info = $model_info . ' ' . trim($v_array[$i]);
}
$v_model = trim($model_info);
$vehicle = $this->vmake_hash[$v_manufacturer][$v_model];
$new_cv->setCustomer($customer)
->setPlateNumber($plate_num)
->setStatusCondition(VehicleStatusCondition::BRAND_NEW)
->setModelYear('')
->setColor('')
->setFuelType(FuelType::GAS)
->setHasMotoliteBattery(true)
->setVehicle($vehicle);
$this->em->persist($new_cv);
// add customer vehicle to cv_hash
$this->cv_hash[$plate_num] = $new_cv;
return $new_cv;
}
protected function loadBatteryManufacturers()
{
$this->bmanu_hash = [];
$batt_manufacturers = $this->em->getRepository(BatteryManufacturer::class)->findAll();
foreach ($batt_manufacturers as $batt_manu)
{
$name = $this->normalizeName($batt_manu->getName());
$this->bmanu_hash[$name] = $batt_manu;
}
}
protected function loadBatteryModels()
{
$this->bmodel_hash = [];
$batt_models = $this->em->getRepository(BatteryModel::class)->findAll();
foreach ($batt_models as $batt_model)
{
$name = $this->normalizeName($batt_model->getName());
$this->bmodel_hash[$name] = $batt_model;
}
}
protected function loadBatterySizes()
{
$this->bsize_hash = [];
$batt_sizes = $this->em->getRepository(BatterySize::class)->findAll();
foreach ($batt_sizes as $batt_size)
{
$name = $this->normalizeName($batt_size->getName());
$this->bsize_hash[$name] = $batt_size;
}
}
protected function loadBatteries()
{
$this->batt_hash = [];
$batts = $this->em->getRepository(Battery::class)->findAll();
foreach ($batts as $batt)
{
$brand = $this->normalizeName($batt->getManufacturer()->getName());
$model = $this->normalizeName($batt->getModel()->getName());
$size = $this->normalizeName($batt->getSize()->getName());
$this->batt_hash[$brand][$model][$size] = $batt;
}
}
protected function loadVehicleManufacturers()
{
$this->vmanu_hash = [];
$vmanus = $this->em->getRepository(VehicleManufacturer::class)->findAll();
foreach ($vmanus as $vmanu)
{
$name = $this->normalizeName($vmanu->getName());
$this->vmanu_hash[$name] = $vmanu;
}
}
protected function loadVehicleMakes()
{
$this->vmake_hash = [];
$vmakes = $this->em->getRepository(Vehicle::class)->findAll();
foreach ($vmakes as $vmake)
{
$manufacturer = $this->normalizeName($vmake->getManufacturer()->getName());
$make = $this->normalizeName($vmake->getMake());
$this->vmake_hash[$manufacturer][$make] = $vmake;
}
}
protected function loadCustomerVehicles()
{
$this->cv_hash = [];
$cvs = $this->em->getRepository(CustomerVehicle::class)->findAll();
foreach ($cvs as $cv)
{
$plate_number = $this->cleanPlateNumber($cv->getPlateNumber());
$this->cv_hash[$plate_number] = $cv;
}
}
protected function normalizeName($name)
{
$normalized_key = trim(strtolower($name));
return $normalized_key;
}
protected function cleanPlateNumber($plate_number)
{
// remove spaces and make upper case
$clean_plate_number = strtoupper(str_replace(' ' , '', $plate_number));
return $clean_plate_number;
}
}

View file

@ -0,0 +1,395 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="cmb_legacy_job_order")
*/
class CMBLegacyJobOrder
{
// legacy internal id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="datetime")
*/
protected $trans_date;
/**
* @ORM\Column(type="string", length=30, nullable=true)
*/
protected $case_number;
/**
* @ORM\Column(type="string", length=30, nullable=true)
*/
protected $insurer;
/**
* @ORM\Column(type="string", length=20, nullable=true)
*/
protected $plate_number;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $trans_type;
/**
* @ORM\Column(type="string", length=20, nullable=true)
*/
protected $car_brand;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $car_make;
/**
* @ORM\Column(type="string", length=30, nullable=true)
*/
protected $nature_of_call;
/**
* @ORM\Column(type="string", length=400, nullable=true)
*/
protected $address;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $driver;
/**
* @ORM\Column(type="string", length=20, nullable=true)
*/
protected $truck;
/**
* @ORM\Column(type="integer", nullable=true)
*/
protected $workshop_arrival_time;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $status;
/**
* @ORM\Column(type="string", length=100, nullable=true)
*/
protected $cust_name;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $cust_mobile;
/**
* @ORM\Column(type="string", length=20, nullable=true)
*/
protected $reference;
/**
* @ORM\Column(type="integer", nullable=true)
*/
protected $odometer;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $batt_model;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $batt_size;
/**
* @ORM\Column(type="boolean", options={"default":false})
*/
protected $flag_trade_in;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $replaced_by;
/**
* @ORM\Column(type="string", length=4000, nullable=true)
*/
protected $remarks;
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $satisfaction;
public function __construct()
{
$this->trans_date = new DateTime();
}
public function setID($id)
{
$this->id = $id;
return $this;
}
public function getID()
{
return $this->id;
}
public function setTransDate(DateTime $trans_date)
{
$this->trans_date = $trans_date;
return $this;
}
public function getTransDate()
{
return $this->trans_date;
}
public function setTransType($trans_type)
{
$this->trans_type = $trans_type;
return $this;
}
public function getTransType()
{
return $this->trans_type;
}
public function setCaseNumber($case_number)
{
$this->case_number = $case_number;
return $this;
}
public function getCaseNumber()
{
return $this->case_number;
}
public function setInsurer($insurer)
{
$this->insurer = $insurer;
return $this;
}
public function getInsurer()
{
return $this->insurer;
}
public function setNatureOfCall($nature_of_call)
{
$this->nature_of_call = $nature_of_call;
return $this;
}
public function getNatureOfCall()
{
return $this->nature_of_call;
}
public function setPlateNumber($plate_number)
{
$this->plate_number = $plate_number;
return $this;
}
public function getPlateNumber()
{
return $this->plate_number;
}
public function setCarBrand($car_brand)
{
$this->car_brand = $car_brand;
return $this;
}
public function getCarBrand()
{
return $this->car_brand;
}
public function setCarMake($car_make)
{
$this->car_make = $car_make;
return $this;
}
public function getCarMake()
{
return $this->car_make;
}
public function setAddress($address)
{
$this->address = $address;
return $this;
}
public function getAddress()
{
return $this->address;
}
public function setDriver($driver)
{
$this->driver = $driver;
return $this;
}
public function getDriver()
{
return $this->driver;
}
public function setTruck($truck)
{
$this->truck = $truck;
return $this;
}
public function getTruck()
{
return $this->truck;
}
public function setWorkshopArrivalTime($workshop_arrival_time)
{
$this->workshop_arrival_time = $workshop_arrival_time;
return $this;
}
public function getWorkshopArrivalTime()
{
return $this->workshop_arrival_time;
}
public function setStatus($status)
{
$this->status = $status;
return $this;
}
public function getStatus()
{
return $this->status;
}
public function setCustName($cust_name)
{
$this->cust_name = $cust_name;
return $this;
}
public function getCustName()
{
return $this->cust_name;
}
public function setCustMobile($cust_mobile)
{
$this->cust_mobile = $cust_mobile;
return $this;
}
public function getCustMobile()
{
return $this->cust_mobile;
}
public function setReference($reference)
{
$this->reference = $reference;
return $this;
}
public function getReference()
{
return $this->reference;
}
public function setOdometer($odometer)
{
$this->odometer = $odometer;
return $this;
}
public function getOdometer()
{
return $this->odometer;
}
public function setBatteryModel($batt_model)
{
$this->batt_model = $batt_model;
return $this;
}
public function getBatteryModel()
{
return $this->batt_model;
}
public function setBatterySize($batt_size)
{
$this->batt_size = $batt_size;
return $this;
}
public function getBatterySize()
{
return $this->batt_size;
}
public function setIsTradeIn($flag_trade_in = true)
{
$this->flag_trade_in = $flag_trade_in;
return $this;
}
public function isTradeIn()
{
return $this->flag_trade_in;
}
public function setReplacedBy($replaced_by)
{
$this->replaced_by = $replaced_by;
return $this;
}
public function getReplacedBy()
{
return $this->replaced_by;
}
public function setSatisfaction($satisfaction)
{
$this->satisfaction = $satisfaction;
return $this;
}
public function getSatisfaction()
{
return $this->satisfaction;
}
}

View file

@ -0,0 +1,57 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="cmb_legacy_job_order_row")
*/
class CMBLegacyJobOrderRow
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// data from csv file
/**
* @ORM\Column(type="json")
*/
protected $data;
public function __construct()
{
$this->data = [];
}
public function addData($id, $value)
{
$this->data[$id] = $value;
return $this;
}
public function setData(array $data_array)
{
$this->data = $data_array;
return $this;
}
public function getDataById($id)
{
// return null if we don't have it
if (!isset($this->data[$id]))
return null;
return $this->data[$id];
}
public function getData()
{
return $this->data;
}
}

View file

@ -34,7 +34,7 @@ class Customer
// first name
/**
* @ORM\Column(type="string", length=80)
* @ORM\Column(type="string", length=100)
* @Assert\NotBlank()
*/
protected $first_name;
@ -42,7 +42,6 @@ class Customer
// last name
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $last_name;
@ -66,7 +65,7 @@ class Customer
// mobile phone
/**
* @ORM\Column(type="string", length=30)
* @ORM\Column(type="string", length=50)
*/
protected $phone_mobile;