draftRepository->findStuck(self::MIN_AGE_DAYS, self::LIMIT); return new DashboardWidget( 'Festhängende Buchungsänderungen', array_map(fn (BookingEditDraft $draft): DashboardWidgetEntry => new DashboardWidgetEntry( $this->label($draft), $this->urlGenerator->generate('app_admin_bookingeditdraft_show', ['id' => $draft->getId()]), 'edit', ), $drafts), 'Keine festhängenden Buchungsänderungen.', $this->urlGenerator->generate('app_admin_bookingeditdraft'), 'Alle Buchungsentwürfe', ); } /** * Names the booking, how long it has been stuck, and when the customer last tried. * * The gap between the two is what distinguishes an abandoned edit from somebody still trying * every few days and getting nowhere. */ private function label(BookingEditDraft $draft): string { $days = $draft->getCreatedAt()->diff(new \DateTimeImmutable())->days ?? 0; return sprintf( 'Vorgang %s (%s) — seit %d Tagen, zuletzt %s', $draft->getBookingNumber() ?? $draft->getBookingId(), (string) $draft->getUser()->getEmail(), $days, $draft->getUpdatedAt()->format('d.m.Y'), ); } }