diff --git a/application/controllers/jobs/LehrauftragJob.php b/application/controllers/jobs/LehrauftragJob.php
new file mode 100644
index 000000000..780c592e1
--- /dev/null
+++ b/application/controllers/jobs/LehrauftragJob.php
@@ -0,0 +1,426 @@
+load->model('accounting/Vertrag_model', 'VertragModel');
+ $this->load->model('accounting/Vertragvertragsstatus_model', 'VertragvertragsstatusModel');
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+ $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
+ $this->load->model('system/Benutzerrolle_model', 'BenutzerrolleModel');
+
+ // Load libraries
+ $this->load->library('PermissionLib');
+
+ // Load helpers
+ $this->load->helper('hlp_sancho_helper');
+ }
+
+ /**
+ * This daily job sends information about all lehr-/projektauftraege ordered (and not approved) the day bofore.
+ * Receivers: Department-/Kompetenzfeldleiter
+ **/
+ public function mailLehrauftraegeToApprove()
+ {
+ // Get vertrag_ids of lehrauftraege that had been ordered and had NOT been approved or cancelled YESTERDAY
+ $this->VertragvertragsstatusModel->addSelect('vertrag_id');
+ $result = $this->VertragvertragsstatusModel->getOrdered_fromDate('YESTERDAY');
+
+ // Get lehrveranstaltung_ids and studiensemester of the lehr-/or projektauftrag contracts
+ $lehreinheit_data_arr = array();
+ if ($vertrag_arr = getData($result))
+ {
+ foreach ($vertrag_arr as $vertrag)
+ {
+ $result = $this->VertragModel->getLehreinheitData($vertrag->vertrag_id, 'lehrveranstaltung_id, studiensemester_kurzbz');
+
+ if (hasData($result))
+ {
+ $obj = new StdClass();
+ $obj->lehrveranstaltung_id = $result->retval[0]->lehrveranstaltung_id;
+ $obj->studiensemester_kurzbz = $result->retval[0]->studiensemester_kurzbz;
+ $lehreinheit_data_arr []= $obj;
+ }
+ }
+ }
+
+ /**
+ * Build the data array to be used in the email. Data array is clustered as follows:
+ * Array
+ * [studiensemester_kurzbz] // studiensemester of lehreinheit
+ * Array
+ * [oe_kurzbz] // oe of lehreinheits lehrveranstaltung
+ * [oe_bezeichnung]
+ * Array
+ * [stg_kz] // stg of lehreinheits lehrveranstaltung
+ * [stg_kurzbz]
+ * [stg_bezeichnung]
+ * [amount] // amount of new ordered lehrauftraege of that stg
+ */
+ $data_arr = array();
+ foreach ($lehreinheit_data_arr as $lehreinheit_data)
+ {
+ $result = $this->_getLVData($lehreinheit_data->lehrveranstaltung_id);
+
+ if (hasData($result))
+ {
+ // Search if studiensemester exists in data_arr
+ $ss_index = array_search($lehreinheit_data->studiensemester_kurzbz, array_column($data_arr, 'studiensemester_kurzbz'));
+
+ // If studiensemester is new, add studienesemester, oe and stg
+ if ($ss_index === false)
+ {
+ $data = array(
+ 'studiensemester_kurzbz' => $lehreinheit_data->studiensemester_kurzbz
+ );
+
+ $data []= array(
+ 'oe_kurzbz' => $result->retval[0]->oe_kurzbz,
+ 'oe_bezeichnung' => $result->retval[0]->lv_oe_bezeichnung
+ );
+
+ // Add stg data to oe, start amount with 1
+ $data[0][] = array(
+ 'stg_kz' => $result->retval[0]->studiengang_kz,
+ 'stg_kurzbz' => strtoupper($result->retval[0]->stg_typ. $result->retval[0]->stg_kurzbz),
+ 'stg_bezeichnung' => $result->retval[0]->lv_stg_bezeichnung,
+ 'amount' => 1
+ );
+
+ // Push to final data_arr
+ $data_arr []= $data;
+ }
+ // Else if studiensemester exists
+ else
+ {
+ // Search if oe exists inside existing studiensemester of data_arr
+ $oe_index = array_search($result->retval[0]->oe_kurzbz, array_column($data_arr[$ss_index], 'oe_kurzbz'));
+
+ // If oe is new, add oe and stg to studiensemester
+ if ($oe_index === false)
+ {
+ // Add oe data
+ $data_arr[$ss_index][] = array(
+ 'oe_kurzbz' => $result->retval[0]->oe_kurzbz,
+ 'oe_bezeichnung' => $result->retval[0]->lv_oe_bezeichnung,
+
+ // Add stg data to oe, start amount with 1
+ array(
+ 'stg_kz' => $result->retval[0]->studiengang_kz,
+ 'stg_kurzbz' => strtoupper($result->retval[0]->stg_typ. $result->retval[0]->stg_kurzbz),
+ 'stg_bezeichnung' => $result->retval[0]->lv_stg_bezeichnung,
+ 'amount' => 1
+ )
+ );
+ }
+ // Else if oe exists
+ else
+ {
+ // Search if stg exists inside existing oe of data_arr
+ $stg_index = array_search($result->retval[0]->studiengang_kz, array_column($data_arr[$ss_index][$oe_index], 'stg_kz'));
+
+ // If stg is new, add stg to oe, start amount with 1
+ if ($stg_index === false)
+ {
+ $data_arr[$ss_index][$oe_index][] = array(
+ 'stg_kz' => $result->retval[0]->studiengang_kz,
+ 'stg_kurzbz' => strtoupper($result->retval[0]->stg_typ. $result->retval[0]->stg_kurzbz),
+ 'stg_bezeichnung' => $result->retval[0]->lv_stg_bezeichnung,
+ 'amount' => 1
+ );
+ }
+ // Else if stg exists
+ else
+ {
+ // Increase amount +1
+ $data_arr[$ss_index][$oe_index][$stg_index]['amount'] = $data_arr[$ss_index][$oe_index][$stg_index]['amount'] + 1;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Cluster data by uid of entitled mail receivers.
+ * Returning array is clustered as follows:
+ * Array
+ * [uid]
+ * Array
+ * [studiensemester_kurzbz] // studiensemester of lehreinheit
+ * Array
+ * [oe_kurzbz] // oe of lehreinheits lehrveranstaltung
+ * [oe_bezeichnung]
+ * Array
+ * [stg_kz] // stg of lehreinheits lehrveranstaltung
+ * [stg_kurzbz]
+ * [stg_bezeichnung]
+ * [amount] // amount of new ordered lehrauftraege of that stg
+ */
+ $data_arr = $this->_clusterData_byReceiver($data_arr);
+
+ // Send email
+ if(!$this->_sendMail($data_arr))
+ {
+ $this->logError('Fehler beim Mailversand in Job MailLehrauftragToApprove');
+ }
+ }
+
+ /**
+ * This daily job sends information about all lehr-/projektauftraege approved the day bofore.
+ * Receivers: lectors
+ **/
+ public function mailLehrauftraegeToAccept()
+ {
+
+ }
+
+ //******************************************************************************************************************
+ // PRIVATE FUNCTIONS
+ //******************************************************************************************************************
+
+ /**
+ * Get data of given lehrveranstaltung.
+ * @param $lehrveranstaltung_id
+ * @return mixed
+ */
+ private function _getLVData($lehrveranstaltung_id)
+ {
+ $this->LehrveranstaltungModel->addSelect('
+ tbl_lehrveranstaltung.oe_kurzbz,
+ oe.bezeichnung AS "lv_oe_bezeichnung",
+ tbl_lehrveranstaltung.studiengang_kz,
+ stg.bezeichnung AS "lv_stg_bezeichnung",
+ stg.typ AS "stg_typ",
+ stg.kurzbz AS "stg_kurzbz"
+ ');
+
+ $this->LehrveranstaltungModel->addJoin('lehre.tbl_studienplan_lehrveranstaltung stpllv', 'lehrveranstaltung_id');
+ $this->LehrveranstaltungModel->addJoin('lehre.tbl_studienplan stpl', 'studienplan_id');
+ $this->LehrveranstaltungModel->addJoin('lehre.tbl_studienordnung sto', 'studienordnung_id');
+ $this->LehrveranstaltungModel->addJoin('public.tbl_studiengang stg', 'ON stg.studiengang_kz = tbl_lehrveranstaltung.studiengang_kz');
+ $this->LehrveranstaltungModel->addJoin('public.tbl_organisationseinheit oe', 'ON oe.oe_kurzbz = tbl_lehrveranstaltung.oe_kurzbz');
+ $this->LehrveranstaltungModel->addOrder('stpllv.insertamum', 'DESC');
+ $this->LehrveranstaltungModel->addLimit(1);
+
+ return $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
+ }
+
+ /**
+ * Send Sancho eMail about ordered Lehrauftraege.
+ * @param $data_arr
+ */
+ private function _sendMail($data_arr)
+ {
+ // Loop through 'container' of mail recipients
+ foreach($data_arr as $data)
+ {
+ // Set mail recipients (department assistance/leader)
+ $to = $data['uid']. '@'. DOMAIN;
+ $html_table = $this->_renderData_LehrauftraegeToApprove($data);
+
+ // Prepare mail content
+ $content_data_arr = array(
+ 'table' => $html_table
+ );
+
+ sendSanchoMail(
+ 'LehrauftragNeueBestellungen',
+ $content_data_arr,
+ $to,
+ 'Bestellung neuer Lehraufträge',
+ 'sancho_header_min_bw.jpg',
+ 'sancho_footer_min_bw.jpg'
+ );
+ }
+ }
+
+ /**
+ * Cluster the data array by entitled mail receiver.
+ * Returning array is clustered as follows:
+ * Array
+ * [uid]
+ * Array
+ * [studiensemester_kurzbz] // studiensemester of lehreinheit
+ * Array
+ * [oe_kurzbz] // oe of lehreinheits lehrveranstaltung
+ * [oe_bezeichnung]
+ * Array
+ * [stg_kz] // stg of lehreinheits lehrveranstaltung
+ * [stg_kurzbz]
+ * [stg_bezeichnung]
+ * [amount] // amount of new ordered lehrauftraege of that stg
+ * @param $data_arr
+ * @return array
+ *
+ */
+ private function _clusterData_byReceiver($data_arr)
+ {
+ $mail_data_arr = array(); // final array with all data clustered by mail receiver
+
+ // Loop through 'container' of studiensemester
+ foreach ($data_arr as $data)
+ {
+ $data_len = count($data) - 1;
+
+ // Loop through 'container' of organisational units
+ for ($i = 0; $i < $data_len; $i++)
+ {
+ // Get all users entitled by organisational unit
+ $result = $this->BenutzerrolleModel->getBenutzerByBerechtigung(self::BERECHTIGUNG_LEHRAUFTRAG_ERTEILEN, $data[$i]['oe_kurzbz']);
+
+ if ($berechtigung_arr = getData($result))
+ {
+ // Loop through entitled users
+ foreach ($berechtigung_arr as $berechtigung)
+ {
+ // Search if UID exists inside mail_data_arr
+ $uid_index = array_search($berechtigung->uid, array_column($mail_data_arr, 'uid'));
+
+ // If UID is new, add UID to final array
+ if ($uid_index === false)
+ {
+ // add UID with corresponding data
+ $mail_data_arr [] = array(
+ 'uid' => $berechtigung->uid,
+ array(
+ 'studiensemester_kurzbz' => $data['studiensemester_kurzbz'],
+ $data[$i]
+ )
+ );
+ } // Else if UID exists
+ else
+ {
+ // Search if studiensemester exists
+ $ss_index = array_search($data['studiensemester_kurzbz'], array_column($mail_data_arr, 'studiensemester_kurzbz'));
+
+ // If studiensemester is new, add studiensemester to existing UID
+ if ($ss_index === false)
+ {
+ $mail_data_arr[$uid_index] []= array(
+ 'studiensemester_kurzbz' => $data['studiensemester_kurzbz'],
+ $data[$i]
+ );
+ }
+ // Else if studiensemester exists
+ else
+ {
+ // Add corresponding data to existing studiensemester of UID
+ $mail_data_arr[$uid_index]['studiensemester_kurbz'][] = $data[$i];
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ return $mail_data_arr;
+ }
+
+ /**
+ * Render the data array for the mail template returing a HTML table.
+ * @param $data_arr Data to be used in HTML table
+ * @return string HTML table to be embedded in eMail
+ */
+ private function _renderData_LehrauftraegeToApprove($data_arr)
+ {
+ $html = '';
+ foreach ($data_arr as $studiensemester_container)
+ {
+ if (is_array($studiensemester_container)) // is_array 'trims' the outer associative key [uid]
+ {
+ if (isset($studiensemester_container['studiensemester_kurzbz']))
+ {
+ $studiensemester = $studiensemester_container['studiensemester_kurzbz'];
+
+ // Link to LehrauftragErteilen
+ $url = site_url(self::LEHRAUFTRAG_ERTEILEN_URI).'?studiensemester='. $studiensemester;
+ }
+
+ // HTML table header
+ $html .= '
+
+ Studiensemester: '. $studiensemester. '
+
+
| LV-Organisationseinheit | +Studiengang | +STG-Kurzbezeichnung | +Anzahl neu bestellter Lehraufträge | +
|---|---|---|---|
| '. $oe_bezeichnung. ' | +'. $stg_data['stg_bezeichnung']. ' | +'. $stg_data['stg_kurzbz']. ' | +'. $stg_data['amount']. ' | +