diff --git a/src/Command/MergeDuplicateVehiclesCommand.php b/src/Command/MergeDuplicateVehiclesCommand.php new file mode 100644 index 00000000..a0b729cd --- /dev/null +++ b/src/Command/MergeDuplicateVehiclesCommand.php @@ -0,0 +1,168 @@ +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); + } +} diff --git a/src/Entity/Battery.php b/src/Entity/Battery.php index 4ace13cf..ed0c99ec 100644 --- a/src/Entity/Battery.php +++ b/src/Entity/Battery.php @@ -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; } diff --git a/src/Entity/CustomerVehicle.php b/src/Entity/CustomerVehicle.php index 01aff142..3af617ef 100644 --- a/src/Entity/CustomerVehicle.php +++ b/src/Entity/CustomerVehicle.php @@ -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() */ diff --git a/src/Entity/Vehicle.php b/src/Entity/Vehicle.php index e7a9a22a..99ec7779 100644 --- a/src/Entity/Vehicle.php +++ b/src/Entity/Vehicle.php @@ -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; + } }