Merge branch 'feature-40842/DashboardAmpeln' into feature-25999/C4

This commit is contained in:
Harald Bamberger
2024-09-09 12:56:55 +02:00
12 changed files with 826 additions and 370 deletions
@@ -0,0 +1,145 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Ampeln extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'open' => self::PERM_LOGGED,
'all' => self::PERM_LOGGED,
'confirm' => self::PERM_LOGGED,
'alleAmpeln' => self::PERM_LOGGED,
]);
$this->load->model('content/Ampel_model', 'AmpelModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* confirms ampel and inserts ampel_id in public.tbl_ampel_benutzer_bestaetigt
* @access public
*
*/
public function confirm($ampel_id)
{
$this->load->library('form_validation');
$this->form_validation->set_data(['ampel_id'=> $ampel_id]);
$this->form_validation->set_rules('ampel_id', 'Ampel ID', 'required|integer');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// load Ampel_benutzer_bestaetigt_model to confirm the ampel
$this->load->model('content/Ampel_Benutzer_Bestaetigt_model', 'AmpelBenutzerBestaetigtModel');
$insert_into_result = $this->AmpelBenutzerBestaetigtModel->insert(["ampel_id"=> $ampel_id, "uid"=> $this->uid]);
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
$this->terminateWithSuccess($insert_into_result);
}
/**
* queries active and not confirmed ampeln by the user
* @access public
*
*/
public function open()
{
$userAmpeln = array();
// fetch active ampeln
$activeAmpeln = $this->AmpelModel->openActive($this->uid, false);
$activeAmpeln = $this->getDataOrTerminateWithError($activeAmpeln);
foreach ($activeAmpeln as $ampel) {
// only include non confirmed active ampeln in the result
if (!$ampel->bestaetigt) {
// check if the user was assigned to the ampel
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if($zugeteilt) $userAmpeln[] = $ampel;
}
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln of the user
* @access public
*
*/
public function all()
{
$userAmpeln = array();
$ampel_result = $this->AmpelModel->active(false, $this->uid);
$ampel_result = $this->getDataOrTerminateWithError($ampel_result);
foreach ($ampel_result as $ampel) {
// check if the ampel was assigned to the user
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if ($zugeteilt) $userAmpeln[] = $ampel;
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln that were assigned to the user until start of first work day
* @access public
*
*/
public function alleAmpeln()
{
//fetch all ampeln
$alle_ampeln = $this->AmpelModel->alleAmpeln($this->uid);
$alle_ampeln = $this->getDataOrTerminateWithError($alle_ampeln);
$alle_ampeln = array_map(function ($ampel) {
// check if ampel is confirmed by user
$confirmedByUser = $this->AmpelModel->isConfirmed($ampel->ampel_id, $this->uid);
$ampel->bestaetigt = $confirmedByUser;
return $ampel;
}, $alle_ampeln);
$this->terminateWithSuccess($alle_ampeln);
}
}
@@ -18,11 +18,6 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Profil extends FHCAPI_Controller
{
@@ -18,11 +18,6 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class ProfilUpdate extends FHCAPI_Controller
{
@@ -25,6 +25,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Used to create a return object, should not be used directly
* @return stdClass
*/
function _createReturnObject($code, $error, $retval)
{
@@ -39,7 +40,7 @@ function _createReturnObject($code, $error, $retval)
/**
* Success
*
* @return array
* @return stdClass
*/
function success($retval = null, $code = null)
{
@@ -49,7 +50,7 @@ function success($retval = null, $code = null)
/**
* Error
*
* @return array
* @return stdClass
*/
function error($retval = null, $code = null)
{
@@ -0,0 +1,14 @@
<?php
class Ampel_Benutzer_Bestaetigt_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_ampel_benutzer_bestaetigt';
$this->pk = 'ampel_benutzer_bestaetigt_id';
}
}
+175 -20
View File
@@ -16,37 +16,95 @@ class Ampel_model extends DB_Model
* 1. not after the deadline date
* 2. not before the vorlaufszeit
* @param bool $email If true, then only ampeln are retrieved that are marked to be sent by mail.
* @return array Returns array of objects.
* @return stdClass Returns array of objects.
*/
public function active($email = false)
public function active($email = false, $uid = null)
{
$parametersArray = null;
$query = '
SELECT *
FROM public.tbl_ampel
WHERE';
if ($email === true)
{
$parametersArray['email'] = $email;
$query .= ' email = ? AND';
$userLanguage = getUserLanguage();
$selectStatement='*,beschreibung[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as beschreibung_trans, buttontext[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as buttontext_trans';
if($uid != null ){
$selectStatement .= ',
COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt';
}
$query .= '(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
AND (NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline))';
$this->addSelect($selectStatement);
$whereStatement='';
$query .= ' ORDER BY deadline DESC';
if ($email === true) {
$whereStatement .= ' email = '.$this->escape($email).' AND';
}
$whereStatement .=
'(
(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
)
AND
(
(NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline)
)
)';
$this->addOrder('deadline', 'DESC');
return $this->loadWhere($whereStatement);
}
public function openActive($uid, $email = false)
{
$userLanguage = getUserLanguage();
$selectStatement = '*,beschreibung[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as beschreibung_trans, buttontext[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as buttontext_trans';
$selectStatement .= ',
COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt';
$this->addSelect($selectStatement);
$whereStatement = '';
if ($email === true) {
$whereStatement .= ' email = ' . $this->escape($email) . ' AND';
}
$whereStatement .=
'
(COALESCE((
SELECT true
FROM public.tbl_ampel_benutzer_bestaetigt a
WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id
AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) = FALSE) AND
(
(
(NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date)
OR (verfallszeit IS NULL)
)
AND
(
(NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date)
OR (vorlaufzeit IS NULL AND NOW() < deadline)
)
)';
$this->addOrder('deadline', 'DESC');
return $this->loadWhere($whereStatement);
return $this->execQuery($query, $parametersArray);
}
/**
* Returns all Ampel-receiver of a specific Ampel.
* @param string $benutzer_select SQL Statement which defines the Ampel-receiver.
* @return array Returns array of objects with property 'uid'.
* @return stdClass Returns array of objects with property 'uid'.
*/
public function execBenutzerSelect($benutzer_select)
{
@@ -90,4 +148,101 @@ class Ampel_model extends DB_Model
else
return $result; //will contain the error-msg from execQuery
}
/**
* checks if a user is assigned to an ampel
* @param string $uid userID
* @param string $benutzer_select the select query which gets all the user that are assigned to an ampel
* @return stdClass
*/
public function isZugeteilt($uid, $benutzer_select){
$zugeteilt = $this->execReadOnlyQuery("
SELECT
CASE WHEN ? IN (".$benutzer_select.")
THEN true
ELSE false
END as zugeteilt
", [$uid]);
if(isError($zugeteilt)){
return $zugeteilt;
}
$zugeteilt = getData($zugeteilt);
return success(current($zugeteilt)->zugeteilt);
}
// THIS FUNCTION IS NOT IN USE
// fetches all ampeln that were assigned to the user after the working start_date
function alleAmpeln($uid){
$userLanguage = getUserLanguage();
$zugeteile_ampeln = [];
$datum = new datum();
$now = $datum->mktime_fromdate(date('Y-m-d'));
// start date of user
$benutzerStartDate = $this->execReadOnlyQuery("
SELECT insertamum FROM public.tbl_benutzer WHERE uid = ?", [$uid]);
$benutzerStartDate = $datum->mktime_fromdate(date(current(getData($benutzerStartDate))->insertamum));
$allAmpeln = $this->execReadOnlyQuery("
SELECT *, beschreibung[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as beschreibung_trans, buttontext[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as buttontext_trans FROM
public.tbl_ampel");
if(isError($allAmpeln)) return error(getError($allAmpeln));
$allAmpeln = getData($allAmpeln);
foreach($allAmpeln as $ampel){
// check if the ampel is assigned to the user
$zugeteilt = $this->execReadOnlyQuery("
SELECT
CASE WHEN ? IN (".$ampel->benutzer_select.")
THEN true
ELSE false
END as zugeteilt
", [$uid]);
if(isError($zugeteilt)) return error(getError($zugeteilt));
$zugeteilt = current(getData($zugeteilt))->zugeteilt;
// abgelaufen check
// $now > strtotime('+' . $ampel->verfallszeit . ' day', $ampel->deadline)
if(
// aktuelles datum liegt vor der Vorlaufzeit der Ampel
(isset($ampel->vorlaufzeit) && $now < strtotime('-' . $ampel->vorlaufzeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
||
// ampel ist vor Arbeitsstart abgelaufen
(isset($ampel->verfallszeit) && $benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
||
// ampel ist vor Arbeitsstart abgelaufen (verfallszeit nicht vorhanden)
($benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline)))
){
// continue iteration if ampel is expired before work start or shouldn't be visible yet
continue;
}
$ampel->zugeteilt = $zugeteilt;
if($zugeteilt) $zugeteile_ampeln[] = $ampel;
}
return success($zugeteile_ampeln);
}
private function getLanguageIndex($userLanguage)
{
return "
SELECT index
FROM public.tbl_sprache
WHERE sprache = " . $userLanguage;
}
}