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