diff --git a/application/config/stv.php b/application/config/stv.php index be49fed97..f902b30ce 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -144,7 +144,7 @@ $config['stv_prestudent_tags'] = [ 'inwork_kf' => ['readonly' => false], 'dd_auto' => ['readonly' => false], 'wh_auto' => ['readonly' => false], - 'prewh_auto' => ['readonly' => true], //when readonly kein rendering für automatisierte tags + 'prewh_auto' => ['readonly' => false], //when readonly kein rendering für automatisierte tags 'out_auto' => ['readonly' => false], 'zgv_auto' => ['readonly' => false], 'wiedereinstieg_auto' => ['readonly' => false], diff --git a/application/controllers/api/frontend/v1/stv/Tags.php b/application/controllers/api/frontend/v1/stv/Tags.php index 3004a1f3b..e5af9becc 100644 --- a/application/controllers/api/frontend/v1/stv/Tags.php +++ b/application/controllers/api/frontend/v1/stv/Tags.php @@ -45,4 +45,5 @@ class Tags extends Tag_Controller { parent::doneTag($this->config->item('stv_prestudent_tags')); } + } diff --git a/application/controllers/jobs/TagJob.php b/application/controllers/jobs/TagJob.php index 93bcee521..689bb6ac9 100644 --- a/application/controllers/jobs/TagJob.php +++ b/application/controllers/jobs/TagJob.php @@ -8,7 +8,7 @@ class TagJob extends JOB_Controller { const BATCHUSER = 'sftest'; - const SEMESTER = 'SS2024'; //docker + const SEMESTER = 'WS2025'; //docker //TODO semester /** @@ -37,70 +37,15 @@ class TagJob extends JOB_Controller ]); } - /** - * Test createTags - */ - public function createAutomatedTagsForPrestudents(...$prestudentIds) + public function rebuildAutomatedTags() { - print_r( PHP_EOL . "Start Job create Automated Tags" . PHP_EOL); - - $tag_typ_kurzbz = "wh_auto"; - $notiz = "TEST AUTOMATED TAG"; - $zuordnung_typ = "prestudent_id"; - $count = 0; - - $values = ($prestudentIds != null) ? $prestudentIds : [ 125239, 167955]; - - $checkZuordnungType = $this->NotizzuordnungModel->isValidType($zuordnung_typ); - if (!isSuccess($checkZuordnungType)) - return error('Error occurred'); - - $values = array_unique($values); - - foreach ($values as $value) - { - //TODO(uid) - $resultInsertNotiz = $this->NotizModel->insert(array( - 'titel' => 'TAG', - 'text' => $notiz, - 'verfasser_uid' => self::BATCHUSER, - 'erledigt' => false, - 'insertamum' => date('Y-m-d H:i:s'), - 'insertvon' => self::BATCHUSER, - 'typ' => $tag_typ_kurzbz - )); - - if (isError($resultInsertNotiz)) - return error ('Error occurred insert Result ' . $value); - - $resultInsertZuordnung = $this->NotizzuordnungModel->insert(array( - 'notiz_id' => $resultInsertNotiz->retval, - $zuordnung_typ => $value - )); - - print_r( PHP_EOL . "Tag vom Typ " . $tag_typ_kurzbz . " für " . $zuordnung_typ . " " . $value . " erstellt"); - - if (isError($resultInsertZuordnung)) - return error ('Error occurred insert Zuordnung' . $value); - - $count++; - } - - print_r( PHP_EOL . "Automatically created Tags: " . $count . PHP_EOL); - print_r( PHP_EOL . "End Job create Automated Tags" . PHP_EOL); - - } - - public function createAutomatedTags() - { - print_r( PHP_EOL . "Start Job create Automated Tags: " . PHP_EOL); - + print_r( PHP_EOL . "Start Job rebuild" . PHP_EOL); $automaticTags = $this->config->item('stv_automatic_tags'); print_r( implode( ", ", $automaticTags) . PHP_EOL); + //TODO(Manu) use a loop in library? if(in_array('wh_auto', $automaticTags)) { - print_r(PHP_EOL . "create Tags wiederholer " . PHP_EOL); $result = $this->PrestudentstatusModel-> loadWhere(array( 'statusgrund_id' => 16, 'studiensemester_kurzbz' => self::SEMESTER @@ -110,127 +55,51 @@ class TagJob extends JOB_Controller return $item->prestudent_id; }, $data); - $result = $this->taglib->getAutomatedTags('wh_auto', $ids); - if (isError($result)) - return error ('Error occurred getAutomatedTags'); + $result = $this->taglib->updateAutomatedTags('wh_auto', $ids); $data = $result->retval; + if (isError($result)) + return error ('Error occurred during updateAutomatedTags'); - print_r( PHP_EOL . "Automatically created Tags of Type WIEDERHOLER: " . $data[0] . PHP_EOL); - print_r( "prestudents: " . implode( ", ", $data[1]) . PHP_EOL); + print_r(PHP_EOL ."ALL TAGS 'wh_auto' " . count($data[0]) . " TO ADD " . count($data[1]) . " TO RECYLE: " . count($data[2]) . " TO DELETE: " . count($data[3])); + + + print_r( PHP_EOL . "Count Recycled: "); + print_r($data[4]); + print_r( PHP_EOL . "Count Added: "); + print_r($data[6]); + print_r( PHP_EOL . "Count Deleted: "); + print_r($data[8] . PHP_EOL); } if(in_array('prewh_auto', $automaticTags)) { - print_r(PHP_EOL . "create Tags pre-wiederholer " . PHP_EOL); - - $result = $this->PrestudentstatusModel-> loadWhere(array( + $result = $this->PrestudentstatusModel->loadWhere(array( 'statusgrund_id' => 15, 'studiensemester_kurzbz' => self::SEMESTER )); $data = $result->retval; - $ids = array_map(function($item) { + $ids = array_map(function ($item) { return $item->prestudent_id; }, $data); - $result = $this->taglib->getAutomatedTags('prewh_auto', $ids); + $result = $this->taglib->updateAutomatedTags('prewh_auto', $ids); if (isError($result)) - return error ('Error occurred getAutomatedTags'); + return error('Error occurred during updateAutomatedTags'); $data = $result->retval; - print_r( PHP_EOL . "Automatically created Tags of Type PRE-WIEDERHOLER: " . $data[0] . PHP_EOL); - print_r( "prestudents: " . implode( ", ", $data[1]) . PHP_EOL); + print_r(PHP_EOL . "ALL TAGS 'prewh_auto' " . count($data[0]) . " TO ADD " . count($data[1]) . " TO RECYLE: " . count($data[2]) . " TO DELETE: " . count($data[3])); + + print_r(PHP_EOL . "Count Recycled: "); + print_r($data[4]); + print_r(PHP_EOL . "Count Added: "); + print_r($data[6]); + print_r(PHP_EOL . "Count Deleted: "); + print_r($data[8] . PHP_EOL); } - if(in_array('dd_auto', $automaticTags)) - { - print_r(PHP_EOL . "create Tags double degree" . PHP_EOL); + print_r( PHP_EOL . "End Job rebuild" . PHP_EOL); - - print_r( PHP_EOL . "Automatically created Tags of Type DOUBLE DEGREE: " . $data[0] . PHP_EOL); - print_r( "prestudents: " . implode( ", ", $data[1]) . PHP_EOL); - } - - - -/* $tag_typ_kurzbz = "wh_auto"; - $notiz = "TEST AUTOMATED TAG"; - $zuordnung_typ = "prestudent_id"; - $count = 0; - - $values = ($arrayToTag != null) ? $arrayToTag : [ 125239, 167955]; - - $checkZuordnungType = $this->NotizzuordnungModel->isValidType($zuordnung_typ); - if (!isSuccess($checkZuordnungType)) - return error('Error occurred'); - - $values = array_unique($values); - - foreach ($values as $value) - { - //TODO(uid) - $resultInsertNotiz = $this->NotizModel->insert(array( - 'titel' => 'TAG', - 'text' => $notiz, - 'verfasser_uid' => self::BATCHUSER, - 'erledigt' => false, - 'insertamum' => date('Y-m-d H:i:s'), - 'insertvon' => self::BATCHUSER, - 'typ' => $tag_typ_kurzbz - )); - - if (isError($resultInsertNotiz)) - return error ('Error occurred insert Result ' . $value); - - $resultInsertZuordnung = $this->NotizzuordnungModel->insert(array( - 'notiz_id' => $resultInsertNotiz->retval, - $zuordnung_typ => $value - )); - - print_r( PHP_EOL . "Tag vom Typ " . $tag_typ_kurzbz . " für " . $zuordnung_typ . " " . $value . " erstellt"); - - if (isError($resultInsertZuordnung)) - return error ('Error occurred insert Zuordnung' . $value); - - $count++; - } - - print_r( PHP_EOL . "Automatically created Tags: " . $count . PHP_EOL);*/ - print_r( PHP_EOL . "End Job create Automated Tags" . PHP_EOL); - - } - - /** - * delete All Automatic Tags - */ - public function deleteAutomatedTags() - { - print_r( PHP_EOL . "Start Job delete ALL Automated Tags" . PHP_EOL); - // $this->NotizModel->select('notiz_id'); - $resultToDelete = $this->NotizModel->loadWhere(array('insertvon' => self::BATCHUSER)); - - $data = $resultToDelete->retval; - $notiz_ids = array_map(function($item) { - return $item->notiz_id; - }, $data); - - print_r($notiz_ids); - - foreach ($notiz_ids as $notiz_id) - { - $result = $this->NotizzuordnungModel->delete([ - 'notiz_id' => $notiz_id - ]); - if (isError($result)) - return error ('Error occurred delete Notizzuordnung' . $notiz_id); - - $result = $this->NotizModel->delete([ - 'notiz_id' => $notiz_id - ]); - if (isError($result)) - return error ('Error occurred delete Notiz' . $notiz_id); - } - print_r( PHP_EOL . "End Job delete Automated Tags" . PHP_EOL); } } diff --git a/application/core/Tag_Controller.php b/application/core/Tag_Controller.php index d3b071f96..a5a3e2a62 100644 --- a/application/core/Tag_Controller.php +++ b/application/core/Tag_Controller.php @@ -20,6 +20,7 @@ class Tag_Controller extends FHCAPI_Controller 'doneTag' => self::BERECHTIGUNG_KURZBZ, 'deleteTag' => self::BERECHTIGUNG_KURZBZ, 'getAllTags' => self::BERECHTIGUNG_KURZBZ, + 'rebuildTagsPrestudent' => self::BERECHTIGUNG_KURZBZ, ]; $merged_permissions = array_merge($default_permissions, $permissions); @@ -27,6 +28,10 @@ class Tag_Controller extends FHCAPI_Controller parent::__construct($merged_permissions); $this->_setAuthUID(); + + // Library + $this->load->library('TagLib'); + $this->load->model('person/Notiz_model', 'NotizModel'); $this->load->model('system/Notiztyp_model', 'NotiztypModel'); $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); @@ -278,7 +283,6 @@ class Tag_Controller extends FHCAPI_Controller public function getAllTags($readonly_tags = false){ $language = $this->_getLanguageIndex(); $prestudent_id = $this->input->get('prestudent_id'); - // $this->terminateWithError("id: " . $prestudent_id, self::ERROR_TYPE_GENERAL); //TODO check for readonly: necessary? if (is_array($readonly_tags) && !isEmptyArray($readonly_tags)) @@ -330,6 +334,17 @@ class Tag_Controller extends FHCAPI_Controller $this->terminateWithSuccess(hasData($notiz) ? getData($notiz) : array()); } + public function rebuildTagsPrestudent() + { + $prestudent_id = $this->input->get('prestudent_id'); + + $result = $this->taglib->rebuildTagsForPrestudent($prestudent_id); + if (isError($result)) + return error ('Error occurred during updateAutomatedTags'); + + $this->terminateWithSuccess($result); + } + private function _setAuthUID() { $this->_uid = getAuthUID(); diff --git a/application/libraries/TagLib.php b/application/libraries/TagLib.php index 144863978..2200e16d9 100644 --- a/application/libraries/TagLib.php +++ b/application/libraries/TagLib.php @@ -18,6 +18,8 @@ class TagLib { const BATCHUSER = 'sftest'; const TYP_ZUORDNUNG = 'prestudent_id'; + const SEMESTER = 'WS2025'; + /** * Object initialization */ @@ -35,7 +37,7 @@ class TagLib $this->_ci->load->model('person/Notiz_model', 'NotizModel'); $this->_ci->load->model('system/Notiztyp_model', 'NotiztypModel'); $this->_ci->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); - + $this->_ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); // Tag-Helper @@ -46,20 +48,82 @@ class TagLib } - public function getAutomatedTags($tag, $prestudentIds) + public function updateAutomatedTags($tag, $prestudentIds) { $prestudentIds = array_unique($prestudentIds); - $count = 0; - $tagged = []; + + $toRecycle = []; + $toAdd = []; + $toDelete = []; + $allTags = []; + + $this->_ci->NotizModel->addSelect('nz.notiz_id'); + $this->_ci->NotizModel->addSelect('prestudent_id'); + $this->_ci->NotizModel->addJoin('public.tbl_notizzuordnung nz', 'notiz_id'); + $resultAllTags = $this->_ci->NotizModel->loadWhere([ + 'typ' => $tag + ]); + + $allTagsData = getData($resultAllTags); + + if (!empty($allTagsData)) { + foreach ($allTagsData as $row) { + $allTags[$row->prestudent_id] = $row->notiz_id; + } + } + + foreach ($prestudentIds as $value) { + if (isset($allTags[$value])) { + // if already existing: recyceln: nothing to do + $toRecycle[$value] = $allTags[$value] ; + } else { + $toAdd[] = $value; + } + } + + foreach ($allTags as $prestudent_id => $notiz_id) { + if (!in_array($prestudent_id, $prestudentIds)) { + $toDelete[$prestudent_id] = $notiz_id; + } + } + + //RECYCLE: Just insert new update Date + $countRecyled = 0; + $retagged = []; + foreach ($toRecycle as $value) + { + //TODO(Manu) refactor for recycle, add + $resultUpdateNotiz = $this->_ci->NotizModel->update( + [ + 'notiz_id' => $value + ], + array( + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => 'BatchJobTagUpdate', + )); + + if (isError($resultUpdateNotiz)) + return error ('Error occurred update Result ' . $value); + + $countRecyled++; + $retagged[] = $resultUpdateNotiz->retval; + } + + //ADD: Create new Tags + $countAdded = 0; + $tagged = []; + foreach ($toAdd as $value) + { + //TODO(Manu) refactor for recycle, add $resultInsertNotiz = $this->_ci->NotizModel->insert(array( 'titel' => 'TAG', 'text' => 'AUTOMATED TAG', - 'verfasser_uid' => self::BATCHUSER, + 'verfasser_uid' => self::BATCHUSER, //has to be an uid 'erledigt' => false, 'insertamum' => date('Y-m-d H:i:s'), - 'insertvon' => self::BATCHUSER, + 'insertvon' => 'BatchJobTagAdd', 'typ' => $tag )); @@ -74,17 +138,206 @@ class TagLib if (isError($resultInsertZuordnung)) return error ('Error occurred insert Zuordnung' . $value); - $count++; - $tagged[] = $value; + $countAdded++; + $tagged[$resultInsertNotiz->retval] = $value; } - return success([$count, $tagged]); + + //DELETE OLD Tags, no more valid + $countDeleted = 0; + $deleted = []; + foreach ($toDelete as $value) + { + $result = $this->_ci->NotizzuordnungModel->delete([ + 'notiz_id' => $value + ]); + if (isError($result)) + return error ('Error occurred delete Notizzuordnung' . $notiz_id); + + $result = $this->_ci->NotizModel->delete([ + 'notiz_id' => $notiz_id + ]); + if (isError($result)) + return error ('Error occurred delete Notiz' . $notiz_id); + + $countDeleted++; + $deleted[] = $value; + } + + return success([$allTags, $toAdd, $toRecycle, $toDelete, $countRecyled, $retagged, $countAdded, $tagged, $countDeleted, $deleted]); } - public function getAutomatedTagsStudiengang($studiengang_Kzs= null) + public function updateAutomatedTagsForPrestudent($tag, $prestudent_id) { + $return = null; + $notiz_id = null; + + $this->_ci->NotizModel->addSelect('nz.notiz_id'); + $this->_ci->NotizModel->addSelect('prestudent_id'); + $this->_ci->NotizModel->addJoin('public.tbl_notizzuordnung nz', 'notiz_id'); + $resultAllTags = $this->_ci->NotizModel->loadWhere([ + 'typ' => $tag, + 'prestudent_id' => $prestudent_id + ]); + if(hasData($resultAllTags)) + { + $notiz_id = $resultAllTags->retval[0]->notiz_id; + } + + //RECYCLE + if ($notiz_id !== null) + { + //TODO(Manu) refactor for recycle, add + $resultUpdateNotiz = $this->_ci->NotizModel->update( + [ + 'notiz_id' => $notiz_id + ], + array( + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => 'Manually', + )); + + if (isError($resultUpdateNotiz)) + return error ('Error occurred update Result ' . $notiz_id); + + $return = ['recycled' => $notiz_id]; + } + else + { + //TODO(Manu) refactor for recycle, add + $resultInsertNotiz = $this->_ci->NotizModel->insert(array( + 'titel' => 'TAG', + 'text' => 'AUTOMATED TAG', + 'verfasser_uid' => self::BATCHUSER, //has to be an uid //TODO (auth UID) + 'erledigt' => false, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'Manually', + 'typ' => $tag + )); + + if (isError($resultInsertNotiz)) + return error ('Error occurred insert Result ' . $prestudent_id); + + $resultInsertZuordnung = $this->_ci->NotizzuordnungModel->insert(array( + 'notiz_id' => $resultInsertNotiz->retval, + self::TYP_ZUORDNUNG => $prestudent_id + )); + + if (isError($resultInsertZuordnung)) + return error ('Error occurred insert Zuordnung' . $prestudent_id); + + $return = ['added' => $resultInsertNotiz->retval]; + } + + return success($return); } +/* + * main function for rebuild Tags for single prestudent + * manually triggered + * */ + public function rebuildTagsForPrestudent($prestudent_id) + { + $automaticTags = $this->_ci->config->item('stv_automatic_tags'); + $return = []; -} \ No newline at end of file + foreach ($automaticTags as $tag) + { + if($this->isCriteriaSetFor($tag, $prestudent_id)) + { + $result = $this->updateAutomatedTagsForPrestudent($tag, $prestudent_id); + if (isError($result)) + return error ('Error occurred during updateAutomatedTags' . $tag); + + else + $return[$tag] = $result; + } + else { + $result = $this->checkForDelete($tag, $prestudent_id); + if($result != null) + $return[$tag] = $result; + } + } + + + return success($return); + + } + + public function checkForDelete($tag, $prestudent_id) + { + $return = null; + $notiz_id = null; + + if (!is_numeric($prestudent_id)) + return error ("prestudent_id " . $prestudent_id . "not numeric"); + + $this->_ci->NotizModel->addSelect('nz.notiz_id'); + $this->_ci->NotizModel->addSelect('prestudent_id'); + $this->_ci->NotizModel->addJoin('public.tbl_notizzuordnung nz', 'notiz_id'); + $resultAllTags = $this->_ci->NotizModel->loadWhere([ + 'typ' => $tag, + 'prestudent_id' => $prestudent_id + ]); + if(hasData($resultAllTags)) + { + $notiz_id = $resultAllTags->retval[0]->notiz_id; + } + + if($notiz_id) + { + $result = $this->_ci->NotizzuordnungModel->delete([ + 'notiz_id' => $notiz_id + ]); + if (isError($result)) + return error ('Error occurred during delete Notizzuordnung' . $notiz_id); + + $result = $this->_ci->NotizModel->delete([ + 'notiz_id' => $notiz_id + ]); + if (isError($result)) + return error ('Error occurred during delete Notiz' . $notiz_id); + + $return = ['deleted' => $notiz_id]; + } + return $return; + } + + public function isCriteriaSetFor($tag, $prestudent_id) + { + //TODO(finish list) + if($tag == 'wh_auto') + { + $result = $this->_ci->PrestudentstatusModel->loadWhere(array( + 'statusgrund_id' => 16, + 'studiensemester_kurzbz' => self::SEMESTER, + 'prestudent_id' => $prestudent_id + )); + if(hasData($result)) + { + return true; + } + else + return false; + } + + if($tag == 'prewh_auto') + { + $result = $this->_ci->PrestudentstatusModel->loadWhere(array( + 'statusgrund_id' => 15, + 'studiensemester_kurzbz' => self::SEMESTER, + 'prestudent_id' => $prestudent_id + )); + if(hasData($result)) + { + return true; + } + else + return false; + } + + return false; + + } +} diff --git a/public/js/api/factory/stv/tag.js b/public/js/api/factory/stv/tag.js index a5db6cb73..d78e7f685 100644 --- a/public/js/api/factory/stv/tag.js +++ b/public/js/api/factory/stv/tag.js @@ -52,12 +52,20 @@ export default { }; }, - //TODO expand to other types + //TODO check if necessary to expand to other idTypes getAllTagsPrestudent(prestudent_id){ return { method: 'get', url: 'api/frontend/v1/stv/Tags/getAllTags', params: prestudent_id }; + }, + + rebuildTagsPrestudent(prestudent_id){ + return { + method: 'get', + url: 'api/frontend/v1/stv/Tags/rebuildTagsPrestudent', + params: prestudent_id + }; } }; \ No newline at end of file diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 3207cddaa..01635e31e 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -123,6 +123,7 @@ export default { isFetchingIssues: false, tagEndpoint: ApiTag, tagData: null, + rebuildData: null }; }, methods: { @@ -244,6 +245,17 @@ export default { { this.reload(); }, + rebuildPrestudentTags(){ + const prestudent_id = this.headerData[0].prestudent_id; + return this.$api + .call(ApiTag.rebuildTagsPrestudent({prestudent_id})) + .then(result => { + this.rebuildData = result.data; + console.log("Rebuild manually triggered"); + this.reload(); + }) + .catch(this.$fhcAlert.handleSystemError); + } }, template: `