feat: cli command to backfill travel dates on draft records, single use

This commit is contained in:
Björn Fromme
2026-03-16 12:02:27 +01:00
parent 1fa17a7df7
commit 9c9db05b86
2 changed files with 125 additions and 0 deletions
@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
namespace App\Command;
use App\BusProNet\Model\Booking;
use App\Repository\BookingEditDraftRepository;
use App\Service\BookingEditDataLoaderService;
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:draft:backfill-travel-date',
description: 'Backfill travel dates for existing drafts from API',
)]
class DraftBackfillTravelDateCommand extends Command
{
public function __construct(
private readonly BookingEditDraftRepository $draftRepository,
private readonly BookingEditDataLoaderService $dataLoader,
private readonly EntityManagerInterface $entityManager,
) {
parent::__construct();
}
protected function configure(): void
{
$this
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Show what would be updated without actually updating');
}
/**
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$dryRun = $input->getOption('dry-run');
$drafts = $this->draftRepository->findAll();
if (0 === \count($drafts)) {
$io->success('No drafts found.');
return Command::SUCCESS;
}
$io->title(sprintf('Processing %d draft(s)', \count($drafts)));
$updated = 0;
$failed = 0;
$skipped = 0;
foreach ($drafts as $draft) {
$bookingId = $draft->getBookingId();
$user = $draft->getUser();
$bookingData = $this->dataLoader->fetchBookingData($bookingId, $user);
if (!$bookingData instanceof Booking) {
$io->warning(sprintf('Could not fetch booking %d for user %s', $bookingId, $user->getEmail()));
++$failed;
continue;
}
$travelDate = $bookingData->travel->dateFrom ?? null;
if (null === $travelDate) {
$io->warning(sprintf('No travel date found for booking %d', $bookingId));
++$skipped;
continue;
}
if ($dryRun) {
$io->text(sprintf(
'[DRY RUN] Would set travel date %s for draft %d (booking %d)',
$travelDate->format('Y-m-d'),
$draft->getId(),
$bookingId
));
} else {
$draft->setTravelDate($travelDate);
}
++$updated;
}
if (false === $dryRun) {
$this->entityManager->flush();
}
$io->newLine();
$io->table(
['Status', 'Count'],
[
['Updated', $updated],
['Failed (API error)', $failed],
['Skipped (no date)', $skipped],
]
);
if ($dryRun) {
$io->note('Dry run - no changes were made.');
} else {
$io->success(sprintf('Updated %d draft(s).', $updated));
}
return Command::SUCCESS;
}
}
+7
View File
@@ -67,6 +67,13 @@ class BookingEditDraft
return $this->travelDate; return $this->travelDate;
} }
public function setTravelDate(\DateTimeImmutable $travelDate): static
{
$this->travelDate = $travelDate;
return $this;
}
public function getFormData(): array public function getFormData(): array
{ {
return $this->formData; return $this->formData;