From 245c0c9102b515f5330825b9aa83783f8e1e2d21 Mon Sep 17 00:00:00 2001
From: Viktoria Wiebe <hush-hush@gmx.net>
Date: Fri, 15 Oct 2021 11:11:32 +0200
Subject: [PATCH] log seats and add position to export table in lectures

---
 app/controllers/course/members.php            |  7 +++
 app/controllers/course/statusgroups.php       | 59 ++++++++++++++++++-
 .../74_add_seat_reservation_log_action.php    | 28 +++++++++
 lib/classes/Seminar.class.php                 | 21 ++++++-
 lib/export/csv-t-1.xsl                        |  6 ++
 lib/export/csv-t-3.xsl                        |  6 ++
 lib/export/export_studipdata_func.inc.php     | 12 +++-
 7 files changed, 136 insertions(+), 3 deletions(-)
 create mode 100644 db/uos_migrations/74_add_seat_reservation_log_action.php

diff --git a/app/controllers/course/members.php b/app/controllers/course/members.php
index 37d52912173..5644717b7d8 100644
--- a/app/controllers/course/members.php
+++ b/app/controllers/course/members.php
@@ -240,6 +240,9 @@ class Course_MembersController extends AuthenticatedController
                         $current_member->position = $i;
                         $position[$current_member->position] = true;
                         $current_member->store();
+                        $membername = $current_member->vorname . " " . $current_member->nachname;
+                        StudipLog::log('SEAT_RESERVATION', $this->course_id, null,
+                            sprintf('%s hat Sitzplatz %s erhalten', $membername, $current_member->position));
                         break;
                     }
                 }
@@ -273,8 +276,12 @@ class Course_MembersController extends AuthenticatedController
             }
 
             foreach ($current_members as $current_member) {
+                $old_position = $current_member->position;
                 $current_member->position = 0;
                 $current_member->store();
+                $membername = $current_member->vorname . " " . $current_member->nachname;
+                StudipLog::log('SEAT_RESERVATION', $this->course_id, null,
+                    sprintf('%s hat Sitzplatz %s zurückgegeben', $membername, $old_position));
             }
         }
 
diff --git a/app/controllers/course/statusgroups.php b/app/controllers/course/statusgroups.php
index 18b327d37e7..80249a97e2d 100644
--- a/app/controllers/course/statusgroups.php
+++ b/app/controllers/course/statusgroups.php
@@ -471,6 +471,17 @@ class Course_StatusgroupsController extends AuthenticatedController
                 $success), $success, htmlReady($g->name)
             ));
         }
+        
+        // Logging seats according to group list number
+        if ($success > 0 && count($g->dates)) {
+            $info = 'Sitzplatz in Statusgruppe ' . $g->name . ' reserviert. Aktuelle Sitzplätze: ';
+            $members = $this->sortMembers($g->members);
+            $i = 1;
+            foreach ($members as $member) {
+                $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+            }
+            StudipLog::log('SEAT_RESERVATION', $this->course_id, null, $info);
+        }
 
         $this->relocate('course/statusgroups');
 
@@ -620,6 +631,17 @@ class Course_StatusgroupsController extends AuthenticatedController
                     htmlReady($g->name)
                 ));
             }
+            // Logging seats according to group list number
+            if (count($g->dates)) {
+                $info = 'Sitzplatz in Statusgruppe ' . $g->name . ' zurückgegeben. Aktuelle Sitzplätze: ';
+                $members = $this->sortMembers($g->members);
+                $i = 1;
+                foreach ($members as $member) {
+                    $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+                }
+                StudipLog::log('SEAT_RESERVATION', $this->course_id, null, $info);
+            }
+            
         } else {
             if ($user_id == $GLOBALS['user']->id) {
                 PageLayout::postError(sprintf(
@@ -804,6 +826,16 @@ class Course_StatusgroupsController extends AuthenticatedController
                 _('Sie wurden aus der Gruppe %s ausgetragen.'),
                 htmlReady($g->name)
             ));
+            // Logging seats according to group list number
+            if (count($g->dates)) {
+                $info = 'Sitzplatz in Statusgruppe ' . $g->name . ' zurückgegeben. Aktuelle Sitzplätze: ';
+                $members = $this->sortMembers($g->members);
+                $i = 1;
+                foreach ($members as $member) {
+                    $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+                }
+                StudipLog::log('SEAT_RESERVATION', $this->course_id, null, $info);
+            }
         } else {
             PageLayout::postError(sprintf(
                 _('Sie konnten nicht aus der Gruppe %s ausgetragen werden.'),
@@ -1274,7 +1306,32 @@ class Course_StatusgroupsController extends AuthenticatedController
                 }
             }
         }
-        $groupname = Statusgruppen::find(Request::option('target_group'))->name;
+        
+        // Logging seats according to group list number
+        $old_group = Statusgruppen::find(Request::option('source'));
+        if (count($old_group->dates)) {
+            $info = 'Sitzplätze in ' . $old_group->name . ' zurückgegeben. Aktuelle Sitzplätze: ';
+            $members = $this->sortMembers($old_group->members);
+            $i = 1;
+            foreach ($members as $member) {
+                $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+            }
+            StudipLog::log('SEAT_RESERVATION', $this->course_id, null, $info);
+        }
+        
+        $target_group = Statusgruppen::find(Request::option('target_group'));
+        if (count($target_group->dates)) {
+            $info = 'Sitzplätze in ' . $target_group->name . ' reserviert. Aktuelle Sitzplätze: ';
+            $members = $this->sortMembers($target_group->members);
+            $i = 1;
+            foreach ($members as $member) {
+                $cm = CourseMember::find([$this->course_id, $member->user_id]);
+                $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+            }
+            StudipLog::log('SEAT_RESERVATION', $this->course_id, null, $info);
+        }
+        
+        $groupname = $target_group->name;
 
         // Everything completed successfully => success message.
         if ($success && !$error) {
diff --git a/db/uos_migrations/74_add_seat_reservation_log_action.php b/db/uos_migrations/74_add_seat_reservation_log_action.php
new file mode 100644
index 00000000000..a1feb2ab671
--- /dev/null
+++ b/db/uos_migrations/74_add_seat_reservation_log_action.php
@@ -0,0 +1,28 @@
+<?php
+class AddSeatReservationLogAction extends Migration
+{
+    public function description()
+    {
+        return "Adds a log event action for a seat reservation";
+    }
+    
+    public function up()
+    {
+        DBManager::get()->exec("
+            INSERT IGNORE INTO log_actions
+            SET action_id = MD5('SEAT_RESERVATION'),
+                name = 'SEAT_RESERVATION',
+                description = 'Nutzer bucht oder gibt einen Sitzplatz zurück',
+                info_template = '%user hat einen Sitzplatz in %sem(%affected) geändert.',
+                active = '1',
+                expires = '0'
+        ");
+    }
+
+    public function down()
+    {
+        DBManager::get()->exec("
+            DELETE FROM log_actions WHERE action_id = MD5('SEAT_RESERVATION')
+        ");
+    }
+}
diff --git a/lib/classes/Seminar.class.php b/lib/classes/Seminar.class.php
index 74ffa2eb07c..c0880d9cd6c 100644
--- a/lib/classes/Seminar.class.php
+++ b/lib/classes/Seminar.class.php
@@ -1997,6 +1997,9 @@ class Seminar
      */
     public function deleteMember($user_id)
     {
+        // Variable for seat logging
+        $seat_number = CourseMember::find([$this->id, $user_id])->position;
+        
         $dozenten = $this->getMembers('dozent');
         if (count($dozenten) >= 2 || !$dozenten[$user_id]) {
             $query = "DELETE FROM seminar_user WHERE Seminar_id = ? AND user_id = ?";
@@ -2054,7 +2057,23 @@ class Seminar
 
             // Remove from associated status groups
             foreach (Statusgruppen::findBySeminar_id($this->id) as $group) {
-                $group->removeUser($user_id, true);
+                $removed = $group->removeUser($user_id, true);
+                // Logging seat reservation by group list number
+                if (count($group->dates) && $removed) {
+                    $info = 'Sitzplätze in Statusgruppe ' . $group->name . ' zurückgegeben. Aktuelle Sitzplätze: ';
+                    $group->sortMembersAlphabetic();
+                    $i = 1;
+                    foreach ($group->members as $member) {
+                        $info .= $member->user->getFullName() . ": " . $i++ . "; ";
+                    }
+                    StudipLog::log('SEAT_RESERVATION', $this->id, null, $info);
+                }
+            }
+            
+            if (!$removed && $seat_number) {
+                StudipLog::log('SEAT_RESERVATION', $this->id, null, 
+                    sprintf("%s hat Sitzplatz %s zurückgegeben", 
+                    get_fullname($user_id), $seat_number));
             }
 
             $this->createMessage(sprintf(
diff --git a/lib/export/csv-t-1.xsl b/lib/export/csv-t-1.xsl
index 5c5e2e9752e..25dfdd4682d 100644
--- a/lib/export/csv-t-1.xsl
+++ b/lib/export/csv-t-1.xsl
@@ -62,6 +62,7 @@
 				<xsl:text>";</xsl:text>
 			</xsl:for-each>
 		</xsl:if>
+		<xsl:text>Sitzplatz;</xsl:text>
 		<xsl:text>Bemerkung</xsl:text>
 		<xsl:text>
 </xsl:text>
@@ -151,6 +152,11 @@
 				<xsl:with-param name="daten" select="zusatzangaben"/>
 			</xsl:call-template>
 
+            <xsl:if test="sitzplatz">
+				<xsl:value-of select="sitzplatz"/>
+			</xsl:if>
+			<xsl:text>";"</xsl:text>
+
 			<xsl:if test="bemerkung">
 				<xsl:value-of select="bemerkung"/>
 			</xsl:if>
diff --git a/lib/export/csv-t-3.xsl b/lib/export/csv-t-3.xsl
index 7ae2f4969ea..e1ded55ab86 100644
--- a/lib/export/csv-t-3.xsl
+++ b/lib/export/csv-t-3.xsl
@@ -38,6 +38,7 @@
         <xsl:text>&#xFEFF;</xsl:text>
 	    <xsl:text>Gruppe;</xsl:text>
 		<xsl:text>Titel;</xsl:text>
+		<xsl:text>Position;</xsl:text>
 		<xsl:text>Vorname;</xsl:text>
 		<xsl:text>Nachname;</xsl:text>
 		<xsl:text>Titel2;</xsl:text>
@@ -87,6 +88,11 @@
 				<xsl:value-of select="str:replace(titel,'&quot;','&quot;&quot;')"/>
 			</xsl:if>
 			<xsl:text>";"</xsl:text>
+			
+			<xsl:if test="listnumber">
+				<xsl:value-of select="listnumber"/>
+			</xsl:if>
+			<xsl:text>";"</xsl:text>
 
 			<xsl:if test="vorname">
 				<xsl:value-of select="vorname"/>
diff --git a/lib/export/export_studipdata_func.inc.php b/lib/export/export_studipdata_func.inc.php
index 2b7a45285af..42dfeb954d5 100644
--- a/lib/export/export_studipdata_func.inc.php
+++ b/lib/export/export_studipdata_func.inc.php
@@ -612,7 +612,8 @@ function export_teilis($inst_id, $ex_sem_id = "no")
                 $parameters[':seminar_id'] = $ex_sem_id;
             } else {
                 $query                          = "SELECT DISTINCT ui.*, aum.*, su.*, FROM_UNIXTIME(su.mkdate) AS registration_date,
-                                 GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge
+                                 GROUP_CONCAT(CONCAT_WS(',', sg.name, a.name, user_studiengang.semester) SEPARATOR '; ') AS nutzer_studiengaenge,
+                                 statusgruppe_user.statusgruppe_id
                           FROM statusgruppe_user
                           LEFT JOIN seminar_user AS su USING (user_id)
                           LEFT JOIN auth_user_md5 AS aum USING (user_id)
@@ -700,6 +701,7 @@ function export_teilis($inst_id, $ex_sem_id = "no")
         $object_counter_tmp = $object_counter;
         if (count($data) > 0) {
             $data_object_tmp .= xml_open_tag($xml_groupnames_person['subgroup1'], $val1);
+            $i = 1;
             foreach ($data as $row) {
                 // Nur Personen ausgeben, die entweder einer Gruppe angehoeren
                 // oder zur Veranstaltung gehoeren und noch nicht ausgegeben wurden.
@@ -721,6 +723,14 @@ function export_teilis($inst_id, $ex_sem_id = "no")
                     if ($matrikelnummer != '') {
                         $data_object_tmp .= xml_tag('matrikelnummer', $matrikelnummer);
                     }
+                    
+                    if ($row['position']) {
+                        $data_object_tmp .= xml_tag('sitzplatz', $row['position']);
+                    } 
+                    
+                    if ($row['statusgruppe_id'] && Statusgruppen::find($row['statusgruppe_id'])->dates) {
+                        $data_object_tmp .= xml_tag('listnumber', $i++);
+                    }
 
                     // freie Datenfelder ausgeben
                     $data_object_tmp             .= export_datafields($row['user_id'], $xml_groupnames_person['childgroup1'], $xml_groupnames_person['childobject1'], 'user');
-- 
GitLab