resq/src/Command/ImportCustomerCommand.php

483 lines
17 KiB
PHP

<?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\Common\Persistence\ObjectManager;
use DateTime;
use App\Entity\Customer;
use App\Entity\CustomerVehicle;
use App\Entity\Vehicle;
use App\Entity\VehicleManufacturer;
use App\Ramcar\FuelType;
use App\Ramcar\VehicleStatusCondition;
class ImportCustomerCommand extends Command
{
// field index in csv file
const F_ID = 0;
const F_DATE_CREATED = 1;
const F_TITLE = 2;
const F_FIRST_NAME = 3;
const F_MIDDLE_NAME = 4;
const F_LAST_NAME = 5;
const F_ROLE = 6;
const F_MEH_CONTACT = 7;
const F_MOBILE_PHONE = 8;
const F_LANDLINE = 9;
const F_OFFICE_PHONE = 10;
const F_FAX = 11;
const F_EMAIL = 12;
const F_PLATE_NUMBER = 13;
const F_V_BRAND = 14;
const F_V_MAKE = 15;
const F_V_MODEL = 16;
const F_V_COLOR = 17;
const F_CUSTOMER_CLASS = 18;
const F_COMMENTS = 19;
const F_NOTES = 20;
protected $em;
// NOTE: we use indeces for these since we tend to run out of memory if we don't
protected $mfg_index;
protected $vehicle_index;
public function __construct(ObjectManager $em)
{
$this->em = $em;
$this->populateMfgIndex();
$this->populateVehicleIndex();
parent::__construct();
}
protected function configure()
{
$this->setName('customer:import')
->setDescription('Import a CSV file with customers.')
->setHelp('Creates customers based on imported CSV.')
->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.');
}
protected function populateMfgIndex()
{
$mfgs = $this->em->getRepository(VehicleManufacturer::class)->findAll();
$this->mfg_index = [];
foreach ($mfgs as $mfg)
{
$name = $mfg->getName();
$this->mfg_index[$name] = $mfg;
// exceptions and special cases
switch ($name)
{
case 'PROTON':
$this->mfg_index['PROTON WIRA'] = $mfg;
break;
case 'OWNER TYPE JEEP':
$this->mfg_index['UNKNOWN'] = $mfg;
break;
case 'GOLF CART':
$this->mfg_index['YAMAHA'] = $mfg;
break;
}
}
}
protected function populateVehicleIndex()
{
$vs = $this->em->getRepository(Vehicle::class)->findAll();
$this->vehicle_index = [];
foreach ($vs as $v)
{
$make = strtoupper($v->getMake());
$mfg_id = $v->getManufacturer()->getID();
$model = $v->getModelYearFormatted();
$this->vehicle_index[$mfg_id][$make][$model] = $v;
// exceptions and special cases for makes
switch ($make)
{
case 'ALMERA':
$this->vehicle_index[$mfg_id]['ALMIRA'][$model] = $v;
break;
case 'TRAILBLAZER':
$this->vehicle_index[$mfg_id]['TRAILBLAZER 2013 LOW'][$model] = $v;
$this->vehicle_index[$mfg_id]['TRAILBLAZER 2014'][$model] = $v;
break;
case 'INNOVA (E-TYPE)':
$this->vehicle_index[$mfg_id]['INNOVA GAS E'][$model] = $v;
break;
case 'INNOVA (G-TYPE)':
$this->vehicle_index[$mfg_id]['INNOVA GAS G'][$model] = $v;
break;
case 'INNOVA (V-TYPE)':
$this->vehicle_index[$mfg_id]['INNOVA GAS V'][$model] = $v;
break;
case 'INNOVA (J-TYPE)':
$this->vehicle_index[$mfg_id]['INNOVA GAS J'][$model] = $v;
break;
case 'RAV 4':
$this->vehicle_index[$mfg_id]['RAV-4'][$model] = $v;
break;
case 'GOLFCART':
$this->vehicle_index[$mfg_id]['GOLF CART'][$model] = $v;
break;
case 'FORESTER 2.5':
$this->vehicle_index[$mfg_id]['FORESTER 2.0 AND 2.5'][$model] = $v;
break;
case 'MU-X 2.5LI 4X2/3.0LI 4X4':
$this->vehicle_index[$mfg_id]['MUX'][$model] = $v;
break;
case 'ADVENTURE GLX':
$this->vehicle_index[$mfg_id]['ADVENTURE GAS'][$model] = $v;
break;
case 'CIVIC 1.8':
$this->vehicle_index[$mfg_id]['NEW CIVIC 1.8 V AT'][$model] = $v;
$this->vehicle_index[$mfg_id]['NEW CIVIC 1.8 V MT'][$model] = $v;
break;
case 'LAND CRUISER / PRADO (GASOLINE)':
$this->vehicle_index[$mfg_id]['PRADO'][$model] = $v;
break;
case 'MAZDA 3 / 2 / 6 ISTOP':
$this->vehicle_index[$mfg_id]['MAZADA 3 / 2 / 6 ISTOP'][$model] = $v;
break;
case 'SORENTO':
$this->vehicle_index[$mfg_id]['SORENTO 7-SEATER AT'][$model] = $v;
break;
case 'CX5':
$this->vehicle_index[$mfg_id]['CX-5'][$model] = $v;
break;
case 'ACCORD 3.5 S - V AT V6':
$this->vehicle_index[$mfg_id]['ACCORD 3.5 S - V AT V6 (BRILLIANT WHITE PEARL)'][$model] = $v;
break;
case 'POLO NOTCH 1.6 MPI AT (GAS)':
$this->vehicle_index[$mfg_id]['POLO HATCH 1.6 MPI AT (GAS)'][$model] = $v;
break;
case 'BB':
$this->vehicle_index[$mfg_id]['TOYOTA BB'][$model] = $v;
break;
case 'BRIO AMAZE':
$this->vehicle_index[$mfg_id]['BRIO-AMAZE'][$model] = $v;
break;
case 'CRV':
$this->vehicle_index[$mfg_id]['CR-V 1.5 I-DTEC'][$model] = $v;
break;
}
// special cases for models
switch ($make)
{
case 'CIVIC':
if ($model == '1991 - 2000')
$this->vehicle_index[$mfg_id][$make]['2000 - down'] = $v;
if ($model == '2001 - 2005')
$this->vehicle_index[$mfg_id][$make]['2002 - 2006'] = $v;
if ($model == '2006 - 2018')
$this->vehicle_index[$mfg_id][$make]['2006*'] = $v;
break;
case 'MONTERO SPORTS':
if ($model == '-')
$this->vehicle_index[$mfg_id][$make]['2010 AND 2014'] = $v;
break;
case 'FOCUS':
if ($model == '2005 - 2013')
$this->vehicle_index[$mfg_id][$make]['2013 - down'] = $v;
if ($model == '2014 - 2018')
$this->vehicle_index[$mfg_id][$make]['2005 - 2018'] = $v;
break;
case 'RANGER':
if ($model == '1999 - 2014')
$this->vehicle_index[$mfg_id][$make]['1999 - 2018'] = $v;
break;
case 'LANCER MX*':
if ($model == '2000 - 2018')
$this->vehicle_index[$mfg_id][$make]['2010'] = $v;
break;
case 'VIOS':
if ($model == '2006')
$this->vehicle_index[$mfg_id][$make]['2006 - down'] = $v;
break;
case 'RAV 4':
if ($model == '2007 - 2018')
$this->vehicle_index[$mfg_id]['RAV-4']['2007'] = $v;
if ($model == '1996 - 2018')
$this->vehicle_index[$mfg_id]['RAV-4']['2002 - 2006'] = $v;
$this->vehicle_index[$mfg_id]['RAV-4']['2001 - down'] = $v;
break;
case 'ACCENT GL 1.5 CRDI MT':
if ($model == '2004 - 2013')
$this->vehicle_index[$mfg_id][$make]['2004 - 2018'] = $v;
if ($model == '2014 - 2018')
$this->vehicle_index[$mfg_id][$make]['2013 to Present'] = $v;
break;
case 'TUCSON CRDI DSL 4X2 AT':
if ($model == '2004 - 2011')
$this->vehicle_index[$mfg_id][$make]['2004 - 2018'] = $v;
break;
case 'FORTUNER (DIESEL)':
if ($model == '2005 - 2016')
$this->vehicle_index[$mfg_id][$make]['2005 - 2018'] = $v;
if ($model == '2016 - 2018')
$this->vehicle_index[$mfg_id][$make]['2016'] = $v;
break;
case 'CAMRY':
if ($model == '2007 - 2018')
$this->vehicle_index[$mfg_id][$make]['2007 - 0n'] = $v;
break;
case 'GRAND VITARA':
if ($model == '2007 - 2018')
$this->vehicle_index[$mfg_id][$make]['2007 - 0n'] = $v;
break;
}
// exceptions and special cases for model
}
}
protected function findVehicle($output, $row)
{
$output->writeln('[0] find vehicle');
// search for manufacturer
$mfg_name = trim($row[self::F_V_BRAND]);
$make = strtoupper(trim($row[self::F_V_MAKE]));
$model = trim($row[self::F_V_MODEL]);
$output->writeln('[5] checking mfg');
if (!isset($this->mfg_index[$mfg_name]))
{
$output->writeln('manufacturer not found: ' . $mfg_name . ' - ' . $make . ' - ' . $model);
return null;
}
$mfg = $this->mfg_index[$mfg_name];
$mfg_id = $mfg->getID();
$output->writeln('[5] checking make');
// check if empty make
if (empty($make))
{
// check if the manufacturer has only one make anyway
if (count($this->vehicle_index[$mfg_id]) == 1)
{
// get first make
$first_make = reset($this->vehicle_index[$mfg_id]);
$first_model = reset($first_make);
if ($first_model == null)
$output->writeln('first_model null');
return $first_model;
}
$output->writeln('no make specified: ' . $mfg_name);
return null;
}
// get year from and to from model
if (empty($model))
$model = 'NONE';
if ($model == 'NONE')
{
$year_from = 0;
$year_to = 0;
$model_index = '-';
}
else
{
$ex_model = explode('-', $model);
$year_from = trim($ex_model[0]);
if (isset($ex_model[1]))
{
$year_to = strtolower(trim($ex_model[1]));
if ($year_to == 'on' || $year_to == 'up')
$year_to = '2018';
$model_index = $year_from . ' - ' . $year_to;
}
else
{
$year_to = 0;
$model_index = $year_from;
}
}
// search for make and model from index
if (!isset($this->vehicle_index[$mfg_id][$make][$model_index]))
{
// check if we match make but not model
if (isset($this->vehicle_index[$mfg_id][$make]))
{
// is there only one entry in the index? that's the one!
if (count($this->vehicle_index[$mfg_id][$make]) == 1)
{
$vehicle = reset($this->vehicle_index[$mfg_id][$make]);
if ($vehicle == null)
$output->writeln('vehicle[1] null');
return $vehicle;
}
// handle blank model year
if ($model_index == '-')
{
$vehicle = reset($this->vehicle_index[$mfg_id][$make]);
if ($vehicle == null)
$output->writeln('vehicle[2] null');
return $vehicle;
}
}
$output->writeln("vehicle make and model not found: $mfg_name - $make ($model_index)");
return null;
}
return $this->vehicle_index[$mfg_id][$make][$model_index];
}
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 = 1;
$save_counter = 0;
$cust_file = fopen('/root/www/ramcar/data/customer_import.csv', 'w');
$cv_file = fopen('/root/www/ramcar/data/cv_import.csv', 'w');
while (($fields = fgetcsv($fh)) !== false)
{
// $output->writeln("Parsing row " . $row_num . "...");
// ignore first row
if ($row_num == 1)
{
$row_num++;
continue;
}
$id = trim($fields[self::F_ID]);
$fname = trim($fields[self::F_FIRST_NAME]);
$lname = trim($fields[self::F_LAST_NAME]);
$title = trim($fields[self::F_TITLE]);
$plate_num = strtoupper(trim($fields[self::F_PLATE_NUMBER]));
$color = trim($fields[self::F_V_COLOR]);
// NOTE: we have to export this to csv then load data infile
// because doctrine is eating up 100% cpu
/*
// customer
$cust = new Customer();
$cust->setTitle($title)
->setFirstName($fname)
->setLastName($lname)
->setCustomerNotes($fields[self::F_NOTES])
->setPhoneMobile($fields[self::F_MOBILE_PHONE])
->setPhoneLandline($fields[self::F_LANDLINE])
->setPhoneOffice($fields[self::F_OFFICE_PHONE])
->setPhoneFax($fields[self::F_FAX])
->setEmail($fields[self::F_EMAIL]);
$this->em->persist($cust);
*/
$cust_fields = [
$id,
$fname,
$lname,
0,
'',
0,
$title,
1,
$fields[self::F_MOBILE_PHONE],
$fields[self::F_LANDLINE],
$fields[self::F_OFFICE_PHONE],
$fields[self::F_FAX],
$fields[self::F_EMAIL],
isset($fields[self::F_NOTES]) ? $fields[self::F_NOTES] : ''
];
$cust_row = str_replace('\\', '\\\\', implode('|', $cust_fields)) . "\n";
fputs($cust_file, $cust_row);
// $output->writeln($id . ' - ' . $fname . ' ' . $lname);
// get vehicle object
$vehicle = $this->findVehicle($output, $fields);
if ($vehicle != null)
{
$output->writeln('[1] vehicle found');
/*
// customer vehicle
$cv = new CustomerVehicle();
$cv->setName('')
->setCustomer($cust)
->setVehicle($vehicle)
->setPlateNumber($plate_num)
->setModelYear(0)
->setColor($color)
->setStatusCondition(VehicleStatusCondition::BRAND_NEW)
->setFuelType(FuelTYpe::GAS)
->setHasMotoliteBattery(false);
$this->em->persist($cv);
*/
$cv_fields = [
$id,
$vehicle->getID(),
'',
$plate_num,
0,
VehicleStatusCondition::BRAND_NEW,
FuelType::GAS,
0,
1,
$color
];
$cv_row = str_replace('\\', '\\\\', implode('|', $cv_fields)) . "\n";
fputs($cv_file, $cv_row);
}
else
{
$output->writeln('[2] vehicle not found');
}
$row_num++;
/*
$save_counter++;
// flush every 100
if ($save_counter >= 100000)
{
$this->em->flush();
$save_counter = 0;
}
*/
}
fclose($cust_file);
fclose($cv_file);
}
}