fix: populate destination cost unit from assigned hotel
This commit is contained in:
@@ -0,0 +1,134 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\BusProNet\DataProvider\HotelDataProvider;
|
||||||
|
use App\Repository\DestinationRepository;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
#[AsCommand(
|
||||||
|
name: 'app:destination:update-cost-units',
|
||||||
|
description: 'One-time command to update cost units for destinations from their assigned hotels',
|
||||||
|
)]
|
||||||
|
class UpdateDestinationCostUnitsCommand extends Command
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly DestinationRepository $destinationRepository,
|
||||||
|
private readonly HotelDataProvider $hotelDataProvider,
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this->addOption(
|
||||||
|
'dry-run',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_NONE,
|
||||||
|
'Run without persisting changes to the database'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
$isDryRun = true === $input->getOption('dry-run');
|
||||||
|
|
||||||
|
if ($isDryRun) {
|
||||||
|
$io->note('Running in dry-run mode. No changes will be persisted.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->destinationRepository->createQueryBuilder('d');
|
||||||
|
$destinations = $qb
|
||||||
|
->where($qb->expr()->isNotNull('d.hotelBusProId'))
|
||||||
|
->andWhere($qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('d.costUnit'),
|
||||||
|
$qb->expr()->eq('d.costUnit', ':emptyString')
|
||||||
|
))
|
||||||
|
->andWhere($qb->expr()->isNull('d.deletedAt'))
|
||||||
|
->setParameter('emptyString', '')
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
;
|
||||||
|
|
||||||
|
$totalCount = count($destinations);
|
||||||
|
|
||||||
|
if (0 === $totalCount) {
|
||||||
|
$io->success('No destinations found that need cost unit updates.');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
$io->info(sprintf('Found %d destination(s) with assigned hotels and empty cost units.', $totalCount));
|
||||||
|
|
||||||
|
$updatedCount = 0;
|
||||||
|
$skippedCount = 0;
|
||||||
|
|
||||||
|
foreach ($destinations as $destination) {
|
||||||
|
$hotelBusProId = $destination->getHotelBusProId();
|
||||||
|
$hotel = $this->hotelDataProvider->get($hotelBusProId);
|
||||||
|
|
||||||
|
if (null === $hotel) {
|
||||||
|
$io->warning(sprintf(
|
||||||
|
'Hotel with BusProId %d not found for destination #%d',
|
||||||
|
$hotelBusProId,
|
||||||
|
$destination->getId()
|
||||||
|
));
|
||||||
|
++$skippedCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$costUnit = $hotel->getCostUnit();
|
||||||
|
|
||||||
|
if (null === $costUnit || '' === $costUnit) {
|
||||||
|
$io->warning(sprintf(
|
||||||
|
'Hotel "%s" (BusProId: %d) has no cost unit. Skipping destination #%d',
|
||||||
|
$hotel->getName(),
|
||||||
|
$hotelBusProId,
|
||||||
|
$destination->getId()
|
||||||
|
));
|
||||||
|
++$skippedCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$destination->setCostUnit($costUnit);
|
||||||
|
++$updatedCount;
|
||||||
|
|
||||||
|
$io->writeln(sprintf(
|
||||||
|
'Updated destination #%d (%s) with cost unit "%s" from hotel "%s"',
|
||||||
|
$destination->getId(),
|
||||||
|
$destination->getProduct(),
|
||||||
|
$costUnit,
|
||||||
|
$hotel->getName()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $isDryRun && $updatedCount > 0) {
|
||||||
|
$this->entityManager->flush();
|
||||||
|
$io->success(sprintf(
|
||||||
|
'Successfully updated %d destination(s). Skipped %d destination(s).',
|
||||||
|
$updatedCount,
|
||||||
|
$skippedCount
|
||||||
|
));
|
||||||
|
} elseif ($isDryRun && $updatedCount > 0) {
|
||||||
|
$io->success(sprintf(
|
||||||
|
'Dry-run complete. Would update %d destination(s). Would skip %d destination(s).',
|
||||||
|
$updatedCount,
|
||||||
|
$skippedCount
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
$io->info(sprintf('No destinations updated. Skipped %d destination(s).', $skippedCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ trait DestinationTrait
|
|||||||
->setHotelBusProId($hotel->getBusProId())
|
->setHotelBusProId($hotel->getBusProId())
|
||||||
->setCountry($destinationDto->getCountry())
|
->setCountry($destinationDto->getCountry())
|
||||||
->setPickups($pickups)
|
->setPickups($pickups)
|
||||||
->setCostUnit($destinationDto->getCostUnit())
|
->setCostUnit($hotel->getCostUnit())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ class DestinationType extends AbstractType
|
|||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
'allow_delete' => true,
|
'allow_delete' => true,
|
||||||
])
|
])
|
||||||
->add('costUnit', TextType::class, [
|
|
||||||
'label' => 'Kostenstelle',
|
|
||||||
])
|
|
||||||
->add('country', ChoiceType::class, [
|
->add('country', ChoiceType::class, [
|
||||||
'label' => 'Land',
|
'label' => 'Land',
|
||||||
'choices' => [
|
'choices' => [
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ class DestinationDto
|
|||||||
|
|
||||||
private array $pickups = [];
|
private array $pickups = [];
|
||||||
|
|
||||||
private ?string $costUnit = null;
|
|
||||||
|
|
||||||
public static function fromEntity(Destination $destination): static
|
public static function fromEntity(Destination $destination): static
|
||||||
{
|
{
|
||||||
$instance = new static();
|
$instance = new static();
|
||||||
@@ -41,7 +39,6 @@ class DestinationDto
|
|||||||
->setHotelBusProId($destination->getHotelBusProId())
|
->setHotelBusProId($destination->getHotelBusProId())
|
||||||
->setCountry($destination->getCountry())
|
->setCountry($destination->getCountry())
|
||||||
->setPickups($pickupIds)
|
->setPickups($pickupIds)
|
||||||
->setCostUnit($destination->getCostUnit())
|
|
||||||
;
|
;
|
||||||
|
|
||||||
return $instance;
|
return $instance;
|
||||||
@@ -118,16 +115,4 @@ class DestinationDto
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCostUnit(): ?string
|
|
||||||
{
|
|
||||||
return $this->costUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCostUnit(?string $costUnit): static
|
|
||||||
{
|
|
||||||
$this->costUnit = $costUnit;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
<div class="grid lg:grid-cols-3 gap-x-8 gap-y-4">
|
<div class="grid lg:grid-cols-3 gap-x-8 gap-y-4">
|
||||||
{{ form_row(form.dateFrom) }}
|
{{ form_row(form.dateFrom) }}
|
||||||
{{ form_row(form.dateTo) }}
|
{{ form_row(form.dateTo) }}
|
||||||
{{ form_row(form.costUnit) }}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
|
<div class="grid lg:grid-cols-2 gap-x-8 gap-y-4">
|
||||||
{{ form_row(form.country) }}
|
{{ form_row(form.country) }}
|
||||||
|
|||||||
Reference in New Issue
Block a user