From 2d2951ecdca42fac87b9e1b37cc1a33495c97f6d Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Mon, 11 Nov 2024 16:33:54 +0000
Subject: [PATCH] fixed problems regarding moving single dates and displaying
 the amount of repetitions, fixes #4724

Closes #4724

Merge request studip/studip!3617
---
 app/controllers/calendar/date.php    |  2 +-
 lib/models/calendar/CalendarDate.php | 30 ++++++++++++++++++----------
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/app/controllers/calendar/date.php b/app/controllers/calendar/date.php
index 7eea76653ab..c812cb1ae82 100644
--- a/app/controllers/calendar/date.php
+++ b/app/controllers/calendar/date.php
@@ -655,7 +655,7 @@ class Calendar_DateController extends AuthenticatedController
             throw new InvalidArgumentException();
         }
 
-        if ($this->date->repetition_type) {
+        if ($this->date->repetition_type !== 'SINGLE') {
             PageLayout::setTitle(_('Verschieben eines Termins aus einer Terminserie'));
             //Show the dialog to decide what shall be done with the repetition.
             if (Request::submitted('move')) {
diff --git a/lib/models/calendar/CalendarDate.php b/lib/models/calendar/CalendarDate.php
index fcdd65cef1c..1d49ff52245 100644
--- a/lib/models/calendar/CalendarDate.php
+++ b/lib/models/calendar/CalendarDate.php
@@ -477,9 +477,10 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                 if ($this->interval == '1') {
                     //Each day
                     if ($this->number_of_dates > 1) {
+                        $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                         $repetition_string = sprintf(
                             _('Täglich (%u Termine)'),
-                            $this->number_of_dates
+                            $this->number_of_dates - $number_of_exceptions
                         );
                     } elseif ($this->repetition_end < CalendarDate::NEVER_ENDING) {
                         $repetition_string = sprintf(
@@ -492,10 +493,11 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                 } else {
                     //Every %u day
                     if ($this->number_of_dates > 1) {
+                        $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                         $repetition_string = sprintf(
                             _('Jeden %1$u. Tag (%2$u Termine)'),
                             $this->interval,
-                            $this->number_of_dates
+                            $this->number_of_dates - $number_of_exceptions
                         );
                     } elseif ($this->repetition_end < self::NEVER_ENDING) {
                         $repetition_string = sprintf(
@@ -535,10 +537,11 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
             if ($this->interval == '1') {
                 //Each week
                 if ($this->number_of_dates > 1) {
+                    $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                     $repetition_string = sprintf(
                         ngettext('Einmal am folgenden %s', 'Jeden %1$s (%2$u Termine)', $this->number_of_dates - 1),
                         $weekday_string,
-                        $this->number_of_dates
+                        $this->number_of_dates - $number_of_exceptions
                     );
                 } elseif ($this->repetition_end < self::NEVER_ENDING) {
                     $repetition_string = sprintf(
@@ -555,11 +558,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
             } else {
                 //Every %u week
                 if ($this->number_of_dates > 1) {
+                    $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                     $repetition_string = sprintf(
                         _('Jeden %1$u. %2$s (%3$u Termine)'),
                         $this->interval,
                         $weekday_string,
-                        $this->number_of_dates
+                        $this->number_of_dates - $number_of_exceptions
                     );
                 } elseif ($this->repetition_end < self::NEVER_ENDING) {
                     $repetition_string = sprintf(
@@ -637,11 +641,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                     //in a specific month.
                     if ($this->offset < 0) {
                         if ($this->number_of_dates > 1) {
+                            $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                             $repetition_string = sprintf(
                                 _('Jedes Jahr im %1$s am letzten %2$s (%3$u Termine)'),
                                 getMonthName($this->month, false),
                                 getWeekday($this->days, false),
-                                $this->number_of_dates
+                                $this->number_of_dates - $number_of_exceptions
                             );
                         } elseif ($this->repetition_end < self::NEVER_ENDING) {
                             $repetition_string = sprintf(
@@ -659,12 +664,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                         }
                     } else {
                         if ($this->number_of_dates > 1) {
+                            $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                             $repetition_string = sprintf(
                                 _('Jedes Jahr im %1$s am %2$u. %3$s (%4$u Termine'),
                                 getMonthName($this->month, false),
                                 $this->offset,
                                 getWeekday($this->days, false),
-                                $this->number_of_dates
+                                $this->number_of_dates - $number_of_exceptions
                             );
                         } elseif ($this->repetition_end < self::NEVER_ENDING) {
                             $repetition_string = sprintf(
@@ -686,11 +692,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                 } else {
                     //Repetition on one specific day of month.
                     if ($this->number_of_dates > 1) {
+                        $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                         $repetition_string = sprintf(
                             _('Jedes Jahr am %1$u. %2$s (%3$u Termine)'),
                             $this->offset,
                             getMonthName($this->month, false),
-                            $this->number_of_dates
+                            $this->number_of_dates - $number_of_exceptions
                         );
                     } elseif ($this->repetition_end < self::NEVER_ENDING) {
                         $repetition_string = sprintf(
@@ -714,12 +721,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                     //in a specific month.
                     if ($this->offset < 0) {
                         if ($this->number_of_dates > 1) {
+                            $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                             $repetition_string = sprintf(
                                 _('Jedes %1$u. Jahr im %2$s am letzten %3$s (%4$u Termine)'),
                                 $this->interval,
                                 getMonthName($this->month, false),
                                 getWeekday($this->days, false),
-                                $this->number_of_dates
+                                $this->number_of_dates - $number_of_exceptions
                             );
                         } elseif ($this->repetition_end < self::NEVER_ENDING) {
                             $repetition_string = sprintf(
@@ -739,13 +747,14 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                         }
                     } else {
                         if ($this->number_of_dates > 1) {
+                            $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                             $repetition_string = sprintf(
                                 _('Jedes %1$u. Jahr im %2$s am %3$u. %4$s (%5$u Termine)'),
                                 $this->interval,
                                 getMonthName($this->month, false),
                                 $this->offset,
                                 getWeekday($this->days, false),
-                                $this->number_of_dates
+                                $this->number_of_dates - $number_of_exceptions
                             );
                         } elseif ($this->repetition_end < self::NEVER_ENDING) {
                             $repetition_string = sprintf(
@@ -769,12 +778,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
                 } else {
                     //Repetition on one specific day of month.
                     if ($this->number_of_dates > 1) {
+                        $number_of_exceptions = CalendarDateException::countByCalendar_date_id($this->id);
                         $repetition_string = sprintf(
                             _('Jedes %1$u. Jahr am %2$u. %3$s (%4$u Termine)'),
                             $this->interval,
                             $this->offset,
                             getMonthName($this->month, false),
-                            $this->number_of_dates
+                            $this->number_of_dates - $number_of_exceptions
                         );
                     } elseif ($this->repetition_end < self::NEVER_ENDING) {
                         $repetition_string = sprintf(
-- 
GitLab