Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
86 / 86
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
SendMonthlyPreviewCommand
100.00% covered (success)
100.00%
86 / 86
100.00% covered (success)
100.00%
5 / 5
16
100.00% covered (success)
100.00%
1 / 1
 getNotificationSubscriptionType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 autogenerateSubscriptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNotifications
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
7
 getTermineText
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
4
 getDeadlinesText
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Olz\Command\Notifications;
4
5use Doctrine\Common\Collections\Criteria;
6use Doctrine\Common\Collections\Order;
7use Olz\Command\Notifications\Common\BaseSendNotificationsCommand;
8use Olz\Command\Notifications\Common\Notification;
9use Olz\Constants\NotificationType;
10use Olz\Entity\Termine\Termin;
11use Olz\Utils\WithUtilsTrait;
12use Symfony\Component\Console\Attribute\AsCommand;
13
14#[AsCommand(name: 'olz:send-monthly-preview')]
15class SendMonthlyPreviewCommand extends BaseSendNotificationsCommand {
16    use WithUtilsTrait;
17
18    public function getNotificationSubscriptionType(): NotificationType {
19        return NotificationType::MONTHLY_PREVIEW;
20    }
21
22    public function autogenerateSubscriptions(): void {
23        // Must be generated by user.
24    }
25
26    public function getNotifications(array $args): array {
27        $current_weekday = intval($this->dateUtils()->getCurrentDateInFormat('N'));
28        $saturday = 6;
29        if ($current_weekday != $saturday) {
30            return [];
31        }
32        $day_of_month = intval($this->dateUtils()->getCurrentDateInFormat('j'));
33        $total_days_of_month = intval($this->dateUtils()->getCurrentDateInFormat('t'));
34        if ($day_of_month <= $total_days_of_month - 14) {
35            return []; // not yet this month
36        }
37        if ($day_of_month > $total_days_of_month - 7) {
38            return []; // not anymore this month
39        }
40
41        $one_month = \DateInterval::createFromDateString('+1 months');
42        $two_months = \DateInterval::createFromDateString('+2 months');
43        $today = new \DateTime($this->dateUtils()->getIsoToday());
44        $next_month = (new \DateTime($this->dateUtils()->getIsoToday()))->add($one_month);
45        $in_two_months = (new \DateTime($this->dateUtils()->getIsoToday()))->add($two_months);
46        $end_of_timespan = new \DateTime($in_two_months->format('Y-m-01'));
47
48        $notification_text = '';
49        $termine_text = $this->getTermineText($today, $end_of_timespan);
50        if (strlen($termine_text) > 0) {
51            $notification_text .= "\n**Termine**\n\n{$termine_text}\n";
52        }
53        $deadlines_text = $this->getDeadlinesText($today, $end_of_timespan);
54        if (strlen($deadlines_text) > 0) {
55            $notification_text .= "\n**Meldeschlüsse**\n\n{$deadlines_text}\n";
56        }
57
58        if (strlen($notification_text) == 0) {
59            return [];
60        }
61
62        $month_name = $this->dateUtils()->olzDate('MM', $next_month);
63        $title = "Monatsvorschau {$month_name}";
64        $text = "Hallo %%userFirstName%%,\n\nIm {$month_name} haben wir Folgendes auf dem Programm:\n\n{$notification_text}";
65
66        return [
67            new Notification($title, $text, [
68                'notification_type' => NotificationType::MONTHLY_PREVIEW,
69            ]),
70        ];
71    }
72
73    public function getTermineText(\DateTime $today, \DateTime $end_of_timespan): string {
74        $termin_repo = $this->entityManager()->getRepository(Termin::class);
75        $criteria = Criteria::create()
76            ->where(Criteria::expr()->andX(
77                Criteria::expr()->gt('start_date', $today),
78                Criteria::expr()->lt('start_date', $end_of_timespan),
79                Criteria::expr()->eq('on_off', 1),
80            ))
81            ->orderBy(['start_date' => Order::Ascending])
82            ->setFirstResult(0)
83            ->setMaxResults(1000)
84        ;
85        $termine = $termin_repo->matching($criteria);
86
87        $base_href = $this->envUtils()->getBaseHref();
88        $code_href = $this->envUtils()->getCodeHref();
89
90        $termine_url = "{$base_href}{$code_href}termine";
91        $termine_text = "";
92        foreach ($termine as $termin) {
93            $id = $termin->getId();
94            $starts_on = $termin->getStartDate();
95            $ends_on = $termin->getEndDate();
96            $date = ($ends_on && $ends_on > $starts_on)
97                ? $this->dateUtils()->compactDate($starts_on).' - '.$this->dateUtils()->compactDate($ends_on)
98                : $this->dateUtils()->compactDate($starts_on);
99            $title = $this->htmlUtils()->escapeMarkdown($termin->getTitle() ?? '');
100            $termine_text .= "- {$date}: [{$title}]({$termine_url}/{$id})\n";
101        }
102        return $termine_text;
103    }
104
105    public function getDeadlinesText(\DateTime $today, \DateTime $end_of_timespan): string {
106        $termin_repo = $this->entityManager()->getRepository(Termin::class);
107
108        $base_href = $this->envUtils()->getBaseHref();
109        $code_href = $this->envUtils()->getCodeHref();
110        $termine_url = "{$base_href}{$code_href}termine";
111
112        $deadlines_text = '';
113
114        $criteria = Criteria::create()
115            ->where(
116                Criteria::expr()->andX(
117                    Criteria::expr()->gt('deadline', $today),
118                    Criteria::expr()->lt('deadline', $end_of_timespan),
119                    Criteria::expr()->eq('on_off', 1),
120                )
121            )
122            ->orderBy(['start_date' => Order::Ascending])
123            ->setFirstResult(0)
124            ->setMaxResults(1000)
125        ;
126        $deadlines = $termin_repo->matching($criteria);
127        foreach ($deadlines as $termin) {
128            $deadline_date = $termin->getDeadline();
129            $date = $deadline_date ? $this->dateUtils()->compactDate($deadline_date) : '';
130            $id = $termin->getId();
131            $title = $this->htmlUtils()->escapeMarkdown($termin->getTitle() ?? '');
132            $deadlines_text .= "- {$date}: Meldeschluss für '[{$title}]({$termine_url}/{$id})'\n";
133        }
134
135        return $deadlines_text;
136    }
137}