76 lines
2.4 KiB
PHP
76 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Email\Mailer;
|
|
use App\Entity\Booking;
|
|
use App\Enum\ResourceType;
|
|
use App\Model\SeriesResult;
|
|
use App\Repository\ResourceTypeSettingsRepository;
|
|
|
|
/**
|
|
* Tells whoever an administrator named that something was booked.
|
|
*
|
|
* Recipients are configured per ResourceType rather than per resource or per group, because that
|
|
* is the level the admin screen groups by and the only one every resource is guaranteed to have:
|
|
* a resource's group is optional, and a kind that is not split into groups -- rooms, cars --
|
|
* would otherwise never notify anybody.
|
|
*
|
|
* **Nothing here may break a booking.** It runs after the transaction has committed, so a
|
|
* failure cannot roll anything back -- and Mailer never throws, so the person who booked is not
|
|
* shown an error about somebody else's mail server.
|
|
*/
|
|
final readonly class BookingNotifier
|
|
{
|
|
public function __construct(
|
|
private Mailer $mailer,
|
|
private ResourceTypeSettingsRepository $settings,
|
|
) {
|
|
}
|
|
|
|
public function bookingCreated(Booking $booking): void
|
|
{
|
|
$resource = $booking->getResource();
|
|
|
|
$this->send(
|
|
$resource->getType(),
|
|
\sprintf('Neue Buchung: %s am %s', $resource->getLabel(), $booking->getDate()->format('d.m.Y')),
|
|
'email/booking_created',
|
|
['booking' => $booking],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* One mail for a whole series, not one per occurrence.
|
|
*
|
|
* A year of weekly bookings is the same act and would otherwise arrive as fifty-two mails in
|
|
* one second -- the same reason AuditLogger records a series once rather than per day.
|
|
*/
|
|
public function seriesCreated(SeriesResult $result): void
|
|
{
|
|
if ($result->isCompletelyBlocked()) {
|
|
return;
|
|
}
|
|
|
|
$series = $result->series;
|
|
$resource = $series->getResource();
|
|
|
|
$this->send(
|
|
$resource->getType(),
|
|
\sprintf('Neue Serienbuchung: %s ab %s', $resource->getLabel(), $series->getStartDate()->format('d.m.Y')),
|
|
'email/series_created',
|
|
['result' => $result, 'series' => $series],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $context
|
|
*/
|
|
private function send(ResourceType $type, string $subject, string $template, array $context): void
|
|
{
|
|
$this->mailer->send($this->settings->recipientsFor($type), $subject, $template, $context);
|
|
}
|
|
}
|