From e2b0b843f86e1e42f868266af184a50e707e4a59 Mon Sep 17 00:00:00 2001 From: Artem Konenko <yadummer@gmail.com> Date: Sun, 24 Sep 2017 20:54:05 +0300 Subject: [PATCH] Add a few models for plans, record books and so on. --- db/migrations/stored/R__functions.sql | 191 +++++++++++++++++- .../stored/R__stored_subdivisions.sql | 14 +- .../structure/V2_0_4_6__upd_record_books.sql | 19 ++ .../classes/Controller/Api/V0/Student.php | 186 +++++++++++++++-- .../classes/Controller/Api/V0/StudyPlan.php | 147 ++++++++++++++ .../classes/Controller/Api/V0/Teacher.php | 30 +-- .../classes/Controller/Handler/Api.php | 39 ++++ .../application/classes/Model/Discipline.php | 8 + .../application/classes/Model/Faculties.php | 12 ++ .../Model/Helper/DisciplineBuilder.php | 3 + .../classes/Model/Helper/PlanBuilder.php | 17 ++ .../Model/Helper/RecordBookBuilder.php | 44 ++++ .../application/classes/Model/Plan.php | 61 ++++++ .../application/classes/Model/RecordBook.php | 135 +++++++++++++ .../application/classes/Model/Student.php | 10 +- .../application/classes/Model/Subject.php | 9 +- .../application/classes/Model/Teacher.php | 8 + ~dev_rating/application/routes/api/v0.php | 13 ++ .../application/views/office/sync.twig | 5 +- 19 files changed, 890 insertions(+), 61 deletions(-) create mode 100644 db/migrations/structure/V2_0_4_6__upd_record_books.sql create mode 100644 ~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php create mode 100644 ~dev_rating/application/classes/Model/Helper/PlanBuilder.php create mode 100644 ~dev_rating/application/classes/Model/Helper/RecordBookBuilder.php create mode 100644 ~dev_rating/application/classes/Model/Plan.php create mode 100644 ~dev_rating/application/classes/Model/RecordBook.php diff --git a/db/migrations/stored/R__functions.sql b/db/migrations/stored/R__functions.sql index 028903bfb..7ad43ef6f 100644 --- a/db/migrations/stored/R__functions.sql +++ b/db/migrations/stored/R__functions.sql @@ -289,6 +289,23 @@ BEGIN RETURN 0; # Успешно удалено; END // +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS Subject_GetIDFromExternalID// +CREATE FUNCTION Subject_GetIDFromExternalID ( + pSubjectExternalID VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT subjects.ID INTO pID + FROM subjects + WHERE subjects.ExternalID = pSubjectExternalID + LIMIT 1; + + RETURN pID; + END // + # ------------------------------------------------------------------------------------------- # Label: accounts # ------------------------------------------------------------------------------------------- @@ -424,6 +441,40 @@ BEGIN RETURN 1; END // +-- Получение внутреннего ID РїРѕ хешу РЎРќРЛС РёР· 1РЎ +DROP FUNCTION IF EXISTS Account_GetIDFromINILA// +CREATE FUNCTION Account_GetIDFromINILA ( + pAccountINILA VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT accounts.ID INTO pID + FROM accounts + WHERE accounts.INILA = pAccountINILA + LIMIT 1; + + RETURN pID; + END // + +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS Account_GetIDFromExternalID// +CREATE FUNCTION Account_GetIDFromExternalID ( + pAccountExternalID VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT accounts.ID INTO pID + FROM accounts + WHERE accounts.ExternalID = pAccountExternalID + LIMIT 1; + + RETURN pID; + END // + # ------------------------------------------------------------------------------------------- # Label: teachers # ------------------------------------------------------------------------------------------- @@ -544,7 +595,7 @@ END // -- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ DROP FUNCTION IF EXISTS Teacher_GetIDFromExternalID// CREATE FUNCTION Teacher_GetIDFromExternalID ( - pTeacherExternalID INT + pTeacherExternalID VARCHAR(9) ) RETURNS int(11) READS SQL DATA BEGIN @@ -559,6 +610,24 @@ READS SQL DATA RETURN pID; END // +-- Получение внутреннего ID РїРѕ хешу РЎРќРЛС РёР· 1РЎ +DROP FUNCTION IF EXISTS Teacher_GetIDFromINILA// +CREATE FUNCTION Teacher_GetIDFromINILA ( + pTeacherINILA VARCHAR(40) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT teachers.ID INTO pID + FROM teachers + INNER JOIN accounts ON teachers.AccountID = accounts.ID + WHERE accounts.INILA = pTeacherINILA + LIMIT 1; + + RETURN pID; + END // + # ------------------------------------------------------------------------------------------- # Label: students # ------------------------------------------------------------------------------------------- @@ -641,6 +710,24 @@ BEGIN RETURN CreateStudent(pLastName, pFirstName, pSecondName, vGroupID, pActivationCode, pSemesterID); END // +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS Student_GetIDFromExternalID// +CREATE FUNCTION Student_GetIDFromExternalID ( + pAccountExternalID VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT students.ID INTO pID + FROM accounts + JOIN students ON accounts.ID = students.AccountID + WHERE accounts.ExternalID = pAccountExternalID + LIMIT 1; + + RETURN pID; + END // + # Give a student an academic leave or attach him to group. # params: # StudentID (int) @@ -688,6 +775,91 @@ BEGIN RETURN ROW_COUNT()-1; END // +# ------------------------------------------------------------------------------------------- +# Label: record books +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS RecordBook_Create// +CREATE FUNCTION RecordBook_Create ( + pExternalID VARCHAR(30) CHARSET utf8, + pStudentID VARCHAR(30) CHARSET utf8, + pPlanID VARCHAR(30) CHARSET utf8, + pFacultyID INT +) RETURNS int(11) +NO SQL + BEGIN + DECLARE vRecordBookID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + INSERT INTO record_books (StudentID, ExternalID, PlanID) + VALUES (pStudentID, pExternalID, pPlanID); + SET vRecordBookID = LAST_INSERT_ID(); + + RETURN vRecordBookID; + END // + +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS RecordBook_GetIDFromExternalID// +CREATE FUNCTION RecordBook_GetIDFromExternalID ( + pRecordBookExternalID VARCHAR(20) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT record_books.ID INTO pID + FROM record_books + WHERE record_books.ExternalID = pRecordBookExternalID + LIMIT 1; + + RETURN pID; + END // + +# ------------------------------------------------------------------------------------------- +# Label: plans +# ------------------------------------------------------------------------------------------- + +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS Plan_GetIDFromExternalID// +CREATE FUNCTION Plan_GetIDFromExternalID ( + pPlanExternalID VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT study_plans.ID INTO pID + FROM study_plans + WHERE study_plans.ExternalID = pPlanExternalID + LIMIT 1; + + IF pID = -1 THEN + INSERT INTO study_plans (ExternalID) + VALUES (pPlanExternalID); + SET pID = LAST_INSERT_ID(); + END IF; + + RETURN pID; + END // + +DROP PROCEDURE IF EXISTS Plan_GetInfo // +CREATE PROCEDURE Plan_GetInfo(IN pID INT(11)) +READS SQL DATA + BEGIN + SELECT + study_plans.ID, + study_plans.ExternalID, + study_groups.FacultyID, + students_groups.SemesterID, + study_groups.GradeID + FROM study_plans + JOIN record_books ON record_books.PlanID = study_plans.ID + JOIN students_groups ON record_books.ID = students_groups.RecordBookID + JOIN study_groups ON students_groups.GroupID = study_groups.ID + WHERE pID = study_plans.ID + LIMIT 1; + END // + # ------------------------------------------------------------------------------------------- # Label: disciplines # ------------------------------------------------------------------------------------------- @@ -762,6 +934,23 @@ BEGIN RETURN vDisciplineID; END // +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP FUNCTION IF EXISTS Discipline_GetIDFromExternalID// +CREATE FUNCTION Discipline_GetIDFromExternalID ( + pDisciplineExternalID VARCHAR(9) +) RETURNS int(11) +READS SQL DATA + BEGIN + DECLARE pID INT DEFAULT -1; + + SELECT disciplines.ID INTO pID + FROM disciplines + WHERE disciplines.ExternalID = pDisciplineExternalID + LIMIT 1; + + RETURN pID; + END // + DROP FUNCTION IF EXISTS ChangeDisciplineSubjectUnsafe// CREATE FUNCTION ChangeDisciplineSubjectUnsafe ( pDisciplineID INT, diff --git a/db/migrations/stored/R__stored_subdivisions.sql b/db/migrations/stored/R__stored_subdivisions.sql index 4d6ac63d8..800334568 100644 --- a/db/migrations/stored/R__stored_subdivisions.sql +++ b/db/migrations/stored/R__stored_subdivisions.sql @@ -59,16 +59,14 @@ BEGIN RETURN pFacultyID; END// -DROP FUNCTION IF EXISTS Faculty_GetIdByExternalID// -CREATE FUNCTION Faculty_GetIdByExternalID( - pFacultyExternalID VARCHAR(9) -) RETURNS INT(11) # -1 or id +-- Получение внутреннего ID РїРѕ РєРѕРґСѓ справочника РёР· 1РЎ +DROP PROCEDURE IF EXISTS Faculty_GetIdByExternalID// +CREATE PROCEDURE Faculty_GetIdByExternalID(IN pFacultyExternalID VARCHAR(9)) READS SQL DATA BEGIN - RETURN (SELECT faculties.ID as ID - FROM faculties - WHERE faculties.ExternalID = pFacultyExternalID - LIMIT 1); + SELECT faculties.ID as ID + FROM faculties + WHERE faculties.ExternalID = pFacultyExternalID; END// # ------------------------------------------------------------------------------------------- diff --git a/db/migrations/structure/V2_0_4_6__upd_record_books.sql b/db/migrations/structure/V2_0_4_6__upd_record_books.sql new file mode 100644 index 000000000..771d9f2a9 --- /dev/null +++ b/db/migrations/structure/V2_0_4_6__upd_record_books.sql @@ -0,0 +1,19 @@ +START TRANSACTION; + +CREATE TABLE `disciplines_study_plans` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `DisciplineID` int(11) NOT NULL, + `StudyPlanID` int(11) NOT NULL, + PRIMARY KEY (`ID`), + UNIQUE KEY `UniqBind` (`DisciplineID`, `StudyPlanID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `disciplines` +-- РљРѕРґ справочника РёР· 1РЎ + ADD COLUMN `ExternalID` VARCHAR(9) CHARACTER SET utf8 DEFAULT NULL AFTER `ID` +; + +ALTER TABLE `accounts` + MODIFY COLUMN `INILA` VARCHAR(40) CHARACTER SET utf8 DEFAULT NULL; + +COMMIT ; \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Api/V0/Student.php b/~dev_rating/application/classes/Controller/Api/V0/Student.php index c04004966..210be72a6 100644 --- a/~dev_rating/application/classes/Controller/Api/V0/Student.php +++ b/~dev_rating/application/classes/Controller/Api/V0/Student.php @@ -2,6 +2,150 @@ class Controller_Api_V0_Student extends Controller_Handler_Api { + private function normalizeRecordBookData($data) + { + /* + * $data = [ +'externalID' => $this->request->query('id') + + 'planExternalID' => $this->request->query('planId') + , 'subdivisionExternalID' => $this->request->query('subdivision') + , 'status' => $this->request->query('status') + , 'level' => $this->request->query('level') + , 'form' => $this->request->query('form') + , 'speciality' => $this->request->query('speciality') + , 'grade' => $this->request->query('grade') + , 'group' => $this->request->query('group') + ]; + */ + if ( !isset($data->id) && isset($data->externalID) ) { + $ID = Model_RecordBook::withExternalID($data->externalID); + $data->id = $ID; + } + + if ( !isset($data->studentID) ) { + if ( isset($data->studentExternalID) ) { + $studentID = Model_Student::withExternalID($data->studentExternalID); + if ($studentID === -1) { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ найден студент РїРѕ данному идентификатору.')); + } + + $data->studentID = $studentID; + } else { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ указан идентификатор студента.')); + } + } + + if ( !isset($data->planID) ) { + if ( isset($data->planExternalID) ) { + $planID = Model_Plan::withExternalID($data->planExternalID); + + $data->planID = $planID; + } else { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ указан идентификатор учебного плана.')); + } + } + + if ( !isset($data->facultyID) ) { + if ( isset($data->facultyExternalID) ) { + $depid = $this->getFacultyIDByExternalID($data->facultyExternalID); + if ( $depid === NULL ) { + $this->badRequestError( $this->makeErrorMsg($data, 'Ошибка РІ РєРѕРґРµ справочника факультета.') ); + } + $data->facultyID = $depid; + } else { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ указано подразделение.')); + } + } + +//print_r($data); +// echo "\n\n"; + + return $data; + } + + private function normalizeStudentData($data) { + if ( !isset($data->id) && isset($data->externalID) ) { + $ID = Model_Student::withExternalID($data->externalID); + $data->id = $ID; + } + + if ( !isset($data->departmentID) ) { + if ( isset($data->departmentExternalID) ) { + $depid = $this->getDepIDByExternalID($data->departmentExternalID); + if ( $depid === NULL ) { + $this->badRequestError( $this->makeErrorMsg($data, 'Ошибка РєРѕРґРµ справочника подразделения.') ); + } + $data->departmentID = $depid; + } elseif ( isset($data->departmentName) ) { + $depid = $this->getDepIDByName($data->departmentName); + if ( $depid === NULL ) { + $this->badRequestError( $this->makeErrorMsg($data, 'Ошибка РІ имени подразделения.') ); + } + $data->departmentID = $depid; + } else { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ указано подразделение.')); + } + } + + echo $data->firstName.' '.$data->secondName.' '.$data->lastName.' $data->id: '.$data->id."\n"; + if ( !isset($data->id) || ($data->id == -1) ) { + echo "-- Try to find by name !\n"; + $foundedList = Model_Teachers::search([$data->firstName, $data->secondName, $data->lastName], 0, 0); + if ( count($foundedList) === 1 ) { + echo '--- Founded by name id: '.$foundedList[0]['ID']."!\n"; + $data->id = $foundedList[0]['ID']; + } + } + + if ( !isset($data->jobPositionID) && isset($data->jobPositionName) ) { + $jpID = Model_Faculties::getJobPositionIdByName($data->jobPositionName); + if ( $jpID === NULL ) { + $jpID = Model_Faculties::createJobPosition($data->jobPositionName); + } + $data->jobPositionID = $jpID; + } elseif( !isset($data->jobPositionName) ) { + $this->badRequestError( $this->makeErrorMsg($data, 'РќРµ указана должность.') ); + } + + switch ($data->status) { + case 'Работает': + $data->status = true; + break; + case 'Уволен': + $data->status = false; + break; + default: + $this->badRequestError( $this->makeErrorMsg($data, 'Указан некорректный статус.') ); + } + + return $data; + } + + private function createRecordBook($data) { + try { + $recordbook = Model_RecordBook::make() + ->studentID($data->studentID) + ->planID($data->planID) + ->facultyID($data->facultyID); + + if ( isset($data->externalID) ) { + $recordbook = $recordbook->externalID($data->externalID); + } + + $recordbook = $recordbook->create(); + } catch (InvalidArgumentException $e) { + $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + } + return ['ID' => $recordbook->ID]; + } + + private function updateRecordBook($data) { + try { +// Model_RecordBook::with($data->id)->changeInfo(); + } catch (InvalidArgumentException $e) { + $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + } + } + public function action_get_index() { $this->response->body( '{ what: get index }' ); @@ -9,10 +153,10 @@ class Controller_Api_V0_Student extends Controller_Handler_Api } /** - * @api {put} api/v0/student Add new student(s) - * @apiName Add new student - * @apiGroup Student - * @apiVersion 0.1.0 + * @api {put} api/v0/student/recordBook Add new record book(s) + * @apiName Add new record book + * @apiGroup Record books + * @apiVersion 0.1.2 * @apiParam {String} token Api key * @apiParam {String} [batch] Flag about massive addition * @apiParam {String} firstName @@ -31,21 +175,23 @@ class Controller_Api_V0_Student extends Controller_Handler_Api $res = []; foreach ($data as $item) { - $data = $this->normalizeTeacherData($item); - $res[] = $this->createTeacher($data); + $data = $this->normalizeRecordBookData($item); + $res[] = $this->createRecordBook($data); } } else { - $data = [ 'firstName' => $this->request->query('firstName') - , 'secondName' => $this->request->query('secondName') - , 'lastName' => $this->request->query('lastName') - , 'departmentName' => $this->request->query('departmentName') - , 'departmentID' => $this->request->query('departmentID') - , 'jobPositionName' => $this->request->query('jobPositionName') - , 'jobPositionID' => $this->request->query('jobPositionID') - , 'status' => $this->request->query('status')]; + $data = [ 'externalID' => $this->request->query('id') + , 'planExternalID' => $this->request->query('planId') + , 'subdivisionExternalID' => $this->request->query('subdivision') + , 'status' => $this->request->query('status') + , 'level' => $this->request->query('level') + , 'form' => $this->request->query('form') + , 'speciality' => $this->request->query('speciality') + , 'grade' => $this->request->query('grade') + , 'group' => $this->request->query('group') + ]; - $data = $this->normalizeTeacherData((object)$data); - $res[] = $this->createTeacher($data); + $data = $this->normalizeRecordBookData((object)$data); + $res[] = $this->createRecordBook($data); } } catch (Exception $e) { $this->badRequestError($e->getMessage()); @@ -77,8 +223,8 @@ class Controller_Api_V0_Student extends Controller_Handler_Api $res = []; foreach ($data as $item) { - $data = $this->normalizeTeacherData($item); - $res[] = $this->createTeacher($data); + $data = $this->normalizeStudentData($item); + $res[] = $this->createRecordBook($data); } } else { $data = [ 'firstName' => $this->request->query('firstName') @@ -90,8 +236,8 @@ class Controller_Api_V0_Student extends Controller_Handler_Api , 'jobPositionID' => $this->request->query('jobPositionID') , 'status' => $this->request->query('status')]; - $data = $this->normalizeTeacherData((object)$data); - $res[] = $this->createTeacher($data); + $data = $this->normalizeStudentData((object)$data); + $res[] = $this->createRecordBook($data); } } catch (Exception $e) { $this->badRequestError($e->getMessage()); diff --git a/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php new file mode 100644 index 000000000..10cb348ba --- /dev/null +++ b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php @@ -0,0 +1,147 @@ +<?php + +class Controller_Api_V0_StudyPlan extends Controller_Handler_Api +{ + private function normalizeDisciplinesData($data) { + if ( !isset($data->id) && isset($data->externalID) ) { + $ID = Model_Discipline::withExternalID($data->externalID); + if ( $ID != -1 ) + $data->id = $ID; + } + + foreach ($data->teachersHashSnils as $teacherHashSnils) { + $ID = Model_Teacher::withINILA($teacherHashSnils); + if ( $ID != -1 ) + $data->teacherIDs[] = $ID; + } + + /* + * Если нет РЅРё РѕРґРЅРѕРіРѕ преподавателя, то ругаемся РІ логи Рё пропускаем дисциплину РґРѕ лучших времен + */ + if ( !isset($data->teacherIDs) || count($data->teacherIDs) == 0 ) { + Log::instance()->add(Log::WARNING, "A discipline without teachers is arrived: {0}", + array( + '{0}' => print_r($data, TRUE) + ) + ); + return null; + } + + switch ($data->type) { + case 'Ркзамен': + $data->type = Model_Discipline::EXAM; + break; + case 'Зачет': + $data->type = Model_Discipline::CREDIT; + break; + default: + Log::instance()->add(Log::WARNING, "A discipline has incorrect type: {0}", + array( + '{0}' => print_r($data, TRUE) + ) + ); + return null; + } + + return $data; + } + + private function normalizeStudyPlanData($data) { + if ( !isset($data->id) && isset($data->externalID) ) { + $ID = Model_Plan::withExternalID($data->externalID); + if ( $ID != -1 ) + $data->id = $ID; + } + + foreach ($data->disciplines as &$discipline) { + $discipline = $this->normalizeDisciplinesData($discipline); + } + + return $data; + } + + private function createStudyPlan($data) { + try { + + } catch (InvalidArgumentException $e) { + $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + } + return []; + } + + private function updateStudyPlan($data) { + $res = []; + try { + foreach ($data->disciplines as $discipline) { + if ( $discipline == null ) + continue; + + if ( isset($discipline->id) ) { + // ToDo: update discipline + } else { + print_r($discipline); + + $plan = Model_Plan::load($data->id); + $facultyID = $plan->FacultyID; + $semesterID = $plan->SemesterID; + $gradeID = $plan->GradeID; + + + $newSubjectID = Model_Subject::create($discipline->name, '', $facultyID); + + $newDiscipline = Model_Discipline::make(); + $newDiscipline->author($discipline->teacherIDs[0]); + $newDiscipline->subject($newSubjectID); + $newDiscipline->type($discipline->type); + $newDiscipline->semester($semesterID); + $newDiscipline->faculty($facultyID); + $newDiscipline->grade($gradeID); + $newDiscipline = $newDiscipline->create(); + $res[] = $newDiscipline->ID; + } + } + } catch (InvalidArgumentException $e) { + $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + } + return $res; + } + + private function processData($data) { + $data = $this->normalizeStudyPlanData($data); + if ($data->id != -1) { + return $this->updateStudyPlan($data); + } else { + return $this->createStudyPlan($data); + } + } + + /** + * @api {put} api/v0/studyPlan Add new study plan(s) + * @apiName Add new study plan + * @apiGroup Study plans + * @apiVersion 0.1.2 + * @apiParam {String} token Api key + * @apiParam {String} [batch] Flag about massive addition + * @apiParam {String} externalId + * @apiParam {Array} disciplines + */ + public function action_put_index() { + try { + if ( $this->request->query('batch') !== NULL ) { + $data = json_decode($this->request->body()); + + $res = []; + foreach ($data as $item) { + $res[] = $this->processData($item); + } + } else { + $data = $this->request->query(); + $res[] = $this->processData($data); + } + } catch (Exception $e) { + $this->badRequestError($e->getMessage()); + } + + return $res; + } +} diff --git a/~dev_rating/application/classes/Controller/Api/V0/Teacher.php b/~dev_rating/application/classes/Controller/Api/V0/Teacher.php index f22ec664f..7ae33e251 100644 --- a/~dev_rating/application/classes/Controller/Api/V0/Teacher.php +++ b/~dev_rating/application/classes/Controller/Api/V0/Teacher.php @@ -2,32 +2,6 @@ class Controller_Api_V0_Teacher extends Controller_Handler_Api { - private function makeErrorMsg($data, $msg) { - $dt = print_r($data, true); - $res = 'Невозможно загрузить/обновить преподавателя. '.$msg.":\n ".$dt; - return $res; - } - - private function getDepIDByName($name) { - try { - $id = Model_Faculties::getDepartmentIdByName($name); - } - catch (InvalidArgumentException $e) { - return NULL; - } - return $id; - } - - private function getDepIDByExternalID($departmentExternalID) { - try { - $id = Model_Faculties::getDepartmentIdByExternalID($departmentExternalID); - } - catch (InvalidArgumentException $e) { - return NULL; - } - return $id; - } - private function normalizeTeacherData($data) { if ( !isset($data->id) && isset($data->externalID) ) { $ID = Model_Teacher::withExternalID($data->externalID); @@ -107,7 +81,7 @@ class Controller_Api_V0_Teacher extends Controller_Handler_Api } $teacher = $teacher->create(); } catch (InvalidArgumentException $e) { - $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + $this->badRequestError( $this->makeErrorMsg($data, 'Невозможно загрузить/обновить преподавателя. '.$e->getMessage()) ); } return ['ID' => $teacher->ID , 'lastName' => $data->lastName @@ -122,7 +96,7 @@ class Controller_Api_V0_Teacher extends Controller_Handler_Api $data->jobPositionID, $data->departmentID, $data->status ); } catch (InvalidArgumentException $e) { - $this->badRequestError( $this->makeErrorMsg($data, $e->getMessage()) ); + $this->badRequestError( $this->makeErrorMsg($data, 'Невозможно загрузить/обновить преподавателя. '.$e->getMessage()) ); } } diff --git a/~dev_rating/application/classes/Controller/Handler/Api.php b/~dev_rating/application/classes/Controller/Handler/Api.php index 2db2726ba..a8765636e 100644 --- a/~dev_rating/application/classes/Controller/Handler/Api.php +++ b/~dev_rating/application/classes/Controller/Handler/Api.php @@ -158,4 +158,43 @@ abstract class Controller_Handler_Api extends Controller [':uri' => $this->request->uri()] )->request($this->request); } + + protected function makeErrorMsg($data, $msg) { + $dt = print_r($data, true); + $res = $msg.":\n ".$dt; + return $res; + } + + /** + * Aux section. It should be extracted somewhere + */ + protected function getDepIDByName($name) { + try { + $id = Model_Faculties::getDepartmentIdByName($name); + } + catch (InvalidArgumentException $e) { + return NULL; + } + return $id; + } + + protected function getDepIDByExternalID($departmentExternalID) { + try { + $id = Model_Faculties::getDepartmentIdByExternalID($departmentExternalID); + } + catch (InvalidArgumentException $e) { + return NULL; + } + return $id; + } + + protected function getFacultyIDByExternalID($facultyExternalID) { + try { + $id = Model_Faculties::getIdByExternalID($facultyExternalID); + } + catch (InvalidArgumentException $e) { + return NULL; + } + return $id; + } } \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Discipline.php b/~dev_rating/application/classes/Model/Discipline.php index bd3e68a19..610c53a23 100644 --- a/~dev_rating/application/classes/Model/Discipline.php +++ b/~dev_rating/application/classes/Model/Discipline.php @@ -92,6 +92,14 @@ class Model_Discipline extends Model_Container DB::query(Database::SELECT, $sql)->param(':id', $this->ID)->execute(); } + public static function withExternalID($extid) { + $sql = 'SELECT `Discipline_GetIDFromExternalID`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } + // todo: should return Model_Group[] public function getGroups() { $sql = 'CALL `GetGroupsForDiscipline`(:id)'; diff --git a/~dev_rating/application/classes/Model/Faculties.php b/~dev_rating/application/classes/Model/Faculties.php index 93a9dc736..0ae0d298c 100644 --- a/~dev_rating/application/classes/Model/Faculties.php +++ b/~dev_rating/application/classes/Model/Faculties.php @@ -72,6 +72,18 @@ class Model_Faculties extends Model return $id->get('ID'); } + public static function getIdByExternalID($facultyExternalID) { + $sql = 'CALL `Faculty_GetIdByExternalID`(:depExternalID)'; + $id = DB::query(Database::SELECT, $sql) + ->param(':depExternalID', $facultyExternalID) + ->execute(); + + if ($id->count() == 0) + throw new InvalidArgumentException(Error::DEPARTMENT_NOT_FOUND); + + return $id->get('ID'); + } + public static function createDepartment($departmentName, $facultyID) { $sql = 'SELECT `Department_Create`(:name, :facultyID) AS `ID`;'; $id = DB::query(Database::SELECT, $sql) diff --git a/~dev_rating/application/classes/Model/Helper/DisciplineBuilder.php b/~dev_rating/application/classes/Model/Helper/DisciplineBuilder.php index c5e2f51b6..8b1f79065 100644 --- a/~dev_rating/application/classes/Model/Helper/DisciplineBuilder.php +++ b/~dev_rating/application/classes/Model/Helper/DisciplineBuilder.php @@ -7,6 +7,9 @@ class Model_Helper_DisciplineBuilder extends Model_Helper_Builder 'Subtype' => null, 'IsLocked' => false, 'Milestone' => 0, + 'Lectures' => 0, + 'Practice' => 0, + 'Labs' => 0 ]; $required = [ diff --git a/~dev_rating/application/classes/Model/Helper/PlanBuilder.php b/~dev_rating/application/classes/Model/Helper/PlanBuilder.php new file mode 100644 index 000000000..3c98e3cd3 --- /dev/null +++ b/~dev_rating/application/classes/Model/Helper/PlanBuilder.php @@ -0,0 +1,17 @@ +<?php + +class Model_Helper_PlanBuilder extends Model_Helper_Builder +{ + public function create() { + $this->data += [ + + ]; + + $required = []; + + if (array_diff($required, array_keys($this->data))) + throw new InvalidArgumentException('Not enough arguments'); + + return new Model_Plan($this->data, false); + } +} diff --git a/~dev_rating/application/classes/Model/Helper/RecordBookBuilder.php b/~dev_rating/application/classes/Model/Helper/RecordBookBuilder.php new file mode 100644 index 000000000..e7ee3a38e --- /dev/null +++ b/~dev_rating/application/classes/Model/Helper/RecordBookBuilder.php @@ -0,0 +1,44 @@ +<?php + +class Model_Helper_RecordBookBuilder extends Model_Helper_Builder +{ + public function create() { + $required = [ + 'StudentID', 'PlanID', 'FacultyID', + ]; + + if (array_diff($required, array_keys($this->data))) + throw new InvalidArgumentException('Not enough arguments'); + + return new Model_RecordBook($this->data, false); + } + + + public function & studentID($id) { + if (!is_numeric($id) || $id <= 0) + throw new InvalidArgumentException('student id is incorrect'); + $this->data['StudentID'] = (int) $id; + return $this; + } + + public function & planID($id) { + if (!is_numeric($id) || $id <= 0) + throw new InvalidArgumentException('plan id is incorrect'); + $this->data['PlanID'] = (int) $id; + return $this; + } + + public function & facultyID($id) { + if (!is_numeric($id) || $id <= 0) + throw new InvalidArgumentException('Faculty id is incorrect'); + $this->data['FacultyID'] = (int) $id; + return $this; + } + + public function & externalID($id) { + $id = trim($id); + + $this->data['ExternalID'] = (int) $id; + return $this; + } +} diff --git a/~dev_rating/application/classes/Model/Plan.php b/~dev_rating/application/classes/Model/Plan.php new file mode 100644 index 000000000..47f63fd29 --- /dev/null +++ b/~dev_rating/application/classes/Model/Plan.php @@ -0,0 +1,61 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +/** + * Class Model_Plan + * + * @property-read $ID int + * @property $ExternalID string + * @property $FacultyID int + * @property $SemesterID int + * @property $GradeID int + */ +class Model_Plan extends Model_Container +{ + protected function getRawData($id) { + $sql = 'CALL `Plan_GetInfo`(:id)'; + $info = DB::query(Database::SELECT, $sql) + ->param(':id', $id)->execute(); + + if ($info->count() == 0) + throw new InvalidArgumentException('Study plan not found'); + + return $info->offsetGet(0); + } + + public static function make() { + return new Model_Helper_PlanBuilder(); + } + + protected function create() { +// $sql = 'SELECT `CreateStudentGroupSearch`(LastName, FirstName, SecondName, GradeID, GroupNum, FacultyID, ActivationCode, SemesterID) AS `ID`'; +// +// $this->data[self::$ID_FIELD] = DB::query(Database::SELECT, $sql) +// ->parameters($this->data) +// ->execute()->get('ID'); +// +// if ($this->ID <= 0) +// throw new InvalidArgumentException(Error::INVALID_PARAMETERS); + } + + public static function withExternalID($extid) { + $sql = 'SELECT `Plan_GetIDFromExternalID`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } + + /** @return Model_Discipline[] */ + public function getDisciplines($semesterID = null) { + throw new BadMethodCallException('Method is not implemented yet!'); + } + + public function getTeachers($loadAll = false, $semesterID = null) { + throw new BadMethodCallException('Method is not implemented yet!'); + } + + // todo implementation + public function update() { + throw new BadMethodCallException('Method is not implemented yet!'); + } +} diff --git a/~dev_rating/application/classes/Model/RecordBook.php b/~dev_rating/application/classes/Model/RecordBook.php new file mode 100644 index 000000000..9c6bc8a2d --- /dev/null +++ b/~dev_rating/application/classes/Model/RecordBook.php @@ -0,0 +1,135 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +/** + * Class Model_RecordBook + * + * @property-read $ID int + * @property $ExternalID string + * @property $PlanID int + * @property $SubdivisionID int + * @property $Status string + * @property $GroupID int + * @property $GroupNum int + * @property $GroupName string + * @property $GradeID int + * @property $GradeNum int + * @property $Degree string + * @property $SpecID int + * @property $SpecName string + * @property $SpecAbbr string + * @property $SpecCode string + * @property $FacultyID int + * @property $FacultyName string + * @property $FacultyAbbr string + */ +class Model_RecordBook extends Model_Container +{ + protected function getRawData($id) { +// $sql = 'CALL `Student_GetInfo`(:id)'; +// $info = DB::query(Database::SELECT, $sql) +// ->param(':id', $id)->execute(); +// +// if ($info->count() == 0) +// throw new InvalidArgumentException('Student not found'); +// +// $sql = 'CALL `Student_GetRecordBooks`(:id)'; +// $res = DB::query(Database::SELECT, $sql) +// ->param(':id', $id)->execute()->as_array(); +// +// $recordBooks = []; +// foreach ($res as $recordBook) +// $recordBooks[$recordBook['ID']] = $recordBook; +// +// return array_merge($info[0], array('RecordBooks' => $recordBooks)); + throw new HTTP_Exception_500("Not implemented"); + } + + public static function make() { + return new Model_Helper_RecordBookBuilder(); + } + + protected function create() { + $sql = 'SELECT `RecordBook_Create`(ExternalID, StudentID, PlanID, FacultyID) AS `ID`'; + + $this->data[self::$ID_FIELD] = DB::query(Database::SELECT, $sql) + ->parameters($this->data) + ->execute()->get('ID'); + + if ($this->ID <= 0) + throw new InvalidArgumentException(Error::INVALID_PARAMETERS); + } + + public static function withExternalID($extid) { + $sql = 'SELECT `RecordBook_GetIDFromExternalID`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } + + /** @return Model_Discipline[] */ + public function getDisciplines($semesterID = null) { + $semesterID = $semesterID ?: User::instance()->SemesterID; + $recordBookID = $this->ID; + + $sql = 'CALL `Student_GetDisciplines`(:recordBookID, :semesterID)'; + $query = DB::query(Database::SELECT, $sql) + ->param(':recordBookID', $recordBookID) + ->param(':semesterID', $semesterID) + ->execute(); + + $list = []; + foreach ($query as $data) + $list[] = new Model_Discipline($data, true); + + return $list; + } + + public function getTeachers($loadAll = false, $semesterID = null) { + // todo: don't load the full data at the Controller_Student_Index + $semesterID = $semesterID ?: User::instance()->SemesterID; + $recordBookID = $this->ID; + + $sql = 'CALL `Student_GetTeachersList`(:recordBookID, :semesterID, :loadAll)'; + $result = DB::query(Database::SELECT, $sql) + ->param(':recordBookID', $recordBookID) + ->param(':semesterID', $semesterID) + ->param(':loadAll', $loadAll) + ->execute(); + + $list = []; + foreach ($result as $row) { + $id = $row['DisciplineID']; + $list[$id][] = $row; + } + return $list; + } + + // todo implementation + public function update() { + throw new BadMethodCallException('Method is not implemented yet!'); + } + + /** + * Set the student's state and group in a semester. + * @param $group int group id + * @return $this; + */ + public function setState($group, $state="common", $semesterID = null) { + $semesterID = $semesterID ?: User::instance()->SemesterID;; + $sql = 'SELECT `ControlStudentGroup`(:id, :group, :state, :semesterID) AS Result'; + + DB::query(Database::SELECT, $sql) + ->param(':id', $this->ID) + ->param(':group', (int) $group) + ->param(':state', $state) + ->param(':semesterID', $semesterID) + ->execute(); + + return $this; + } + + public function transferIntoGroup($group, $semesterID = null) { + return $this->setState($group, "common", $semesterID); + } +} diff --git a/~dev_rating/application/classes/Model/Student.php b/~dev_rating/application/classes/Model/Student.php index 0ca7262ae..ab046fae8 100644 --- a/~dev_rating/application/classes/Model/Student.php +++ b/~dev_rating/application/classes/Model/Student.php @@ -84,7 +84,15 @@ class Model_Student extends Model_Container return $response == -1 ? -1 : $code; } - + + public static function withExternalID($extid) { + $sql = 'SELECT `Student_GetIDFromExternalID`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } + /** @return Model_Discipline[] */ public function getDisciplines($semesterID = null, $recordBookID = null) { $semesterID = $semesterID ?: User::instance()->SemesterID; diff --git a/~dev_rating/application/classes/Model/Subject.php b/~dev_rating/application/classes/Model/Subject.php index 3bb8f6354..832c931a4 100644 --- a/~dev_rating/application/classes/Model/Subject.php +++ b/~dev_rating/application/classes/Model/Subject.php @@ -35,7 +35,6 @@ class Model_Subject return self::MARK_A; } - public static function create($name, $abbr, $facultyID) { $sql = 'SELECT `CreateSubject`(:faculty, :name, :abbr) AS `Num`'; $res = DB::query(Database::SELECT, $sql) @@ -47,4 +46,12 @@ class Model_Subject return (int) $res->get('Num'); } + + public static function withExternalID($extid) { + $sql = 'SELECT `Plan_GetIDFromExternalID`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } } diff --git a/~dev_rating/application/classes/Model/Teacher.php b/~dev_rating/application/classes/Model/Teacher.php index 1161f186c..7efcec091 100644 --- a/~dev_rating/application/classes/Model/Teacher.php +++ b/~dev_rating/application/classes/Model/Teacher.php @@ -56,6 +56,14 @@ class Model_Teacher extends Model_Container return $res; } + public static function withINILA($extid) { + $sql = 'SELECT `Teacher_GetIDFromINILA`(:ExtID) AS `ID`'; + $res = DB::query(Database::SELECT, $sql) + ->param(':ExtID', $extid) + ->execute()->get('ID'); + return $res; + } + protected function create() { if ( isset($this->data['ExternalID']) ) { $sql = 'SELECT `Teacher_CreateActivated`(LastName, FirstName, SecondName, JobPositionID, DepID, ExternalID, INILA) AS `ID`'; diff --git a/~dev_rating/application/routes/api/v0.php b/~dev_rating/application/routes/api/v0.php index c118e9012..6eddb79d8 100644 --- a/~dev_rating/application/routes/api/v0.php +++ b/~dev_rating/application/routes/api/v0.php @@ -128,4 +128,17 @@ Route::set('apiv0:subject:another', 'api/v0/subject/<action>(/<id>)', ['id' => ' 'action' => 'index', 'directory' => 'Api/V0', 'controller' => 'Subject', + ]); + +Route::set('apiv0:studyPlan', 'api/v0/studyPlan') + ->filter(function($route, $params, $request) + { + // Prefix the method to the action name + $params['action'] = strtolower($request->method()).'_'.$params['action']; + return $params; // Returning an array will replace the parameters + }) + ->defaults([ + 'action' => 'index', + 'directory' => 'Api/V0', + 'controller' => 'StudyPlan', ]); \ No newline at end of file diff --git a/~dev_rating/application/views/office/sync.twig b/~dev_rating/application/views/office/sync.twig index 5f7208eaa..cb8b3c337 100644 --- a/~dev_rating/application/views/office/sync.twig +++ b/~dev_rating/application/views/office/sync.twig @@ -20,11 +20,12 @@ </div> <div> - <button class="defaultForm GreenButton" id="syncStudents">Синхронизировать студентов</button> + <button class="defaultForm GreenButton" id="syncPlans">Синхронизировать учебные планы</button> </div> <div> - <button class="defaultForm GreenButton" id="syncPlans">Синхронизировать учебные планы</button> + <button class="defaultForm GreenButton" id="syncStudents">Синхронизировать студентов</button> + </div> <div> -- GitLab