resq/src/Command/MergeDuplicateVehiclesCommand.php

167 lines
4.9 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\ORM\EntityManagerInterface;
use App\Entity\Vehicle;
class MergeDuplicateVehiclesCommand extends Command
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
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);
return 0;
}
}