Merge branch '52-migrate-contact-and-job-order-scripts' into 'master'
Resolve "Migrate contact and job order scripts" Closes #52 See merge request jankstudio/resq!50
This commit is contained in:
commit
f6145d45f1
13 changed files with 1034418 additions and 11 deletions
|
|
@ -11,5 +11,5 @@ return [
|
||||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||||
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
||||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||||
DataDog\AuditBundle\DataDogAuditBundle::class => ['all' => true],
|
// DataDog\AuditBundle\DataDogAuditBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
323910
data/Contacts.csv
Normal file
323910
data/Contacts.csv
Normal file
File diff suppressed because it is too large
Load diff
375903
data/JO 2016.csv
Normal file
375903
data/JO 2016.csv
Normal file
File diff suppressed because one or more lines are too long
256689
data/JO 2017.csv
Normal file
256689
data/JO 2017.csv
Normal file
File diff suppressed because one or more lines are too long
76622
data/JO 2018.csv
Normal file
76622
data/JO 2018.csv
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -5,6 +5,9 @@ delete from ticket;
|
||||||
delete from audit_logs;
|
delete from audit_logs;
|
||||||
delete from audit_associations;
|
delete from audit_associations;
|
||||||
delete from customer_vehicle;
|
delete from customer_vehicle;
|
||||||
|
delete from mobile_number;
|
||||||
|
delete from mobile_session;
|
||||||
|
delete from customer;
|
||||||
delete from vehicle;
|
delete from vehicle;
|
||||||
delete from vehicle_manufacturer;
|
delete from vehicle_manufacturer;
|
||||||
delete from battery;
|
delete from battery;
|
||||||
|
|
|
||||||
3
sql/load_customer_data.sql
Normal file
3
sql/load_customer_data.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
load data local infile '/root/www/ramcar/data/customer_import.csv' into table customer fields terminated by '|' lines terminated by '\n';
|
||||||
|
load data local infile '/root/www/ramcar/data/cv_import.csv' into table customer_vehicle fields terminated by '|' lines terminated by '\n' (customer_id, vehicle_id, name, plate_number, model_year, status_condition, fuel_type, flag_motolite_battery, flag_active, color);
|
||||||
|
|
||||||
957
sql/resq.customer_import_20180322.sql
Normal file
957
sql/resq.customer_import_20180322.sql
Normal file
File diff suppressed because one or more lines are too long
315
src/Command/ImportCustomerCommand.php
Normal file
315
src/Command/ImportCustomerCommand.php
Normal file
|
|
@ -0,0 +1,315 @@
|
||||||
|
<?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)
|
||||||
|
{
|
||||||
|
$this->mfg_index[$mfg->getName()] = $mfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function populateVehicleIndex()
|
||||||
|
{
|
||||||
|
$vs = $this->em->getRepository(Vehicle::class)->findAll();
|
||||||
|
|
||||||
|
$this->vehicle_index = [];
|
||||||
|
foreach ($vs as $v)
|
||||||
|
{
|
||||||
|
$this->vehicle_index[strtoupper($v->getMake())][$v->getModelYearFormatted()] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function findVehicle($output, $row)
|
||||||
|
{
|
||||||
|
// search for manufacturer
|
||||||
|
$mfg_name = trim($row[self::F_V_BRAND]);
|
||||||
|
if (!isset($this->mfg_index[$mfg_name]))
|
||||||
|
{
|
||||||
|
$output->writeln('manufacturer not found: ' . $mfg_name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$mfg = $this->mfg_index[$mfg_name];
|
||||||
|
|
||||||
|
// check if empty make
|
||||||
|
$make = strtoupper(trim($row[self::F_V_MAKE]));
|
||||||
|
if (empty($make))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// get year from and to from model
|
||||||
|
$model = trim($row[self::F_V_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[$make][$model_index]))
|
||||||
|
{
|
||||||
|
// check if we match make but not model
|
||||||
|
if (isset($this->vehicle_index[$make]))
|
||||||
|
{
|
||||||
|
// is there only one entry in the index? that's the one!
|
||||||
|
if (count($this->vehicle_index[$make]) == 1)
|
||||||
|
{
|
||||||
|
$vehicle = reset($this->vehicle_index[$make]);
|
||||||
|
return $vehicle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$output->writeln("vehicle make and model not found: $mfg_name - $make ($model_index)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$csv_file = $input->getArgument('file');
|
||||||
|
|
||||||
|
/*
|
||||||
|
old CSV column order:
|
||||||
|
** NO LONGER APPLIES
|
||||||
|
0 - internal id
|
||||||
|
1 - name
|
||||||
|
2 - duplicate (yes or blank)
|
||||||
|
3 - date created
|
||||||
|
4 - date last modified
|
||||||
|
5 - phone
|
||||||
|
6 - company (plate number)
|
||||||
|
7 - email
|
||||||
|
8 - login access
|
||||||
|
9 - fax
|
||||||
|
10 - billing address 1 (blank)
|
||||||
|
11 - billing address 2 (blank)
|
||||||
|
12 - billing city (blank)
|
||||||
|
13 - billing state / province (blank)
|
||||||
|
14 - billing zip (blank)
|
||||||
|
15 - billing country (blank)
|
||||||
|
16 - job title (blank)
|
||||||
|
17 - category (blank)
|
||||||
|
18 - office phone
|
||||||
|
19 - mobile phone
|
||||||
|
20 - home phone
|
||||||
|
21 - date created
|
||||||
|
22 - date last modified
|
||||||
|
23 - first name
|
||||||
|
24 - last name
|
||||||
|
25 - login access
|
||||||
|
26 - role
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 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],
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
$row_num++;
|
||||||
|
/*
|
||||||
|
$save_counter++;
|
||||||
|
|
||||||
|
// flush every 100
|
||||||
|
if ($save_counter >= 100000)
|
||||||
|
{
|
||||||
|
$this->em->flush();
|
||||||
|
$save_counter = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
fclose($cust_file);
|
||||||
|
fclose($cv_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ class JobOrderController extends BaseController
|
||||||
|
|
||||||
// db loaded
|
// db loaded
|
||||||
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
|
$params['bmfgs'] = $em->getRepository(BatteryManufacturer::class)->findAll();
|
||||||
$params['customers'] = $em->getRepository(Customer::class)->findAll();
|
// $params['customers'] = $em->getRepository(Customer::class)->findAll();
|
||||||
$params['promos'] = $em->getRepository(Promo::class)->findAll();
|
$params['promos'] = $em->getRepository(Promo::class)->findAll();
|
||||||
|
|
||||||
// name values
|
// name values
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class Battery
|
||||||
|
|
||||||
// product code
|
// product code
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="string", length=80, unique=true)
|
* @ORM\Column(type="string", length=80)
|
||||||
* @Assert\NotBlank()
|
* @Assert\NotBlank()
|
||||||
*/
|
*/
|
||||||
protected $prod_code;
|
protected $prod_code;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class Customer
|
||||||
|
|
||||||
// title
|
// title
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="string", length=10)
|
* @ORM\Column(type="string", length=80)
|
||||||
* @Assert\NotBlank()
|
* @Assert\NotBlank()
|
||||||
*/
|
*/
|
||||||
protected $title;
|
protected $title;
|
||||||
|
|
@ -51,7 +51,7 @@ class Customer
|
||||||
protected $customer_classification;
|
protected $customer_classification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=80)
|
* @ORM\Column(type="text", length=65535)
|
||||||
*/
|
*/
|
||||||
protected $customer_notes;
|
protected $customer_notes;
|
||||||
|
|
||||||
|
|
@ -63,25 +63,25 @@ class Customer
|
||||||
|
|
||||||
// mobile phone
|
// mobile phone
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=12)
|
* @ORM\Column(type="string", length=30)
|
||||||
*/
|
*/
|
||||||
protected $phone_mobile;
|
protected $phone_mobile;
|
||||||
|
|
||||||
// landline
|
// landline
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=12)
|
* @ORM\Column(type="string", length=30)
|
||||||
*/
|
*/
|
||||||
protected $phone_landline;
|
protected $phone_landline;
|
||||||
|
|
||||||
// office phone
|
// office phone
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=12)
|
* @ORM\Column(type="string", length=30)
|
||||||
*/
|
*/
|
||||||
protected $phone_office;
|
protected $phone_office;
|
||||||
|
|
||||||
// fax
|
// fax
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text", length=12)
|
* @ORM\Column(type="string", length=30)
|
||||||
*/
|
*/
|
||||||
protected $phone_fax;
|
protected $phone_fax;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ class CustomerVehicle
|
||||||
|
|
||||||
// plate number
|
// plate number
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="string", length=10)
|
* @ORM\Column(type="string", length=100)
|
||||||
* @Assert\NotBlank()
|
* @Assert\NotBlank()
|
||||||
*/
|
*/
|
||||||
protected $plate_number;
|
protected $plate_number;
|
||||||
|
|
@ -59,7 +59,7 @@ class CustomerVehicle
|
||||||
|
|
||||||
// color of customer's vehicle
|
// color of customer's vehicle
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="string", length=25)
|
* @ORM\Column(type="string", length=80)
|
||||||
* @Assert\NotBlank()
|
* @Assert\NotBlank()
|
||||||
*/
|
*/
|
||||||
protected $color;
|
protected $color;
|
||||||
|
|
@ -116,6 +116,11 @@ class CustomerVehicle
|
||||||
*/
|
*/
|
||||||
protected $flag_active;
|
protected $flag_active;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->flag_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getID()
|
public function getID()
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue