diff --git a/db/migrations/stored/R__functions.sql b/db/migrations/stored/R__functions.sql index 85b866306b9b8c493b7c3cc4b6f896eae05e4d86..562f2b1adac93425a2233c1b3d8a7542b981e909 100644 --- a/db/migrations/stored/R__functions.sql +++ b/db/migrations/stored/R__functions.sql @@ -162,33 +162,36 @@ DROP FUNCTION IF EXISTS CreateGroup// CREATE FUNCTION CreateGroup ( pGradeID INT, pGroupNum INT, - pSpecializationID INT, - pGroupName VARCHAR(50) CHARSET utf8, + pSpecName VARCHAR(200) CHARSET utf8, + pFacultyID INT, pYear INT ) RETURNS int(11) # group id NO SQL BEGIN - DECLARE vGroupID, vFacultyID, vGroupYear, vIsSpecMatch INT DEFAULT -1; + DECLARE vGroupID, vSpecId, vGroupYear, vIsSpecMatch INT DEFAULT -1; DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; - SET vFacultyID = (SELECT FacultyID FROM specializations WHERE specializations.ID = pSpecializationID LIMIT 1); + # create specialization + INSERT INTO specializations (Name, Abbr, FacultyID) VALUES (pSpecName, NULL, pFacultyID) + ON DUPLICATE KEY UPDATE + specializations.ID = LAST_INSERT_ID(specializations.ID); + SET vSpecId = LAST_INSERT_ID(); - # create discipline - INSERT INTO study_groups (GradeID, GroupNum, FacultyID) VALUES (pGradeID, pGroupNum, vFacultyID) + # create group + INSERT INTO study_groups (GradeID, GroupNum, FacultyID) VALUES (pGradeID, pGroupNum, pFacultyID) ON DUPLICATE KEY UPDATE study_groups.ID = LAST_INSERT_ID(study_groups.ID); SET vGroupID = LAST_INSERT_ID(); - SELECT groups_years.GroupID, (groups_years.SpecializationID = pSpecializationID AND - (pGroupName IS NULL OR groups_years.Name <=> pGroupName)) + SELECT groups_years.GroupID, groups_years.SpecializationID = vSpecId INTO vGroupYear, vIsSpecMatch FROM groups_years WHERE groups_years.GroupID = vGroupID AND groups_years.Year = pYear LIMIT 1; IF vGroupYear = -1 THEN - INSERT INTO groups_years (GroupID, Year, SpecializationID, Name) - VALUES (vGroupID, pYear, pSpecializationID, pGroupName); + INSERT INTO groups_years (GroupID, Year, SpecializationID) + VALUES (vGroupID, pYear, vSpecId); ELSEIF NOT vIsSpecMatch THEN RETURN -1; END IF; @@ -245,7 +248,10 @@ BEGIN # create/get subject (subject name is unique key) INSERT INTO subjects (Name, Abbr, ExternalID) VALUES (pSubjectName, pSubjectAbbr, pExternalID) ON DUPLICATE KEY UPDATE - subjects.ID = LAST_INSERT_ID(subjects.ID); + subjects.ID = LAST_INSERT_ID(subjects.ID), + subjects.Name = pSubjectName, + subjects.Abbr = COALESCE(pSubjectAbbr, subjects.Abbr), + subjects.ExternalID = COALESCE(pExternalID, subjects.ExternalID); SET vSubjectID = LAST_INSERT_ID(); BEGIN # handler block @@ -719,18 +725,12 @@ CREATE FUNCTION CreateStudentEx ( ) RETURNS int(11) NO SQL BEGIN - DECLARE vAccountID, vGradeID, vSpecID, vGroupID, vYear INT DEFAULT -1; + DECLARE vGradeID, vGroupID, vYear INT DEFAULT -1; DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; - # get specialization id - INSERT INTO specializations (Name, Abbr, FacultyID) VALUES (pSpecName, NULL, pFacultyID) - ON DUPLICATE KEY UPDATE - specializations.ID = LAST_INSERT_ID(specializations.ID); - SET vSpecID = LAST_INSERT_ID(); - SET vYear = COALESCE((SELECT Year FROM semesters WHERE semesters.ID = pSemesterID LIMIT 1), -1); SET vGradeID = CreateGrade(pGradeNum, pDegree); - SET vGroupID = CreateGroup(vGradeID, pGroupNum, vSpecID, NULL, vYear); + SET vGroupID = CreateGroup(vGradeID, pGroupNum, pSpecName, pFacultyID, vYear); RETURN CreateStudent(pLastName, pFirstName, pSecondName, vGroupID, pActivationCode, pSemesterID); END // diff --git a/media/less/common.less b/media/less/common.less index b1f1c3ca1405900a0475f9ac26a407d0572859b7..633ce67ed3d109c8aa22d381556a3cd26ba3d86d 100644 --- a/media/less/common.less +++ b/media/less/common.less @@ -238,12 +238,9 @@ input[type="checkbox"] { display: inline; text-align: right; float: right; - > div { + > * { display: inline-block; - margin: 0 5px; - } - a { - margin-left: 5px; + margin-left: 10px; } } } @@ -342,23 +339,38 @@ input[type="checkbox"] { } .semesterLayer { + position: relative; display: inline-block; width: auto; - .semesterChanger, .semesterSwitcherBtn { - //margin-left: 0px; - font-family: @FontFamily; - font-size: 1em; + text-align: left; + font-family: @FontFamily; + font-size: 1em; + + .semesterChanger { + text-align: right; + + > * { + position: relative; + display: inline-block; + + &:not(:last-child) { + margin-right: 5px; + } + } } + .semesterSwitcher { display: block; padding: 10px; overflow: hidden; .modalWindow(auto); + min-width: 160px; margin-top: 5px; background: @ColorBaseWhite; border: 1px solid @ColorBaseGrey; .box-shadow(0 0 5px, @ColorGrey); .radius(5px); + li { margin-bottom: 5px; &:last-child { margin-bottom: 0; } @@ -371,22 +383,35 @@ input[type="checkbox"] { display: inline-block; width: auto; text-align: left; - .recordBookChanger, .recordBookSwitcherBtn { - //margin-left: 0px; - font-family: @FontFamily; - font-size: 1em; + font-family: @FontFamily; + font-size: 1em; + + .recordBookChanger { + text-align: right; + + > * { + position: relative; + display: inline-block; + + &:not(:last-child) { + margin-right: 5px; + } + } } + .recordBookSwitcher { display: block; padding: 10px; overflow: hidden; .modalWindow(auto); right: 0; + min-width: 160px; margin-top: 5px; background: @ColorBaseWhite; border: 1px solid @ColorBaseGrey; .box-shadow(0 0 5px, @ColorGrey); .radius(5px); + li { margin-bottom: 5px; &:last-child { margin-bottom: 0; } diff --git a/media/less/js/event_inspector.less b/media/less/js/event_inspector.less index 2083b25833fffbbc74fe3b8dcb90dc50648e655c..f47b49a6abce045b07af60bbf3524855399e2d18 100644 --- a/media/less/js/event_inspector.less +++ b/media/less/js/event_inspector.less @@ -3,6 +3,7 @@ .EventInspectorList { position: fixed; + z-index: 10000; height: auto; min-width: 200px; width: 15%; diff --git a/media/less/student/index.less b/media/less/student/index.less index efcf02dd871c3c7a4f197ed23bfc679d06285a7b..200ff2103eb04d9c0db13b76c21d6275be7b2f6c 100644 --- a/media/less/student/index.less +++ b/media/less/student/index.less @@ -111,12 +111,45 @@ .header_wrapper { padding: 9pt 10px; + + .logotype { + margin-right: 10px; + } .logotype span, #username { display: none; } } - + + .semesterLayer { + .semesterChangerTitle { + display: none; + } + } + + .recordBookLayer { + .recordBookChangerTitle { + display: none; + } + + .recordBookChangerSelection { + width: calc(~"100vw - 235px"); + overflow: hidden; + white-space: nowrap; + direction: rtl; + + &:before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 10px; + height: 100%; + background: linear-gradient(to right, @ColorBaseWhite, fade(@ColorBaseWhite, 0%)); + } + } + } + div.window { min-width: initial !important; diff --git a/media/less/student/subject.less b/media/less/student/subject.less index afb65318d3f88ced536ebc2dbebb70568b71ca1d..426a1bdf2a340d020adaae691eaa8915cc5d8fa8 100644 --- a/media/less/student/subject.less +++ b/media/less/student/subject.less @@ -164,11 +164,44 @@ h3.blockTitle .header_wrapper { padding: 9pt 10px; + .logotype { + margin-right: 10px; + } + .logotype span, #username { display: none; } } + .semesterLayer { + .semesterChangerTitle { + display: none; + } + } + + .recordBookLayer { + .recordBookChangerTitle { + display: none; + } + + .recordBookChangerSelection { + width: calc(~"100vw - 235px"); + overflow: hidden; + white-space: nowrap; + direction: rtl; + + &:before { + content: ''; + position: absolute; + left: 0; + top: 0; + width: 10px; + height: 100%; + background: linear-gradient(to right, @ColorBaseWhite, fade(@ColorBaseWhite, 0%)); + } + } + } + div.window { min-width: initial !important; diff --git a/~dev_rating/application/classes/Controller/Api/V0/Student.php b/~dev_rating/application/classes/Controller/Api/V0/Student.php index 29e32c19d9fd2aff0ef530ba538428ee66abb9ba..59fedd5837036db1038f1bdeda2ae17943d2c1d6 100644 --- a/~dev_rating/application/classes/Controller/Api/V0/Student.php +++ b/~dev_rating/application/classes/Controller/Api/V0/Student.php @@ -167,7 +167,14 @@ class Controller_Api_V0_Student extends Controller_Handler_Api { throw new InvalidArgumentException('RecordBook: grade not found'); } - $group = Model_Group::find($gradeID, $recordBookData->group, $recordBookData->facultyID); + $speciality = $recordBookData->speciality; + if (strpos($speciality, ' - ') == 8) { + $speciality = substr($speciality, 11); + } + + $year = Model_Plan::load($recordBookData->planID)->Year; + + $group = Model_Group::findOrCreate($gradeID, $recordBookData->group, $speciality, $recordBookData->facultyID, $year); if (is_null($group)) { throw new InvalidArgumentException('RecordBook: group not found'); } diff --git a/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php index fd256db602ffc3684b9effccbf95df05409931de..d959226b0657dfa219d705ce225ad980a29439ae 100644 --- a/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php +++ b/~dev_rating/application/classes/Controller/Api/V0/StudyPlan.php @@ -2,10 +2,6 @@ class Controller_Api_V0_StudyPlan extends Controller_Handler_Api { private function normalizeDisciplinesData($disciplineData, $facultyID) { - if (!isset($disciplineData->subjectID) && isset($disciplineData->externalID)) { - $disciplineData->subjectID = Model_Subject::withExternalID($disciplineData->externalID, $disciplineData->name, '', $facultyID); - } - foreach ($disciplineData->teachers as $teacherData) { if (empty($teacherData->hashSnils)) { Log::instance()->add(Log::WARNING, '{0} {1}: {2}', array( @@ -22,13 +18,7 @@ class Controller_Api_V0_StudyPlan extends Controller_Handler_Api { } if (empty($disciplineData->teacherIDs)) { - if (!empty($disciplineData->teachers)) { - Log::instance()->add(Log::WARNING, '{0} {1}: {2}', array( - '{0}' => 'SYNC_DISCIPLINES', - '{1}' => 'Discipline without teachers', - '{2}' => json_encode($disciplineData), - )); - } + throw new InvalidArgumentException('Discipline without teachers'); } switch ($disciplineData->type) { @@ -45,6 +35,10 @@ class Controller_Api_V0_StudyPlan extends Controller_Handler_Api { throw new InvalidArgumentException('Discipline has bad type'); } + if (!isset($disciplineData->subjectID) && isset($disciplineData->externalID)) { + $disciplineData->subjectID = Model_Subject::withExternalID($disciplineData->externalID, $disciplineData->name, NULL, $facultyID); + } + return $disciplineData; } diff --git a/~dev_rating/application/classes/Model/Group.php b/~dev_rating/application/classes/Model/Group.php index f4c759360b5649b297d60e815dd6a724f01baf38..e7d65539e0eeb9f805bfa326d4af221752350f51 100644 --- a/~dev_rating/application/classes/Model/Group.php +++ b/~dev_rating/application/classes/Model/Group.php @@ -14,12 +14,14 @@ class Model_Group extends Model return $g; } - public static function find($gradeID, $groupNum, $facultyID) { - $sql = 'SELECT `FindGroup`(:gradeID, :groupNum, :facultyID) AS `ID`'; + public static function findOrCreate($gradeID, $groupNum, $specialization, $facultyID, $year) { + $sql = 'SELECT `CreateGroup`(:gradeID, :groupNum, :specialization, :facultyID, :year) AS `ID`'; $id = DB::query(Database::SELECT, $sql) ->param(':gradeID', $gradeID) ->param(':groupNum', $groupNum) + ->param(':specialization', $specialization) ->param(':facultyID', $facultyID) + ->param(':year', $year) ->execute()->get('ID'); if ($id <= 0) { return null; diff --git a/~dev_rating/application/classes/Model/Subject.php b/~dev_rating/application/classes/Model/Subject.php index 282b8b9145ad44a4cfc6b83352ba30f706aa3372..b7fa868f63c4999eec56d5c26b31e59f0fdfddf9 100644 --- a/~dev_rating/application/classes/Model/Subject.php +++ b/~dev_rating/application/classes/Model/Subject.php @@ -48,7 +48,7 @@ class Model_Subject return (int) $res->get('Num'); } - public static function withExternalID($extID, $name='', $abbr='', $facultyID=null) { + public static function withExternalID($extID, $name, $abbr, $facultyID) { $sql = 'SELECT `Subject_GetByExternalID`(:extID) AS `ID`'; $id = DB::query(Database::SELECT, $sql) ->param(':extID', $extID) diff --git a/~dev_rating/application/views/base.twig b/~dev_rating/application/views/base.twig index 9da3ef83619c68d4453c3a248c68dbffb45dc150..3b4536867fa15b1bbf5f5d3ff4ff3a3824f7b012 100644 --- a/~dev_rating/application/views/base.twig +++ b/~dev_rating/application/views/base.twig @@ -17,7 +17,8 @@ {% macro SemesterSwitcher(SemesterList) %} <a href="#" id="changeSemester" class="semesterChanger" title="Сменить семестр"> {% set Semester = SemesterList[User.SemesterID] %} - Семестр: {{ Rus[Semester.Season] }} {{ Semester.Num == 1 ? Semester.Year : (Semester.Year + 1) }} + <span class="semesterChangerTitle">Семестр:</span> + <span class="semesterChangerSelection">{{ Rus[Semester.Season] }} {{ Semester.Num == 1 ? Semester.Year : (Semester.Year + 1) }}</span> <i class="fa fa-angle-down"></i> </a> <div class="semesterSwitcherBtn"> @@ -34,7 +35,8 @@ {% macro RecordBookSwitcher(RecordBookList) %} <a href="#" id="changeRecordBook" class="recordBookChanger" title="Сменить зачетку"> {% set RecordBook = RecordBookList[User.RecordBookID] %} - Зачетка: {{ RecordBook.ExternalID }} + <span class="recordBookChangerTitle">Зачетка:</span> + <span class="recordBookChangerSelection">{{ RecordBook.ExternalID }}</span> <i class="fa fa-angle-down"></i> </a> <div class="recordBookSwitcherBtn">