Merge branch '144-command-to-merge-duplicate-vehicles' into 'master'

Resolve "Command to merge duplicate vehicles"

Closes #144

See merge request jankstudio/resq!141
This commit is contained in:
Kendrick Chan 2018-06-16 03:52:22 +00:00
commit c7ebd61305
4 changed files with 188 additions and 6 deletions

View file

@ -0,0 +1,168 @@
<?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 App\Entity\Vehicle;
class MergeDuplicateVehiclesCommand extends Command
{
protected $em;
public function __construct(ObjectManager $om)
{
$this->em = $om;
parent::__construct();
}
protected function configure()
{
$this->setName('vehicle:merge')
->setDescription('Merge duplicate vehicle makes.')
->setHelp('Finds duplicate vehicle makes and merges them into one record. Deletes the duplicate record afterwards.');
}
protected function buildVehicleIndex()
{
$vindex = [];
$vehicles = $this->em->getRepository(Vehicle::class)->findAll();
foreach ($vehicles as $v)
{
$mfg_id = $v->getManufacturer()->getID();
$clean_make = strtolower(trim($v->getMake()));
if (!isset($vindex[$mfg_id][$clean_make]))
$vindex[$mfg_id][$clean_make] = [];
$vindex[$mfg_id][$clean_make][] = $v;
}
return $vindex;
}
protected function getDupeModels($source, $vlist, &$found_dupes)
{
$vfrom = $source->getModelYearFrom();
$vto = $source->getModelYearTo();
$id = $source->getID();
$dupes = [];
foreach ($vlist as $v)
{
// skip ourselves
if ($id == $v->getID())
continue;
// same model years
if ($vfrom == $v->getModelYearFrom() && $vto == $v->getModelYearTo())
{
// mark as duplicate
$found_dupes[$v->getID()] = true;
$dupes[$v->getID()] = $v;
/*
$dupes[$v->getID()] = [
'id' => $v->getID(),
'make' => $v->getMake(),
'y_from' => $v->getModelYearFrom(),
'y_to' => $v->getModelYearTo(),
'y_formatted' => $v->getModelYearFormatted(),
];
*/
}
}
return $dupes;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// get entity manager
$em = $this->em;
// get all vehicle makes
$vindex = $this->buildVehicleIndex();
// collect all dupes
$dupes = [];
$found_dupes = [];
$source_index = [];
// manufacturers
foreach ($vindex as $mfg_id => $vmfgs)
{
// makes
foreach ($vmfgs as $make => $data)
{
if (count($data) > 1)
{
// check if they have the same model years
foreach ($data as $v)
{
// if we already found a dupe with him, skip
if (isset($found_dupes[$v->getID()]))
continue;
// get dupes
$v_dupes = $this->getDupeModels($v, $data, $found_dupes);
if (count($v_dupes) > 0)
{
$source_index[$v->getID()] = $v;
$dupes[$v->getID()] = $v_dupes;
}
}
}
}
}
// process the duplicates
foreach ($dupes as $source_id => $sub_dupes)
{
$source = $source_index[$source_id];
$output->writeln('processing - ' . $source_id);
$output->writeln('removing duplicates for ' . $source->getManufacturer()->getName() . ' ' . $source->getMake() . ' ' . $source->getModelYearFormatted());
foreach ($sub_dupes as $dupe)
{
// move customer vehicles
$cvs = $dupe->getCustomerVehicles();
foreach ($cvs as $cv)
{
$cv->setVehicle($source);
$output->writeln('adjusting customer vehicle ' . $cv->getPlateNumber());
}
// move battery compatibility
$batts = $dupe->getBatteries();
foreach ($batts as $batt)
{
// $source->addBattery($batt);
$batt->addVehicle($source);
$batt->removeVehicle($dupe);
$output->writeln('adding battery ' . $batt->getModel()->getName() . ' ' . $batt->getSize()->getName());
}
// flush
$em->flush();
// remove dupes
$output->writeln('removing duplicate - ' . $dupe->getID());
$em->remove($dupe);
$em->flush();
}
}
// print_r($dupes);
}
}

View file

@ -181,7 +181,15 @@ class Battery
public function addVehicle(Vehicle $vehicle)
{
$this->vehicles[$vehicle->getID()] = $vehicle;
if (!isset($this->vehicles[$vehicle->getID()]))
$this->vehicles[$vehicle->getID()] = $vehicle;
return $this;
}
public function removeVehicle(Vehicle $vehicle)
{
if (isset($this->vehicles[$vehicle->getID()]))
unset($this->vehicles[$vehicle->getID()]);
return $this;
}

View file

@ -37,7 +37,7 @@ class CustomerVehicle
// vehicle
/**
* @ORM\ManyToOne(targetEntity="Vehicle", inversedBy="customers")
* @ORM\ManyToOne(targetEntity="Vehicle", inversedBy="cust_vehicles")
* @ORM\JoinColumn(name="vehicle_id", referencedColumnName="id")
* @Assert\NotBlank()
*/

View file

@ -24,7 +24,7 @@ class Vehicle
/**
* @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="vehicle")
*/
protected $customers;
protected $cust_vehicles;
// manufacturer
/**
@ -55,7 +55,7 @@ class Vehicle
// link to batteries compatible with this vehicle
/**
* @ORM\ManyToMany(targetEntity="Battery", mappedBy="vehicles", fetch="EXTRA_LAZY")
* @ORM\ManyToMany(targetEntity="Battery", mappedBy="vehicles", indexBy="id", fetch="EXTRA_LAZY")
*/
protected $batteries;
@ -68,7 +68,7 @@ class Vehicle
public function __construct()
{
$this->customers = new ArrayCollection();
$this->cust_vehicles = new ArrayCollection();
$this->batteries = new ArrayCollection();
$this->flag_mobile = true;
}
@ -145,7 +145,8 @@ class Vehicle
public function addBattery(Battery $battery)
{
$this->batteries->add($battery);
$this->batteries[$battery->getID()] = $battery;
return $this;
}
@ -170,4 +171,9 @@ class Vehicle
{
return $this->flag_mobile;
}
public function getCustomerVehicles()
{
return $this->cust_vehicles;
}
}