From 4812a305b566941add5bab63c2d64eaece1aa2f2 Mon Sep 17 00:00:00 2001
From: Peter Thienel <thienel@data-quest.de>
Date: Wed, 27 Oct 2021 19:22:59 +0000
Subject: [PATCH] BIEST #69 MVV-Studiengang-Ansprechpartner: Externe Personen

---
 app/controllers/shared/contacts.php           | 104 +++++++++++++++---
 .../studiengaenge/studiengangteile.php        |   2 +
 app/views/module/module/modul.php             |   2 +-
 .../shared/contacts/add_ansprechpartner.php   |   8 +-
 .../shared/contacts/contact_range_fields.php  |  24 ++++
 app/views/shared/contacts/details.php         |   4 +-
 .../shared/contacts/edit_ansprechpartner.php  |  40 +++++++
 app/views/shared/contacts/range.php           |  50 +++++----
 .../studiengaenge/studiengang.php             |   2 +-
 .../studiengangteile/stgteil.php              |   2 +-
 lib/models/MvvContactRange.php                |   3 +-
 11 files changed, 193 insertions(+), 48 deletions(-)
 create mode 100644 app/views/shared/contacts/contact_range_fields.php
 create mode 100644 app/views/shared/contacts/edit_ansprechpartner.php

diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php
index e3e2cfe9a4b..f2d5ceea658 100644
--- a/app/controllers/shared/contacts.php
+++ b/app/controllers/shared/contacts.php
@@ -118,6 +118,17 @@ class Shared_ContactsController extends MVVController
             $this->range_type = MvvContactRange::getRangeTypeByRangeId($this->range_id);
         }
         $this->contacts = MvvContactRange::findBySQL('range_id = ? ORDER BY position ASC', [$this->range_id]);
+        $one_contact = reset($this->contacts);
+        $this->perm_contacts = 0;
+        if (is_object($one_contact)) {
+            $range_type = $one_contact->range_type;
+            $range_object = $range_type::find($one_contact->range_id);
+            if (!$range_object) {
+                $this->perm_contacts = MvvPerm::get(Request::get('range_type'))->getFieldPerm('contact_assignments');
+            } else {
+                $this->perm_contacts = MvvPerm::get($range_object)->getFieldPerm('contact_assignments');
+            }
+        }
         if (!isset($this->contact_id)) {
             $this->contact_id = null;
         }
@@ -125,12 +136,12 @@ class Shared_ContactsController extends MVVController
 
     public function details_action($origin, $contact_id)
     {
-        $contact_range = MvvContactRange::findOneBySQL('contact_id=?', [$contact_id]);
-        if (!$contact_range) {
+        $this->contact_range = MvvContactRange::findOneBySQL('contact_id = ?', [$contact_id]);
+        if (!$this->contact_range) {
             throw new Trails_Exception(404);
         }
 
-        $this->relations = $contact_range->getRelations($this->filter);
+        $this->relations = $this->contact_range->getRelations($this->filter);
         $this->origin = $origin;
 
         if (!Request::isXhr()) {
@@ -399,9 +410,27 @@ class Shared_ContactsController extends MVVController
         }
     }
 
+    public function edit_ansprechpartner_action($contact_range_id, $origin = 'index')
+    {
+        $this->contact_range = MvvContactRange::find($contact_range_id);
+        if ($this->contact_range) {
+            if ($this->contact_range->contact->contact_status === 'extern') {
+                PageLayout::setTitle(_('Externen Ansprechpartner bearbeiten'));
+                $this->extern_contact = MvvExternContact::find($this->contact_range->contact_id);
+            } else if ($this->contact_range->contact->contact_status === 'intern') {
+                PageLayout::setTitle(_('Internen Ansprechpartner bearbeiten'));
+            } else if ($this->contact_range->contact->contact_status === 'institution') {
+                PageLayout::setTitle(_('Zugeordnete Einrichtung bearbeiten'));
+            } else {
+                throw new Exception(_('Unbekannter Zuordnungs-Typ.'));
+            }
+        }
+        $this->origin = $origin;
+    }
+
     public function add_ansprechpartner_action($origin = 'index', $range_type = null, $range_id = null, $user_id = null, $category = null)
     {
-        PageLayout::setTitle(_('Ansprechpartner des Studienganges'));
+        PageLayout::setTitle(_('Ansprechpartner zuordnen'));
 
         $this->extcontact_search_obj = new SQLSearch("SELECT extern_contact_id, mvv_extern_contacts.name "
                 . "FROM mvv_extern_contacts "
@@ -413,7 +442,8 @@ class Shared_ContactsController extends MVVController
         $this->ext_contact = $ext_contact;
 
         if (Request::submitted('store_ansprechpartner')) {
-
+            CSRFProtection::verifySecurityToken();
+            
             if (!$user_id) {
                 if (Request::get('exansp_name')) {
                     $ext_contact->name = Request::i18n('exansp_name');
@@ -491,12 +521,12 @@ class Shared_ContactsController extends MVVController
         }
 
         if ($user_id && $category) {
-            $contact_range = MvvContactRange::findOneBySQL("contact_id =? AND range_id =? AND category=?",[$user_id, $range_id, $category]);
+            $contact_range = MvvContactRange::findOneBySQL("contact_id = ? AND range_id = ? AND category = ?", [$user_id, $range_id, $category]);
             $this->ansp_status = $contact_range->contact->contact_status;
             $this->ansp_altmail = $contact_range->contact->alt_mail;
             $this->ansp_typ = $contact_range->type;
             $this->ansp_kat = $contact_range->category;
-            $this->ansp_name = $contact_range->name;
+            $this->ansp_name = $contact_range->contact->getContactName();
         } else {
             $this->ansp_name = '';
         }
@@ -508,11 +538,46 @@ class Shared_ContactsController extends MVVController
         $this->origin = $origin;
     }
 
-    public function delete_range_action($range_id, $contact_id, $category)
+    public function store_ansprechpartner_action ($contact_range_id, $origin = 'index') {
+        CSRFProtection::verifySecurityToken();
+        
+        $contact_range = MvvContactRange::find($contact_range_id);
+        if (!$contact_range) {
+            throw new Exception(_('Fehlerhafte Zuordnung!'));
+        }
+        $contact_range->type = Request::option('contact_type', '');
+        $contact_range->category = Request::option('contact_category');
+        if ($contact_range->contact->contact_status === 'extern') {
+            $extern_contact = MvvExternContact::find($contact_range->contact_id);
+            $extern_contact->name     = Request::get('contact_name');
+            $extern_contact->vorname  = Request::get('contact_vorname');
+            $extern_contact->homepage = Request::get('contact_homepage', '');
+            $extern_contact->mail     = Request::get('contact_mail', '');
+            $extern_contact->tel      = Request::get('contact_tel', '');
+            if (!strlen($extern_contact->name)) {
+                PageLayout::postError('Es muss ein Name angegeben werden!');
+            }
+            $extern_contact->store();
+        }
+        $contact_range->contact->alt_mail = Request::get('contact_altmail', '');
+        $contact_range->contact->store();
+        $contact_range->store();
+        PageLayout::postSuccess(_('Der Ansprechpartner wurde gespeichert.'));
+        if ($origin === 'range') {
+            $this->response->add_header('X-Dialog-Execute', 'STUDIP.MVV.Contact.reload_contacttable("' . $contact_range->range_id . '", "' . $contact_range->range_type . '")');
+            $this->response->add_header('X-Dialog-Close', 1);
+        } else {
+            $this->response->add_header('X-Dialog-Close', 1);
+            $this->response->add_header('X-Location', $this->url_for('/index', ['contact_id' => $mvv_contact->id]));
+        }
+        $this->render_nothing();
+    }
+
+    public function delete_range_action($contact_range_id)
     {
-        CSRFProtection::verifyRequest();
+        CSRFProtection::verifySecurityToken();
 
-        $range = MvvContactRange::findOneBySQL("contact_id =? AND range_id =? AND category=?",[$contact_id, $range_id, $category]);
+        $range = MvvContactRange::find($contact_range_id);
         $contact = $range->contact;
 
         if (!($range && MvvPerm::get($contact)->haveFieldPerm('ranges', MvvPerm::PERM_CREATE))) {
@@ -570,27 +635,32 @@ class Shared_ContactsController extends MVVController
         }
     }
 
-    public function sort_action($range_id = null)
+    public function sort_action($range_id = null, $range_type = '')
     {
         if (Request::submitted('order')) {
             $ordered = json_decode(Request::get('ordering'), true);
             if (is_array($ordered)) {
                 $ok = false;
+                $range_type = '';
                 foreach ($ordered as $p => $user_kat_id) {
                     $usr_kat_split = explode('_', $user_kat_id['id']);
-                    if ($mvv_contact_range = MvvContactRange::findOneBySQL("contact_id =? AND range_id =? AND category=?",[$usr_kat_split[0], $range_id, $usr_kat_split[1]])) {
+                    if ($mvv_contact_range = MvvContactRange::findOneBySQL("contact_id = ? AND range_id = ? AND category = ?",
+                            [$usr_kat_split[0], $range_id, $usr_kat_split[1]])) {
                         $mvv_contact_range->position = $p + 1;
                         $ok += $mvv_contact_range->store();
+                        $range_type = $mvv_contact_range->range_type;
                     }
                 }
-                if (Request::isXhr()) {
-                    header('X-Dialog-Close: 1');
-                    exit;
-                }
+                $this->response->add_header('X-Dialog-Execute', 'STUDIP.MVV.Contact.reload_contacttable("' . $range_id . '", "' . $range_type . '")');
+                $this->response->add_header('X-Dialog-Close', 1);
+                $this->render_nothing();
+                return;
             }
         }
         $this->range_id = $range_id;
-        $this->contacts = MvvContactRange::findBySQL('range_id = ? ORDER BY position ASC', [$range_id]);
+        $this->range_type = $range_type;
+        $this->contacts = MvvContactRange::findBySQL('range_id = ? AND range_type = ? ORDER BY position ASC',
+                [$range_id, $range_type]);
         PageLayout::setTitle(_('Reihenfolge ändern'));
     }
 
diff --git a/app/controllers/studiengaenge/studiengangteile.php b/app/controllers/studiengaenge/studiengangteile.php
index 75ce8b4008a..8bd66cd6e4f 100644
--- a/app/controllers/studiengaenge/studiengangteile.php
+++ b/app/controllers/studiengaenge/studiengangteile.php
@@ -16,6 +16,8 @@ class Studiengaenge_StudiengangteileController extends SharedVersionController
         parent::before_filter($action, $args);
         Navigation::activateItem($this->me . '/studiengaenge/studiengangteile');
         $this->action = $action;
+        PageLayout::addStyleSheet('studip-statusgroups.css');
+        PageLayout::addScript('studip-statusgroups.js');
     }
 
     public function index_action()
diff --git a/app/views/module/module/modul.php b/app/views/module/module/modul.php
index 6e698378d16..6c03e424444 100644
--- a/app/views/module/module/modul.php
+++ b/app/views/module/module/modul.php
@@ -452,7 +452,7 @@ if ($GLOBALS['MVV_MODUL']['SPRACHE']['default'] != $display_language) {
         </legend>
         <label>
             <?= _('Ansprechpartner'); ?>
-            <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->haveFieldPerm('contact_assignments', MvvPerm::PERM_CREATE), 'range_type' => 'Modul', 'range_id' => $modul->id]) ?>
+            <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->getFieldPerm('contact_assignments'), 'range_type' => 'Modul', 'range_id' => $modul->id, 'contacts' => $contacts->getArrayCopy()]) ?>
         </label>
 
         <label><?= _('Weitere verantwortliche Personen') ?>
diff --git a/app/views/shared/contacts/add_ansprechpartner.php b/app/views/shared/contacts/add_ansprechpartner.php
index f4d40d2d408..30317bcb841 100644
--- a/app/views/shared/contacts/add_ansprechpartner.php
+++ b/app/views/shared/contacts/add_ansprechpartner.php
@@ -83,19 +83,19 @@ jQuery(function ($) {
             </label>
             <label>
                 <?= _('Vorname (optional)') ?>
-                <input name="exansp_vorname" type="text" value=""<?= $perm_extern->disable('vorname'); ?>>
+                <input name="exansp_vorname" type="text" value="<?= htmlReady($ext_contact->vorname) ?>"<?= $perm_extern->disable('vorname'); ?>>
             </label>
             <label>
                 <?= _('Homepage') ?>
                 <?= MvvI18N::input('exansp_web', $ext_contact->homepage, ['maxlength' => '255'])->checkPermission($ext_contact) ?>
             </label>
             <label>
-                <?= _('E-Mail') ?>
-                <input name="exansp_mail" type="text" value=""<?= $perm_extern->disable('mail'); ?>>
+                <?= _('Email') ?>
+                <input name="exansp_mail" type="text" value="<?= htmlReady($ext_contact->mail) ?>"<?= $perm_extern->disable('mail'); ?>>
             </label>
             <label>
                 <?= _('Telefon') ?>
-                <input name="exansp_tel" type="text" value=""<?= $perm_extern->disable('tel'); ?>>
+                <input name="exansp_tel" type="text" value="<?= htmlReady($ext_contact->tel) ?>"<?= $perm_extern->disable('tel'); ?>>
             </label>
         </fieldset>
     </div>
diff --git a/app/views/shared/contacts/contact_range_fields.php b/app/views/shared/contacts/contact_range_fields.php
new file mode 100644
index 00000000000..3a8bdba66aa
--- /dev/null
+++ b/app/views/shared/contacts/contact_range_fields.php
@@ -0,0 +1,24 @@
+<fieldset>
+    <legend>
+        <?= _('Zuordnungsdaten') ?>
+    </legend>
+    <? if ($contact_range->range_type !== 'Modul') : ?>
+        <label>
+            <?= _('Ansprechpartnertyp') ?>
+            <select style="display: inline-block; max-width: 40em;" name="contact_type"<?= MvvPerm::get('MvvContactRange')->disable('contact_type') ?>>
+                <option value=""<?= empty($contact_range->type) ? ' selected' : '' ?>><?= _('keine Auswahl') ?></option>
+            <? foreach ($GLOBALS['MVV_CONTACTS']['TYPE']['values'] as $key => $entry) : ?>
+                <option value="<?= $key ?>"<?= $key == $contact_range->type ? ' selected' : '' ?>><?= htmlReady($entry['name']) ?></option>
+            <? endforeach ?>
+            </select>
+        </label>
+    <? endif ?>
+    <label>
+        <?= _('Kategorie') ?>
+        <select style="display: inline-block; max-width: 40em;" name="contact_category"<?= MvvPerm::get('MvvContactRange')->disable('contact_category') ?>>
+        <? foreach (MvvContactRange::getCategoriesByRangetype($contact_range->range_type) as $key => $entry) : ?>
+            <option value="<?= $key ?>"<?= $key == $contact_range->category ? ' selected' : '' ?>><?= htmlReady($entry['name']) ?></option>
+        <? endforeach ?>
+        </select>
+    </label>
+</fieldset>
\ No newline at end of file
diff --git a/app/views/shared/contacts/details.php b/app/views/shared/contacts/details.php
index c3f1e44eec1..7a7347774ba 100644
--- a/app/views/shared/contacts/details.php
+++ b/app/views/shared/contacts/details.php
@@ -55,13 +55,13 @@
                                     <?
                                         $actions = ActionMenu::get();
                                         $actions->addLink(
-                                            $controller->url_for('shared/contacts/add_ansprechpartner', $origin, $rel['range_type'], $rel['range_id'], $rel['contact_id'], $rel['category']),
+                                            $controller->url_for('shared/contacts/edit_ansprechpartner', $rel['contact_range_id'], $origin),
                                             _('Ansprechpartner bearbeiten'),
                                             Icon::create('edit'),
                                             ['data-dialog' => 'size=auto']
                                         );
                                         $actions->addLink(
-                                            $controller->url_for('shared/contacts/delete_range', $rel['range_id'], $rel['contact_id'], $rel['category']),
+                                            $controller->url_for('shared/contacts/delete_range', $rel['contact_range_id']),
                                             _('Ansprechpartner-Zuordnung löschen'),
                                             Icon::create('trash'),
                                             [
diff --git a/app/views/shared/contacts/edit_ansprechpartner.php b/app/views/shared/contacts/edit_ansprechpartner.php
new file mode 100644
index 00000000000..fed2665dfd4
--- /dev/null
+++ b/app/views/shared/contacts/edit_ansprechpartner.php
@@ -0,0 +1,40 @@
+<form class="default" action="<?= $controller->url_for('/store_ansprechpartner', $contact_range->contact_range_id, $origin) ?>" method="post" data-dialog="size=auto">
+    <fieldset>
+        <legend>
+            <?= _('Personendaten') ?>
+        </legend>
+        <? if ($contact_range->contact->contact_status === 'extern') : ?>
+            <? $perm_extern = MvvPerm::get('MvvExternContact') ?>
+            <label>
+                <?= _('Name') ?>
+                <?= MvvI18N::input('contact_name', $extern_contact->name, ['maxlength' => '255'])->checkPermission($extern_contact) ?>
+            </label>
+            <label>
+                <?= _('Vorname (optional)') ?>
+                <input name="contact_vorname" type="text" value="<?= htmlReady($extern_contact->vorname) ?>"<?= $perm_extern->disable('vorname'); ?>>
+            </label>
+            <label>
+                <?= _('Homepage') ?>
+                <?= MvvI18N::input('contact_homepage', $extern_contact->homepage, ['maxlength' => '255'])->checkPermission($extern_contact) ?>
+            </label>
+            <label>
+                <?= _('Email') ?>
+                <input name="contact_mail" type="text" value="<?= htmlReady($extern_contact->mail) ?>"<?= $perm_extern->disable('mail'); ?>>
+            </label>
+            <label>
+                <?= _('Telefon') ?>
+                <input name="contact_tel" type="text" value="<?= htmlReady($extern_contact->tel) ?>"<?= $perm_extern->disable('tel'); ?>>
+            </label>
+        <? endif ?>
+        <label>
+            <?= _('Alternative Kontaktmail (optional)') ?>
+            <input name="contact_altmail" type="text" value="<?= htmlReady($contact_range->contact->alt_mail) ?>"<?= MvvPerm::get('MvvContact')->disable('alt_mail'); ?>>
+        </label>
+    </fieldset>
+    <?= $this->render_partial('shared/contacts/contact_range_fields') ?>
+    <?= CSRFProtection::tokenTag() ?>
+    <div data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern'), 'store_contacta') ?>
+        <?= Studip\LinkButton::createCancel(); ?>
+    </div>
+</form>
diff --git a/app/views/shared/contacts/range.php b/app/views/shared/contacts/range.php
index 1f13bab5351..a036c1073aa 100644
--- a/app/views/shared/contacts/range.php
+++ b/app/views/shared/contacts/range.php
@@ -8,12 +8,16 @@
 <table id="mvv_contacts" class="default sortable-table" data-sortlist="[[0, 0]]">
     <caption>
         <span class="actions">
-            <a href="<?= $controller->url_for('shared/contacts/add_ansprechpartner', 'range', $range_type, $range_id);?>" data-dialog="size=auto">
-                <?= Icon::create('headache+add', Icon::ROLE_CLICKABLE, ['title' => _('Ansprechpartner hinzufügen')]); ?>
-            </a>
-            <a href="<?= $controller->url_for('shared/contacts/sort', $range_id);?>" data-dialog="size=auto">
-                <?= Icon::create('arr_2up', Icon::ROLE_CLICKABLE, ['title' => _('Reihenfolge der Ansprechpartner ändern')]); ?>
-            </a>
+            <? if ($perm_contacts >= MvvPerm::PERM_CREATE) : ?>
+                <a href="<?= $controller->url_for('shared/contacts/add_ansprechpartner', 'range', $range_type, $range_id);?>" data-dialog="size=auto">
+                    <?= Icon::create('headache+add', Icon::ROLE_CLICKABLE, ['title' => _('Ansprechpartner hinzufügen')]); ?>
+                </a>
+            <? endif ?>
+            <? if (reset($contacts) && MvvPerm::get(reset($contacts))->haveFieldPerm('position', MvvPerm::PERM_WRITE)) : ?>
+                <a href="<?= $controller->url_for('shared/contacts/sort', $range_id, $range_type);?>" data-dialog="size=auto">
+                    <?= Icon::create('arr_2up', Icon::ROLE_CLICKABLE, ['title' => _('Reihenfolge der Ansprechpartner ändern')]); ?>
+                </a>
+            <? endif ?>
         </span>
     </caption>
     <thead>
@@ -43,21 +47,25 @@
             <td class="actions">
             <?
                 $actions = ActionMenu::get();
-                $actions->addLink(
-                    $controller->url_for('shared/contacts/add_ansprechpartner', 'range', $mvv_contact->range_type, $mvv_contact->range_id, $mvv_contact->contact_id, $mvv_contact->category),
-                    _('Ansprechpartner bearbeiten'),
-                    Icon::create('edit'),
-                    ['data-dialog' => 'size=auto']
-                );
-                $actions->addLink(
-                    $controller->url_for('shared/contacts/delete_range', $mvv_contact->range_id, $mvv_contact->contact_id, $mvv_contact->category),
-                    _('Ansprechpartner-Zuordnung löschen'),
-                    Icon::create('trash'),
-                    [
-                        'data-confirm' => _('Wollen Sie die Zuordnung des Ansprechpartners wirklich entfernen?'),
-                        'data-dialog' => 'size=auto'
-                    ]
-                );
+                if ($perm_contacts >= MvvPerm::PERM_WRITE) {
+                    $actions->addLink(
+                        $controller->url_for('shared/contacts/edit_ansprechpartner', $mvv_contact->id, 'range'),
+                        _('Ansprechpartner bearbeiten'),
+                        Icon::create('edit'),
+                        ['data-dialog' => 'size=auto']
+                    );
+                }
+                if ($perm_contacts >= MvvPerm::PERM_CREATE) {
+                    $actions->addLink(
+                        $controller->url_for('shared/contacts/delete_range', $mvv_contact->id),
+                        _('Ansprechpartner-Zuordnung löschen'),
+                        Icon::create('trash'),
+                        [
+                            'data-confirm' => _('Wollen Sie die Zuordnung des Ansprechpartners wirklich entfernen?'),
+                            'data-dialog' => 'size=auto'
+                        ]
+                    );
+                }
                 echo $actions;
             ?>
             </td>
diff --git a/app/views/studiengaenge/studiengaenge/studiengang.php b/app/views/studiengaenge/studiengaenge/studiengang.php
index bb507ed349f..69a47ac0ad3 100644
--- a/app/views/studiengaenge/studiengaenge/studiengang.php
+++ b/app/views/studiengaenge/studiengaenge/studiengang.php
@@ -324,7 +324,7 @@
         <legend>
             <?= _('Ansprechpartner'); ?>
         </legend>
-        <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->haveFieldPerm('contact_assignments', MvvPerm::PERM_CREATE), 'range_type' => 'Studiengang', 'range_id' => $studiengang->id]) ?>
+        <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->getFieldPerm('contact_assignments'), 'range_type' => 'Studiengang', 'range_id' => $studiengang->id, 'contacts' => $contacts->getArrayCopy()]) ?>
     </fieldset>
 
     <?= $plugin_hook_content ?>
diff --git a/app/views/studiengaenge/studiengangteile/stgteil.php b/app/views/studiengaenge/studiengangteile/stgteil.php
index 7579579ea75..ce18fddbe7a 100644
--- a/app/views/studiengaenge/studiengangteile/stgteil.php
+++ b/app/views/studiengaenge/studiengangteile/stgteil.php
@@ -87,7 +87,7 @@
         <legend>
             <?= _('Ansprechpartner'); ?>
         </legend>
-        <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->haveFieldPerm('contact_assignments', MvvPerm::PERM_CREATE), 'range_type' => 'StudiengangTeil', 'range_id' => $stgteil->id]) ?>
+        <?= $this->render_partial('shared/contacts/range', ['perm_contacts' => $perm->getFieldPerm('contact_assignments'), 'range_type' => 'StudiengangTeil', 'range_id' => $stgteil->id, 'contacts' => $contacts->getArrayCopy()]) ?>
     </fieldset>
     
     <footer data-dialog-button>
diff --git a/lib/models/MvvContactRange.php b/lib/models/MvvContactRange.php
index e9a1109e966..be988e93a65 100644
--- a/lib/models/MvvContactRange.php
+++ b/lib/models/MvvContactRange.php
@@ -180,7 +180,8 @@ class MvvContactRange extends ModuleManagementModel
             default:
                 return array_merge(
                     $GLOBALS['MVV_STUDIENGANG']['PERSONEN_GRUPPEN']['values'],
-                    $GLOBALS['MVV_MODUL']['PERSONEN_GRUPPEN']['values']
+                    $GLOBALS['MVV_MODUL']['PERSONEN_GRUPPEN']['values'],
+                    $GLOBALS['MVV_STGTEIL']['PERSONEN_GRUPPEN']['values']
                 );
         }
     }
-- 
GitLab