diff --git a/db/StoredProcedures.sql b/db/StoredProcedures.sql
index d8ec988cfa791a6f745d3636b3db252c216e7af3..a13e4a953247f073713a998d5fff68d29c8304d3 100644
--- a/db/StoredProcedures.sql
+++ b/db/StoredProcedures.sql
@@ -2148,7 +2148,8 @@ BEGIN
 			faculties.ID					AS 'FacultyID',
 			faculties.Name 					AS 'FacultyName',
 			disciplines.isLocked 			AS 'isLocked',
-			(modules.ID IS NOT NULL) 		AS 'isBonus' 
+			(modules.ID IS NOT NULL) 		AS 'isBonus',
+			disciplines.isMilestone
 	FROM `disciplines`
 	INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID
 	INNER JOIN `faculties` ON faculties.ID = disciplines.FacultyID
@@ -2850,6 +2851,43 @@ END //
 
 
 
+DROP FUNCTION IF EXISTS RestrictAfterMilestone//
+CREATE FUNCTION `RestrictAfterMilestone`	(	`TeacherID` 	INT,
+												`DisciplineID` 	INT
+			 								) 	RETURNS int(11)
+    NO SQL
+BEGIN 				 
+
+	UPDATE `disciplines`
+	SET disciplines.MilestoneDate = CURDATE(),
+		disciplines.isMilestone = 1
+	WHERE disciplines.ID = DisciplineID
+	LIMIT 1;
+
+	RETURN 0;
+END //
+
+
+
+DROP FUNCTION IF EXISTS RestrictAfterMilestoneForCredits//
+CREATE FUNCTION `RestrictAfterMilestoneForCredits`	(	`TeacherID` 	INT,
+														`FacultyID` 	INT
+													) 	RETURNS int(11)
+    NO SQL
+BEGIN 	
+	DECLARE semID INT;
+
+	SET semID = GetCurSemesterID();
+	
+	UPDATE `disciplines`
+	SET disciplines.MilestoneDate = CURDATE(),
+		disciplines.isMilestone = 1
+	WHERE 	disciplines.SemesterID = semID AND
+			disciplines.ExamType = 'credit';
+
+	RETURN 0;
+END //
+
 -- -------------------------------------------------------------------------------------------
 -- Label: modules
 -- -------------------------------------------------------------------------------------------
@@ -3566,7 +3604,7 @@ CREATE FUNCTION `SetStudentRate`(	`TeacherID` 	INT,
 									RETURNS int(11)
     NO SQL
 BEGIN
-    DECLARE checker, DisciplineID, groupID, rateID, maxRate INT;
+    DECLARE checker, DisciplineID, groupID, rateID, maxRate, isOver, mtype INT;
     DECLARE isLocked, isUsed tinyint; 
 
 	SET groupID = -1;
@@ -3579,10 +3617,18 @@ BEGIN
 		RETURN -1;
 	END IF;					 
 
+	SET isOver = 1;
     SET isLocked = 0;
     SET DisciplineID = -1;
-    SELECT modules.DisciplineID, disciplines.isLocked, rating_table.StudentID, submodules.isUsed, submodules.MaxRate
-    INTO DisciplineID, isLocked, rateID, isUsed, maxRate
+    SET mtype = -1;
+    SELECT 	modules.DisciplineID, 
+    		disciplines.isLocked, 
+    		disciplines.isMilestone, 
+    		rating_table.StudentID, 
+    		submodules.isUsed, 
+    		submodules.MaxRate,
+    		modules.Type
+    INTO DisciplineID, isLocked, isOver, rateID, isUsed, maxRate, mtype
 	FROM `submodules`
 	INNER JOIN `modules` 				ON 	submodules.ModuleID = modules.ID
 	INNER JOIN `disciplines` 			ON 	modules.DisciplineID = disciplines.ID
@@ -3600,7 +3646,10 @@ BEGIN
 				disciplines_groups.ID IS NOT NULL
 			)
 	LIMIT 1;
-	IF DisciplineID <= 0 OR Rate > maxRate THEN
+	IF 	DisciplineID <= 0 OR 
+		Rate > maxRate OR 
+		(isOver > 0 AND (mtype = 1 OR mtype = 3))
+	THEN
 		RETURN -1;
 	END IF;
 
@@ -4043,36 +4092,47 @@ END //
 
 
 
-DROP PROCEDURE IF EXISTS GetRatesForStudentsGroup//
-CREATE PROCEDURE `GetRatesForStudentsGroup`	(	IN `TeacherID` INT,
-										IN `DisciplineID` INT,
-										IN `StudyGroupID` INT
-									)
+DROP PROCEDURE IF EXISTS GetDisciplinesForGroup//
+CREATE PROCEDURE `GetDisciplinesForGroup`	(	IN `GroupID` INT
+											)
     NO SQL
-BEGIN  				 
-    IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) 
-    THEN
-		SELECT 	NULL AS 'ID'
-		LIMIT 0;
-	ELSE
-		SELECT 	students.ID 	AS 'ID',
-				students.LastName			AS 'Last',
-				students.FirstName			AS 'First',
-				students.SecondName 		AS 'Second',
-				GetRateForDiscSemester(students.ID, DisciplineID) AS 'intermediate',
-				GetRateForDiscBonus(students.ID, DisciplineID) AS 'bonus'
-		FROM `students`
-		INNER JOIN `study_groups` ON study_groups.ID = students.StudyGroupID
-		-- LEFT JOIN `modules` ON 	modules.DisciplineID = DisciplineID AND
-		-- 						(modules.Type = 'exam' OR modules.Type = 'extra')	
-		-- LEFT JOIN `submodules` ON 	submodules.ModuleID = modules.ID
-		WHERE 	study_groups.ID = StudyGroupID AND 
-				InternalIsStudentAttached(students.ID, DisciplineID);
+BEGIN  		
+	SELECT disciplines_groups.DisciplineID
+	FROM `disciplines_groups`
+	WHERE disciplines_groups.StudyGroupID = GroupID 
+	UNION DISTINCT
+	SELECT disciplines_students.DisciplineID
+	FROM `disciplines_students`
+	INNER JOIN `students` ON disciplines_students.StudentID = students.ID
+	WHERE students.StudyGroupID = GroupID;
+
+END //
 
 
 
-		
-	END IF;
+DROP PROCEDURE IF EXISTS GetRatesForStudentsGroup//
+CREATE PROCEDURE `GetRatesForStudentsGroup`	(	IN `TeacherID` INT,
+                                                        IN `DisciplineID` INT,
+                                                        IN `StudyGroupID` INT
+                                                )
+    NO SQL
+BEGIN  		
+-- TODO: TeacherID deprecated		 
+	SELECT 	students.ID 	AS 'ID',
+			students.LastName			AS 'Last',
+			students.FirstName			AS 'First',
+			students.SecondName 		AS 'Second',
+			GetRateForDiscSemester(students.ID, DisciplineID) AS 'intermediate',
+			GetRateForDiscBonus(students.ID, DisciplineID) AS 'bonus'
+	FROM `students`
+	INNER JOIN `study_groups` ON study_groups.ID = students.StudyGroupID
+	-- LEFT JOIN `modules` ON 	modules.DisciplineID = DisciplineID AND
+	-- 						(modules.Type = 'exam' OR modules.Type = 'extra')	
+	-- LEFT JOIN `submodules` ON 	submodules.ModuleID = modules.ID
+	WHERE 	study_groups.ID = StudyGroupID AND 
+			InternalIsStudentAttached(students.ID, DisciplineID)
+	ORDER BY Last ASC;
+
 END //
 
 
diff --git a/db/Structure.sql b/db/Structure.sql
index 91cd7209e4121d8a5f300e5074c2301f0dce3024..d16e12a988788fa03370431453a701ff127b4764 100644
--- a/db/Structure.sql
+++ b/db/Structure.sql
@@ -90,7 +90,11 @@ CREATE TABLE IF NOT EXISTS `disciplines` (
   `LectionCount` int(11) NOT NULL DEFAULT '0',
   `LabCount` int(11) NOT NULL DEFAULT '0',
   `FacultyID` int(11) NOT NULL,
+  -- isLocked (for editing structure)
   `isLocked`  tinyint(1) NOT NULL DEFAULT '0',
+  -- isOver semester time (or is session time)
+  `isOver`  tinyint(1) NOT NULL DEFAULT '0',
+  `OverDate` DATE NULL DEFAULT NULL,
   PRIMARY KEY (`ID`),
   KEY `GradeID`   (`GradeID`),
   KEY `SubjectID` (`SubjectID`),
@@ -513,42 +517,51 @@ CREATE TABLE IF NOT EXISTS `recovery_tokens` (
 -- Дамп данных таблицы `user_roles`
 --
 
+-- 1 - common
+-- 2 - student
+-- 4 - teacher
+-- 8 - admin
+-- 16 - deans
 INSERT INTO `user_roles` (`ID`, `Type`, `RoleName`, `Mark`) VALUES
-(1, 'student', 'Студент', 1),
-(2, 'teacher', 'Преподаватель', 2),
-(3, 'teacher', 'Преподаватель-Администратор', 4);
+(1, 'student', 'Студент', 3),
+(2, 'teacher', 'Преподаватель', 5),
+(3, 'teacher', 'Преподаватель-Администратор', 31),
+(4, 'teacher', 'Работник деканата', 21)//
 
 --
 -- Дамп данных таблицы `user_roles`
 --
 
+
+
 INSERT INTO `page_access` (`ID`, `Pagename`, `Bitmask`) VALUES
-(1, 'common:index', 7),
-(2, 'common:settings', 7),
-(3, 'common:profile', 7),
-(4, 'teacher:index', 6),
-(5, 'teacher:settings', 6),
-(6, 'teacher:map:create', 6),
-(7, 'teacher:map:edit', 6),
-(8, 'teacher:rating', 6),
-(9, 'teacher:profile', 6),
-(10, 'admin:common', 4),
-(11, 'student:index', 1),
-(12, 'student:settings', 1),
-(13, 'student:subject', 1),
-(14, 'teacher:map:discipline', 6),
-(15, 'teacher:map:structure', 6),
-(16, 'teacher:map:groups', 6),
-(17, 'teacher:map:students', 6),
-(18, 'teacher:map:teachers', 6),
-(19, 'handler:AdmAccounts', 4),
-(20, 'handler:AdmStudents', 4),
-(21, 'handler:AdmTeachers', 4),
-(22, 'handler:GetHelp', 7),
-(23, 'handler:Map', 6),
-(24, 'handler:Rating', 6),
-(25, 'handler:Settings', 7),
-(26, 'teacher:exam', 6);
+(1, 'common:index', 1),
+(2, 'common:settings', 1),
+(3, 'common:profile', 1),
+(4, 'teacher:index', 4),
+(5, 'teacher:settings', 4),
+(6, 'teacher:map:create', 4),
+(7, 'teacher:map:edit', 4),
+(8, 'teacher:rating', 4),
+(9, 'teacher:profile', 4),
+(10, 'admin:common', 8),
+(11, 'student:index', 2),
+(12, 'student:settings', 2),
+(13, 'student:subject', 2),
+(14, 'teacher:map:discipline', 4),
+(15, 'teacher:map:structure', 4),
+(16, 'teacher:map:groups', 4),
+(17, 'teacher:map:students', 4),
+(18, 'teacher:map:teachers', 4),
+(19, 'handler:AdmAccounts', 8),
+(20, 'handler:AdmStudents', 8),
+(21, 'handler:AdmTeachers', 8),
+(22, 'handler:GetHelp', 1),
+(23, 'handler:Map', 4),
+(24, 'handler:Rating', 4),
+(25, 'handler:Settings', 1),
+(26, 'teacher:exam', 4),
+(27, 'dean_office:index', 16)//
 
 
 INSERT INTO `general_settings` (`ID`, `Val`, `ValS`) VALUES
diff --git a/db/fix.sql b/db/fix.sql
index 1e7ae43aecc97782fa9cbf82ac36910c64ffddc5..af042e239690b9e3398119b00e8fc6899333ab8a 100644
--- a/db/fix.sql
+++ b/db/fix.sql
@@ -1,237 +1,4 @@
-DELIMITER //
+ALTER TABLE `disciplines`
+ADD `isMilestone`  int(11) NOT NULL DEFAULT '0',
+ADD `MilestoneDate` DATE NULL DEFAULT NULL;
 
-
-
-
-DROP FUNCTION IF EXISTS AddSubmodule//
-CREATE FUNCTION `AddSubmodule`  ( `TeacherID`   INT, 
-									`ModuleID`    INT, 
-									`MaxRate`     INT, 
-									`Name`      VARCHAR(200) charset utf8, 
-									`Description` VARCHAR(200) charset utf8,
-									`ControlType` VARCHAR(30) charset utf8
-								)   RETURNS int(11)
-		NO SQL
-BEGIN  
-	DECLARE checker INT;  
-
-
-	SET checker = 0;
-	SELECT MAX(submodules.OrderNum)
-	INTO checker
-	FROM `submodules`
-	WHERE   ModuleID = submodules.ModuleID
-	LIMIT 1;
-	IF checker IS NULL THEN
-		SET checker = 0;
-	END IF;
-	SET checker = checker + 1;
-
-	IF Description = "" THEN
-		INSERT INTO `submodules`  
-				(   submodules.ModuleID, submodules.MaxRate, submodules.OrderNum, submodules.Name, submodules.Description, submodules.Type )
-		VALUES  (   ModuleID, MaxRate, checker, Name, NULL, ControlType);
-	ELSE 
-		INSERT INTO `submodules`  
-				(   submodules.ModuleID, submodules.MaxRate, submodules.OrderNum, submodules.Name, submodules.Description, submodules.Type )
-		VALUES  (   ModuleID, MaxRate, checker, Name, Description, ControlType);
-	END IF;
-	
-	RETURN  ( SELECT submodules.ID
-				FROM `submodules`
-				WHERE   submodules.ModuleID = ModuleID AND
-						submodules.OrderNum = checker
-				LIMIT 1
-			);
-END //
-
-DROP FUNCTION IF EXISTS AddModuleExtra//
-CREATE FUNCTION `AddModuleExtra`	(	`TeacherID` 	INT, 
-										`DisciplineID` 	INT
-									) 	RETURNS int(11)
-    NO SQL
-BEGIN  
-    DECLARE checker, vModule, vType, vGap INT;  					 	
-    IF 	NOT InternalIsTeacherAuthor(TeacherID,DisciplineID)
-    THEN
-    	RETURN -1;
-	END IF;
-
-	SET vType = -1;
-	SET checker = -1;
-	SELECT modules.ID 
-	INTO checker
-	FROM `modules`
-	WHERE 	DisciplineID = modules.DisciplineID AND 
-			modules.Type = 4
-	LIMIT 1;
-	IF checker > 0 THEN
-		RETURN -2;
-	END IF;
-
-
-	INSERT INTO `modules` 	
-			( 	modules.Name, modules.OrderNum, modules.DisciplineID, modules.Type )
-	VALUES 	( 	'Добор баллов' , 2900666 , DisciplineID, 4 );
-
-	SET vModule = -1;
-	SELECT 	modules.ID, disciplines.ExamType 
-	INTO vModule, vType
-	FROM `modules`
-	INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID 
-	WHERE 	DisciplineID = modules.DisciplineID AND 
-			modules.Type = 4
-	LIMIT 1;
-	IF vModule <= 0 THEN
-		RETURN -1; 
-	END IF;
-
-	SET vGap = -1;
-	IF vType = 1 THEN
-		SET vGap = 6;
-	END IF;
-	IF vType = 2 THEN
-		SET vGap = 30;
-		SET checker = AddSubmodule(TeacherID, vModule, vGap, '', NULL, 'LandmarkControl');
-	END IF; 
-
-	SET checker = AddSubmodule(TeacherID, vModule, vGap, '', NULL, 'LandmarkControl');
-	RETURN vModule;
-END //
-
-
-DROP FUNCTION IF EXISTS AddModule//
-CREATE FUNCTION `AddModule`	(	`TeacherID` 	INT, 
-								`DisciplineID` 	INT, 
-								`Name` 			VARCHAR(200) charset utf8
-							) 	RETURNS int(11)
-    NO SQL
-BEGIN  
-    DECLARE checker INT;  					 
-	
-    IF 	NOT InternalIsTeacherAuthor(TeacherID,DisciplineID)
-    THEN
-    	RETURN -1;
-	END IF;
-
-	SET checker = 0;
-	SELECT MAX(modules.OrderNum)
-	INTO checker
-	FROM `modules`
-	WHERE 	DisciplineID = modules.DisciplineID AND
-			modules.Type != 1
-	LIMIT 1;
-	IF checker IS NULL THEN
-		SET checker = 0;
-	END IF;
-	SET checker = checker + 1;
-
-
-	INSERT INTO `modules` 	
-			( 	modules.Name, modules.OrderNum, modules.DisciplineID )
-	VALUES 	(	Name , checker , DisciplineID );
-	
-
-	RETURN 	(	SELECT 	modules.ID
-				FROM 	`modules`
-				WHERE 	DisciplineID = modules.DisciplineID AND 
-						checker = modules.OrderNum
-				LIMIT 1 
-			);
-END //
-
-ALTER TABLE `modules` CHANGE `Type` `Type` enum('regular','exam', 'bonus', 'extra') NOT NULL DEFAULT 'regular'//
-
-
-DELETE FROM `rating_table`
-WHERE rating_table.SubmoduleID IN
-	(
-		SELECT submodules.ID
-		FROM `submodules`
-		INNER JOIN `modules` ON modules.ID = submodules.ModuleID
-		WHERE modules.Type = 2
-	)//
-
-
-
-INSERT INTO `page_access` (`ID`, `Pagename`, `Bitmask`) VALUES (NULL, 'teacher:exam', '6')//
-
-ALTER TABLE `specializations` ADD  `Code` varchar(12) NULL//
-
-
--- SELECT  modules.ID, AddSubmodule(disciplines.AuthorID, modules.ID, 40, '', NULL, 'LandmarkControl') AS '1'
--- FROM `modules`
--- INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID
--- WHERE modules.Type = 2 //
-
-
-
-
-DROP PROCEDURE IF EXISTS  fix_modules//
-CREATE PROCEDURE fix_modules()
-BEGIN
-	DECLARE checker INT;
-   DECLARE vid   INT;
-   DECLARE vname INT;
-   -- this flag will be set to true when cursor reaches end of table
-   DECLARE exit_loop BOOLEAN;         
-   -- Declare the cursor
-   DECLARE employee_cursor CURSOR FOR
-   		SELECT  modules.ID AS 'ID', disciplines.AuthorID
-		FROM `modules`
-		INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID
-		WHERE modules.Type = 2;
-
-   -- set exit_loop flag to true if there are no more rows
-   DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
-   -- open the cursor
-   OPEN employee_cursor;
-   -- start looping
-   employee_loop: LOOP
-     -- read the name from next row into the variables 
-     FETCH  employee_cursor INTO vid, vname;
-      	SET checker = AddSubmodule(vname, vid, 40, '', NULL, 'LandmarkControl');
-      	SET checker = AddSubmodule(vname, vid, 40, '', NULL, 'LandmarkControl');
-     IF exit_loop THEN
-         CLOSE employee_cursor;
-         LEAVE employee_loop;
-     END IF;
-   END LOOP employee_loop;
-END //
-
- DROP PROCEDURE IF EXISTS  fix_modules2//
- CREATE PROCEDURE fix_modules2()
-BEGIN
-	DECLARE checker INT;
-   DECLARE vid  INT;
-   DECLARE vname INT;
-   -- this flag will be set to true when cursor reaches end of table
-   DECLARE exit_loop BOOLEAN;         
-   -- Declare the cursor
-   DECLARE employee_cursor CURSOR FOR
-   		SELECT  disciplines.ID AS 'ID', disciplines.AuthorID
-		FROM `disciplines`;
-
-   -- set exit_loop flag to true if there are no more rows
-   DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
-   -- open the cursor
-   OPEN employee_cursor;
-   -- start looping
-   employee_loop: LOOP
-     -- read the name from next row into the variables 
-     FETCH  employee_cursor INTO vid, vname;
-     SET checker = AddModuleExtra(vname, vid);
-     IF exit_loop THEN
-         CLOSE employee_cursor;
-         LEAVE employee_loop;
-     END IF;
-   END LOOP employee_loop;
-END //
-
-
- CALL fix_modules()//
-  CALL fix_modules2()//
- DROP PROCEDURE IF EXISTS  fix_modules//
- DROP PROCEDURE IF EXISTS  fix_modules2//
-
-DELIMITER ;
\ No newline at end of file
diff --git a/status b/status
new file mode 100644
index 0000000000000000000000000000000000000000..92e178428778c8c5f9c80a629068db6595584188
--- /dev/null
+++ b/status
@@ -0,0 +1,293 @@
+commit 5a0752c941ee8fd86cd7f4de9a595b292f9771a8
+Author: pimka <pimka@ro.ru>
+Date:   Fri Dec 26 13:12:36 2014 +0300
+
+    file creator && xls
+
+commit f386533d5fd560281e6c36153e0431e6135a3620
+Author: pimka <pimka@ro.ru>
+Date:   Fri Dec 26 13:09:19 2014 +0300
+
+    modal window
+
+commit 9aac5357c8ac94c0afd050695f0052fbaae3c542
+Author: pimka <pimka@ro.ru>
+Date:   Fri Dec 26 02:27:23 2014 +0300
+
+    authentication timeout modal window
+
+commit f855afa842f0b97038f271008492594a0ab23fd9
+Merge: 853167d 1a47a4d
+Author: pimka <pimka@ro.ru>
+Date:   Thu Dec 25 23:50:15 2014 +0300
+
+    Merge branch 'master' of http://itlab.mmcs.sfedu.ru/git/grade-rating into develop
+
+commit 853167d08e2dd645524c078ab8b71101c5ceb317
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Thu Dec 25 21:59:34 2014 +0300
+
+    php refactoring
+
+commit 1a47a4d0d71774ed9ec98219357aef3d7b3dc53a
+Merge: 3abe6a1 d77688d
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Thu Dec 25 17:50:09 2014 +0300
+
+    Merge branch 'release/v0.9.1'
+
+commit d77688d157b6d916bb86959fd194c6bdc7e4a2f0
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Thu Dec 25 17:47:13 2014 +0300
+
+    Comment rows on exam page
+
+commit 732263777a1a8cc5bcd97958ce6b8be40746d31b
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Thu Dec 25 17:36:13 2014 +0300
+
+    FIX: mpdf; FIX: Select of subjects
+
+commit c976dc13553453c60d8989f2a2a946b7e5668695
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Thu Dec 25 16:28:25 2014 +0300
+
+    FIX: date in excel creator
+
+commit 66b94adf8deff1b8e61e9c8102fc430918c1e48d
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Thu Dec 25 14:28:40 2014 +0300
+
+    fix
+
+commit 365957a174b9f1e7b94ae518b04748f522dd6969
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Thu Dec 25 14:23:44 2014 +0300
+
+    Добавил страницу для деканата (.../~dev_rating/statement)... Перейти на страницу может любой преподаватель (далее исправим)!!!
+
+commit 1ee627573167f6b76fe9814f839012e457d4ffd3
+Author: Андрей Руденец <andrey.rudenets@gmail.com>
+Date:   Wed Dec 24 15:08:44 2014 +0300
+
+    FIX: Inline-block behavior in Firefox
+
+commit acad4e77dee11e370b840181c6f61b27052864ca
+Author: Андрей Руденец <andrey.rudenets@gmail.com>
+Date:   Wed Dec 24 15:06:22 2014 +0300
+
+    IDEA support
+
+commit 98f2f648a6576d66526b94ddae6f10374ccdd00d
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Wed Dec 24 14:35:38 2014 +0300
+
+    add <p class="help">Если вашего предмета нет в списке - пожалуйста, напишите на нам. Кнопка 'Сообщение'</p>
+
+commit ae4c5a4801dbf231076b95081c0a58bad7f5f57b
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Tue Dec 23 23:28:36 2014 +0300
+
+    who is developer
+
+commit c24433ed93d91bd1aee085455bffbd48a5381f06
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Tue Dec 23 23:01:48 2014 +0300
+
+    ...
+
+commit dfc569d9681f5a69c8fe36ca34884349302bb9d8
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Tue Dec 23 22:57:15 2014 +0300
+
+    fix exam page
+
+commit 0c70cc0d8c14a5068496352fcfe6222d42374d95
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Tue Dec 23 22:54:14 2014 +0300
+
+    FIX: max extra
+
+commit 20855a03a020d8b457f37fd768b67573c65ba41e
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Tue Dec 23 22:49:25 2014 +0300
+
+    FIX: extra max
+
+commit 0f7b600148b65ad96a337e046a6f6a19846739af
+Merge: b79610f 3abe6a1
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Tue Dec 23 22:28:39 2014 +0300
+
+    Merge branch 'master' into develop
+
+commit b79610fbf9ea53b74e7ce3c1aa3e76859f127f5f
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Tue Dec 23 22:28:25 2014 +0300
+
+    style fix
+
+commit c31a73b37f3703d6d580c5c8962844d24a5c55e1
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Tue Dec 23 21:59:23 2014 +0300
+
+    hot fix
+
+commit 3abe6a1f956c80c854c61422290dfdb48e48ce53
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Tue Dec 23 15:09:26 2014 +0300
+
+    FIX: templates
+
+commit 395e76bdc369e4df68e7d5f436add5f7dc20b6ce
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Tue Dec 23 14:54:04 2014 +0300
+
+    html subjects fix
+
+commit f0ca830cbeede9e18fb2dadabc64e0f55c3d7299
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Tue Dec 23 14:48:12 2014 +0300
+
+    hot fixes
+
+commit 6ed52861f3f8a6a486bb3051d831f8b87116b254
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 23:26:05 2014 +0300
+
+    FIX: after life testing
+
+commit 94af61dcc18b03b558577a3ba03fe09dab2e41fc
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 21:31:41 2014 +0300
+
+    css fix
+
+commit 91669f2c2d0c9363b9f9bff199bc74550975cd85
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 20:24:14 2014 +0300
+
+    UPD: update.txt
+
+commit 4c8e89e7fa3b9c73707f7951d0c1f3b3e7a5ae71
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 19:59:12 2014 +0300
+
+    FIX: disabled columns
+
+commit 2e2faff2ed9fe6273c145a4c3d035615627d5062
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 19:15:45 2014 +0300
+
+    fix: sort and seek
+
+commit 79597e493a49faabdd26590b623e3380e6e93824
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 18:41:08 2014 +0300
+
+    FIX: { FIX: exam view; RM: rate in exam view }
+
+commit bc1f8db53ddc994dec429eef6b82ab8e9c9e5cee
+Author: RomanSteinberg <romanofficial@yandex.ru>
+Date:   Mon Dec 22 18:33:14 2014 +0300
+
+    FIX: exam view; RM: rate in exam view
+
+commit 3c8cb17ef9416526fcd0c7d09e7626c6ccf0b079
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 12:14:59 2014 +0300
+
+    fix js hover
+
+commit 4eb2356d5d96d04b1082f19645faeba0cb3c24ad
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 02:30:29 2014 +0300
+
+    ...
+
+commit db4d1a0d4f53a0245647f261b8f63d0ed3b077b4
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 02:23:16 2014 +0300
+
+    ...
+
+commit 2a823db447e7e8b6558432614626fcb473133782
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:56:27 2014 +0300
+
+    final fix
+
+commit 46a7f89e04fc2f601dc1eff3d8cd96f481ca05b3
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:53:17 2014 +0300
+
+    fix
+
+commit 036c21f9ba5aca0860f23c34715a1ad9d45882ff
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:42:13 2014 +0300
+
+    postfix
+
+commit e1286ba09de58aada735143833cff66c2fe9e1a7
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:22:43 2014 +0300
+
+    fix
+
+commit fe0efb216436168b51d1454b30286455dbc7b775
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:19:25 2014 +0300
+
+    fix
+
+commit 41051640faee74f3cc7848577957407341d18c12
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:07:56 2014 +0300
+
+    another fix
+
+commit 7c2adecf64fd5504cdbe61fd145f737a306c70da
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 01:06:18 2014 +0300
+
+    fix js and css
+
+commit 42d0952f00a42633517b64cbd8aa46156a70be8b
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 01:02:39 2014 +0300
+
+    fix
+
+commit f6e87c15667e8d50d80bf0979f003096399edea0
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 00:52:48 2014 +0300
+
+    almost dying
+
+commit 43d89cb7fd3b9ff3e2322da1735bceeaa7d468e6
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 00:36:47 2014 +0300
+
+    css
+
+commit ac5458dd65cee56e1220c252dac19cd5df4b8ca2
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 00:27:32 2014 +0300
+
+    just another fix
+
+commit c33ae701c82d5b0351a0a234195736d20570694c
+Author: PavelBegunkov <asml.Silence@gmail.com>
+Date:   Mon Dec 22 00:19:37 2014 +0300
+
+    stylish
+
+commit c0eb0f1d546e48db0a765e6e197783c7942ea8b9
+Merge: 824de16 9a0e18d
+Author: Антон Шалимов <solidovic@gmail.com>
+Date:   Mon Dec 22 00:12:00 2014 +0300
+
+    Merge branch 'develop' of http://itlab.mmcs.sfedu.ru/git/grade-rating into develop
+
+commit 9
\ No newline at end of file
diff --git a/~dev_rating/application/bootstrap.php b/~dev_rating/application/bootstrap.php
index c356dc4f0b83334ee95ec162fabd4c7577de072e..49bb2afef344e1989137c70446a2c37cbec14ff2 100644
--- a/~dev_rating/application/bootstrap.php
+++ b/~dev_rating/application/bootstrap.php
@@ -335,9 +335,9 @@ Route::set('admin:common', 'admin(/<controller>(/<action>(/<param1>(:<param2>)))
         ));
 
 /* --------------- Деканат (Ведомости) ---------------- */       
-Route::set('deans_office:statement', 'statement')
+Route::set('dean_office:index', 'dean_office')
         ->defaults(array(
-            'directory' => 'DeansOffice',
+            'directory' => 'DeanOffice',
             'controller' => 'index',
             'action' => 'index'
         ));
\ No newline at end of file
diff --git a/~dev_rating/application/classes/Controller/DeansOffice/Index.php b/~dev_rating/application/classes/Controller/DeanOffice/Index.php
similarity index 72%
rename from ~dev_rating/application/classes/Controller/DeansOffice/Index.php
rename to ~dev_rating/application/classes/Controller/DeanOffice/Index.php
index 57443057136063b471fe19bcaebfd4cff8ad260e..4473e1a2e84203c4590f998877f84b9fbb870cbb 100644
--- a/~dev_rating/application/classes/Controller/DeansOffice/Index.php
+++ b/~dev_rating/application/classes/Controller/DeanOffice/Index.php
@@ -1,10 +1,10 @@
 <?php defined('SYSPATH') or die('No direct script access.');
 
-class Controller_DeansOffice_Index extends Controller_UserEnvi {
+class Controller_DeanOffice_Index extends Controller_UserEnvi {
 
     public function action_index()
     {
-        $twig = Twig::factory('DeansOffice/index');
+        $twig = Twig::factory('dean_office/index');
         $model = new Model_Teacher_Map;
 
         $twig->GradesList = DataArray::factory('Grades')->common()->asArray();
diff --git a/~dev_rating/application/classes/Controller/Handler.php b/~dev_rating/application/classes/Controller/Handler.php
index 6e6b1d0d9150edae23762c09f2b96ce27b4555df..5fb6b4461ca77e6e91d33d3089a7855bc2753ecf 100644
--- a/~dev_rating/application/classes/Controller/Handler.php
+++ b/~dev_rating/application/classes/Controller/Handler.php
@@ -32,7 +32,10 @@ class Controller_Handler extends Controller {
         // Получаем имя маршрута 
         $route = Route::name($this->request->route());
         $route .= ':'.$this->request->controller();
-        $userMark = $user->offsetGet('RoleMark');
+        $userMark = (int)$user->offsetGet('RoleMark');
+        if ($userMark == 0) {
+            $userMark = (int)1;
+        }
         // Если запрос не прошел на проверку доступа
         if( !$this->checkAccessLevel() || 
             !$this->checkBitmask($userMark, $route))
@@ -50,7 +53,7 @@ class Controller_Handler extends Controller {
     protected function checkBitmask($userMark, $route)
     {
         $sysModel = new Model_System;
-        $bitmask = $sysModel->getBitmaskForRoute($route);
+        $bitmask = (int)$sysModel->getBitmaskForRoute($route);
         if(!$bitmask)
             return true;
         return ($bitmask & $userMark) != 0;
diff --git a/~dev_rating/application/classes/Controller/Handler/FileCreator.php b/~dev_rating/application/classes/Controller/Handler/FileCreator.php
index 88a3841bf4459099986823d0566acdc3e11a8f2a..95e27fc28d5ee455782a43d295a876aa41ebe019 100644
--- a/~dev_rating/application/classes/Controller/Handler/FileCreator.php
+++ b/~dev_rating/application/classes/Controller/Handler/FileCreator.php
@@ -173,111 +173,221 @@ class Controller_Handler_FileCreator extends Controller_Handler
     // Ведомость
     public function action_GenerateExcelStatement()
     {
-        // TODO CHECK!!!       
-		
+        // TODO CHECK!!! // TODO      
 		// parameters
-		$disciplineID = $this->post->offsetGet('disciplineID');
+        $disciplineID = $this->post->offsetGet('disciplineID');
         $groupID = $this->post->offsetGet('studyGroupID');
+		
 		// preparation
-		$db = $this->model;
+        $db = $this->model;
         $info = $db->getFinalFormInfo($disciplineID, $groupID);
+       
         $type = $info[0]['ExamType'];
-		$templateFile = DOCROOT."docs/template $type.xls";
+        $templateFile = DOCROOT."docs/template $type.xls";
         if (!file_exists($templateFile)) {
             exit("template wasn't found" . PHP_EOL); // TODO
         }
-		$objPHPExcel = PHPExcel_IOFactory::load($templateFile);
+        $objPHPExcel = PHPExcel_IOFactory::load($templateFile);
         $objPHPExcel->setActiveSheetIndex(0);
-		$index = 1;
 		        
         // $specName = '';  <------- TODO
-        
+		$this->printDisciplineToExcelFile($objPHPExcel, $disciplineID, $groupID, $info[0]);
+           
+        $this->GetHeaders("FinalForm".$disciplineID."_".$groupID);
+        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
+        $objWriter->save('php://output');
+    } 
+	
+    public function printDisciplineToExcelFile(&$objPHPExcel, $disciplineID, $groupID, $headerData) {
+		
+        // preparation
+        $type = $headerData['ExamType'];
+        $db = $this->model;
         $result = $db->getRatesForStudentsGroup($this->user['TeacherID'], $disciplineID, $groupID);
-        $rowsCount = count($result); // Получаем количество записей 
-        
-        $objPHPExcel = PHPExcel_IOFactory::load($templateFile);
-		$objPHPExcel->setActiveSheetIndex(0);
-        
-    
+		
         // fill header
+        $this->prepareSheetHeader($objPHPExcel, $type, $headerData);
+                
+        // fill students rows
+        $startRow = 13;  
+        $rowNumber = $startRow;
+        $index = 1;
+
+        foreach($result as $studentInfo){
+            $this->addStudentToSheet($objPHPExcel, $studentInfo, $rowNumber, $index);
+            $rowNumber++;
+            $index++;				
+        }    
+    }
+
+    protected function prepareSheetHeader(&$objPHPExcel, $examType, $data) {
+        $sheet = $objPHPExcel->getActiveSheet();
+        
         $range = $objPHPExcel->getNamedRange("Discipline")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['SubjectName']);
-		$range = $objPHPExcel->getNamedRange("Group")->getRange();
-		$objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['GroupNum']);
+        $sheet->setCellValue($range, $data['SubjectName']);
+        $range = $objPHPExcel->getNamedRange("Group")->getRange();
+        $sheet->setCellValue($range, $data['GroupNum']);
         $range = $objPHPExcel->getNamedRange("Subdivision")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['FacultyName']);
+        $sheet->setCellValue($range, $data['FacultyName']);
         $range = $objPHPExcel->getNamedRange("Major")->getRange();  
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", "Специальность: ".$info[0]['SpecName']." ".$info[0]['SpecCode']);
+        $sheet->setCellValue($range, "Специальность: ".$data['SpecName']." ".$data['SpecCode']);
         $range = $objPHPExcel->getNamedRange("Teacher")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['LastName']." ".$info[0]['FirstName']." ".$info[0]['SecondName']);
+        $sheet->setCellValue($range, $data['LastName']." ".$data['FirstName']." ".$data['SecondName']);
+		
         $range = $objPHPExcel->getNamedRange("Grade")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['GradeNum']);
+		$degree = $data['Degree'];
+		$gradeName = $data['GradeNum'];
+		if ($degree == 'master')
+			$gradeName = $gradeName."Рј";
+        $sheet->setCellValue($range, $gradeName);
+		
         $range = $objPHPExcel->getNamedRange("Semester")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['SemesterNum']);
+        $sheet->setCellValue($range, $data['SemesterNum']);
         $range = $objPHPExcel->getNamedRange("Year")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", $info[0]['Year']);
+        $sheet->setCellValue($range, $data['Year']);
         $range = $objPHPExcel->getNamedRange("CreationDate")->getRange();
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", date("d.m.y"));
+        $sheet->setCellValue($range, date("d.m.y"));
         $range = $objPHPExcel->getNamedRange("Date")->getRange();
-        if ($type == 'exam') 
+        if ($examType == 'exam') {
             $controlDate = '__________';
-        else
+        } else {
             $controlDate = '30.12.2014';
-        $objPHPExcel->getActiveSheet()->setCellValue("$range", "Дата зачета \n$controlDate");
+        }
+        $sheet->setCellValue("$range", "Дата зачета \n$controlDate");
+    }
     
-        // fill students rows
-        $startRow = 13; 
-        $finalRow = 52; 
-        $indPosition = 'A'; // Номер 
-        $namePosition = 'B';  // ФИО 
-        $totalRatePosition = 'G';  // Итоговый рейтинг 
-        $semesterRatePosition  = 'H';   // Сумма баллов
-        $bonusRatePosition = 'I'; // Бонусные баллы
-        $rowNumber = $startRow;
-        $index = 1;
-
-        foreach($result as $studentInfo){
-			
-			$objPHPExcel->getActiveSheet()->insertNewRowBefore($rowNumber + 1, 1);
-			$objPHPExcel->getActiveSheet()->getStyle("A".$rowNumber.":S".$rowNumber)->getBorders()->getAllBorders()->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
-			
-			$objPHPExcel->getActiveSheet()->mergeCells("B".$rowNumber.":F".$rowNumber);
+    protected function addStudentToSheet(&$objPHPExcel, $data, $row, $index) 
+    {
+            $sheet = $objPHPExcel->getActiveSheet();
+        
+            $indPosition = 'A'; // Номер 
+            $namePosition = 'B';  // ФИО 
+            $totalRatePosition = 'G';  // Итоговый рейтинг 
+            $semesterRatePosition  = 'H';   // Сумма баллов
+            $bonusRatePosition = 'I'; // Бонусные баллы
+        
+            $sheet  ->getStyle("A".$row.":S".$row)
+                    ->getBorders()->getAllBorders()
+                    ->setBorderStyle(PHPExcel_Style_Border::BORDER_THIN);
+            $sheet  ->getStyle("G".$row.":S".$row)
+                    ->getAlignment()
+                    ->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
+            $sheet->mergeCells("B".$row.":F".$row);
 			
-            $lastName = $studentInfo['Last'];
-            $firstName = $studentInfo['First'];
-            $secondName = $studentInfo['Second'];
-            $rate = (int)$studentInfo['intermediate'];
-            $bonus = (int)$studentInfo['bonus'];
-            $fullName = "$lastName  $firstName $secondName";
+            $lastName = $data['Last'];
+            $firstName = $data['First'];
+            $secondName = $data['Second'];
+            $rate = (int)$data['intermediate'];
+            $bonus = (int)$data['bonus'];
+            $fullName = $lastName." ".$firstName." ".$secondName;
             $totalRate = $rate + $bonus;
 			
-			if($totalRate < 60)
-			{
-				$tempRate = " ";
-				$tempStr = "не зачтено";
-			}	
-			else
-			{
-				$tempStr = "зачтено";
-				$tempRate = $totalRate;
-			}	
+			if ($totalRate > 100)
+				$totalRate = 100;
+
+            if($totalRate < 60) {
+                    $tempRate = " ";
+                    $tempStr = "не зачтено";
+            } else {
+                    $tempRate = $totalRate;			
+                    $tempStr = "зачтено";
+            }
 			
-            $objPHPExcel->getActiveSheet()->setCellValue("$indPosition$rowNumber", "$index")
-                                  ->setCellValue("$namePosition$rowNumber", "$fullName")
-                                  ->setCellValue("$totalRatePosition$rowNumber", "$tempRate")
-                                  ->setCellValue("$semesterRatePosition$rowNumber","$rate")
-                                  ->setCellValue("$bonusRatePosition$rowNumber","$bonus")
-								  ->setCellValue("J".$rowNumber,$tempStr);
-								  
-            $rowNumber++;
-            $index++;				
-        }    
-	    $this->GetHeaders("FinalForm".$disciplineID."_".$groupID);
+            $sheet  ->setCellValue($indPosition.$row, $index)
+                    ->setCellValue($namePosition.$row, $fullName)
+                    ->setCellValue($totalRatePosition.$row, $tempRate)
+                    ->setCellValue($semesterRatePosition.$row, $rate)
+                    ->setCellValue($bonusRatePosition.$row, $bonus)
+                    ->setCellValue("J".$row, $tempStr);
+        
+    }
+	
+    protected function getSheetName(&$disciplineInfo) {
+        $str = $disciplineInfo['SubjectAbbr'];
+        if (empty($str)) {
+            $str = $disciplineInfo['SubjectName'];
+        }
+        //$str = preg_replace('/[^A-Za-z0-9\-]/', '', $str);
+        return substr($str, 0, 10);
+    }
+	
+    public function action_GenerateFinalFormsForGroup() {
+        // parameters
+        //$gradeID = $this->post->offsetGet('gradeID');
+        $groupID = $this->post->offsetGet('GroupID');
+
+        // preparation
+        $db = $this->model;
+        $listDisciplines = $db->GetDisciplinesForGroup($groupID);
 
+        $templateFile = DOCROOT."docs/template credit.xls";
+        if (!file_exists($templateFile)) {
+                exit("template wasn't found" . PHP_EOL); // TODO
+        }
+        $objPHPExcel = PHPExcel_IOFactory::load($templateFile);
+        // Make copy of sheet
+        $sheetTemplate = $objPHPExcel->getActiveSheet()->copy();
+        // Make copy of named ranges
+        $nmrange = $objPHPExcel->getNamedRanges() ; 
+
+        $index = 0;
+        foreach ($listDisciplines as $record) {
+                $disciplineID = $record['DisciplineID'];
+                $info = $db->getFinalFormInfo($disciplineID, $groupID);
+
+                $type = $info[0]['ExamType'];
+                if ($type == 'exam') {
+                continue;
+            }
+
+            if ($index > 0) {
+                        // remove name ranges from active page
+                        foreach ($objPHPExcel->getNamedRanges() as $name => $r )
+                        {
+                                $objPHPExcel -> removeNamedRange ($r->getName(), null);
+                        }	
+                        //make clone from page copy and include it in workbook
+                        $C = clone $sheetTemplate;
+                        try {
+                            $C->setTitle($this->getSheetName($info[0]));
+                        } catch (Exception $ex) {
+                            $C->setTitle("Без_имени_".$index);
+                        }  
+                       
+                        $objPHPExcel->addSheet($C,$index);
+                        $objPHPExcel->setActiveSheetIndex($index);
+                        // create name ranges at new sheet 
+                        foreach ($nmrange as $namedRange) {
+                                $name = $namedRange->getName();
+                                $rg = $namedRange->getRange();
+                                $objPHPExcel->addNamedRange(new PHPExcel_NamedRange($name, $objPHPExcel->getActiveSheet(),$rg));
+                        }
+                }
+                else
+                {   
+                    try {
+                        $objPHPExcel->setActiveSheetIndex($index)->setTitle($this->getSheetName($info[0]));
+                    } catch (Exception $ex) {
+                        $objPHPExcel->setActiveSheetIndex($index)->setTitle("Без_имени_".$index);
+                    }        
+                    $gradeNum = $info[0]['GradeNum'];
+                    $groupNum = $info[0]['GroupNum'];
+                }
+
+                $this->printDisciplineToExcelFile($objPHPExcel, $disciplineID, $groupID, $info[0]);
+                $index++;
+        }
+        
+        if ($index === 0) {
+            throw HTTP_Exception::factory(400);
+            return;
+        }
+
+        $this->GetHeaders("FinalForm_".$gradeNum."_".$groupNum);
         $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
         $objWriter->save('php://output');
-    } 
-
+    }
+	
     // Выводим HTTP-заголовки
     public function GetHeaders($filename = 'excel')
     {
diff --git a/~dev_rating/application/classes/Controller/Student/Index.php b/~dev_rating/application/classes/Controller/Student/Index.php
index c3ba87ecf0ebd562ae4431597866d0f149c56ebd..aa7fb553d088c3d82d0e4186daacceb96476eda8 100644
--- a/~dev_rating/application/classes/Controller/Student/Index.php
+++ b/~dev_rating/application/classes/Controller/Student/Index.php
@@ -13,7 +13,6 @@ class Controller_Student_Index extends Controller_UserEnvi {
         foreach($disciplines as $row)
         {
             $i++;
-            $color = 0;
             $disciplinesHandled[$i]['ID'] = $row['ID'];
             if($row['ExamType'] == 'exam')
             {
@@ -73,7 +72,7 @@ class Controller_Student_Index extends Controller_UserEnvi {
                 $color = 5;
             elseif($percent >= 0.85 AND $percent <= 0.94)
                 $color = 6;
-            elseif($percent >= 0.95 AND $percent <= 1)
+            elseif($percent >= 0.95)
                 $color = 7;
             if($examRate !== NULL AND $examRate < 22)
                 $color = 2;
diff --git a/~dev_rating/application/classes/Controller/Teacher/Rating.php b/~dev_rating/application/classes/Controller/Teacher/Rating.php
index dea08e8edd8902165e030c2abafe429efa5245f7..2816a5ea5b0793d52ebf38b2119a05859ba10db0 100644
--- a/~dev_rating/application/classes/Controller/Teacher/Rating.php
+++ b/~dev_rating/application/classes/Controller/Teacher/Rating.php
@@ -30,6 +30,7 @@ class Controller_Teacher_Rating extends Controller_UserEnvi {
         $temp = $this->model_discipline->getDisciplineInfoByID($id);
         $disciplineInfo['ExamType'] = $temp[0]['ExamType'];
         $disciplineInfo['ID'] = $id;
+        $disciplineInfo['isMilestone'] = $temp[0]['isMilestone'];
         $disciplineInfo['StudyGroupID_Filter'] = $this->getStudyGroupID_ForFilter($id);
 
         return $disciplineInfo;
@@ -44,7 +45,7 @@ class Controller_Teacher_Rating extends Controller_UserEnvi {
         $id = $this->request->param('id');
 
         // Шапка таблицы: структура УКД (модули и мероприятия)
-		$structure = $this->model_rating->GetMapForDiscipline($this->UserInfo['TeacherID'], $id);
+        $structure = $this->model_rating->GetMapForDiscipline($this->UserInfo['TeacherID'], $id);
 
         if($structure->count() == 0)
             throw HTTP_Exception::factory (404, "Для дисциплины с ID $id не создана УКД или такой дисциплины не существует!");
diff --git a/~dev_rating/application/classes/Controller/UserEnvi.php b/~dev_rating/application/classes/Controller/UserEnvi.php
index 7fc0298d434078457c6df0a2cc2505ce4602b067..f91d3bbcee26391ce0cc0d8a53ac30c445ae042d 100644
--- a/~dev_rating/application/classes/Controller/UserEnvi.php
+++ b/~dev_rating/application/classes/Controller/UserEnvi.php
@@ -24,7 +24,13 @@ class Controller_UserEnvi extends Controller {
         $route = Route::name($this->request->route());
         $userMark = $user->offsetGet('RoleMark');
         $sysModel = new Model_System;
-        $bitmask = $sysModel->getBitmaskForRoute($route);
+        $bitmask = (int)$sysModel->getBitmaskForRoute($route);
+        if ($bitmask === 0) {
+            $bitmask = (int)1;
+        }
+        if ($userMark === 0) {
+            $userMark = (int)1;
+        }
         if(!($bitmask & $userMark)) {
             throw HTTP_Exception::factory(403, 
             'Не пытайтесь попасть туда, куда попадать не следует.');
diff --git a/~dev_rating/application/classes/Model/Teacher/Rating.php b/~dev_rating/application/classes/Model/Teacher/Rating.php
index a57687d68f1e2239e9def1887eca760a2ece377e..02c4c36b2db40b96dc9b1b300a8bb7cda53510eb 100644
--- a/~dev_rating/application/classes/Model/Teacher/Rating.php
+++ b/~dev_rating/application/classes/Model/Teacher/Rating.php
@@ -61,4 +61,10 @@ class Model_Teacher_Rating extends Model
         return DB::query(Database::SELECT, $sql)->execute();
     }
     
+    public function getDisciplinesForGroup($groupID)
+    {
+        $sql = "CALL `GetDisciplinesForGroup`($groupID)";
+        return DB::query(Database::SELECT, $sql)->execute();
+    }
+    
 }
diff --git a/~dev_rating/application/views/base.twig b/~dev_rating/application/views/base.twig
index 227a5571e8b6cfe08bb60ba0e27329ef6d3ea42e..baf3a73d842d6f18f6236c804fbcf01a7ec16d8f 100644
--- a/~dev_rating/application/views/base.twig
+++ b/~dev_rating/application/views/base.twig
@@ -70,9 +70,12 @@
                                     {{ User.First }} {{ User.Last }}
 					</div>
 					| 
-                                {% if User.RoleMark == 4 %}
-                                {{ HTML.anchor('admin', 'Администрирование', {'title': 'Перейти в панель управления системой'})|raw }}
-                                {% endif %}
+					{% if (User.RoleMark b-and 16) != 0 %}
+						{{ HTML.anchor('dean_office', 'Деканат')|raw }}
+					{% endif %}
+					{% if User.RoleMark b-and 4 %}
+						{{ HTML.anchor('admin', 'Администрирование', {'title': 'Перейти в панель управления системой'})|raw }}
+					{% endif %}
 				{{ HTML.anchor('/', 'Главная страница', {'title': 'Перейти на главную страницу'})|raw }}
 				{{ HTML.anchor('settings', 'Настройки', {'title': 'Настроить аккаунт'})|raw }}
 				{{ HTML.anchor('sign/out', 'Выход', {'title': 'Выйти из системы'})|raw }}
diff --git a/~dev_rating/application/views/DeansOffice/index.twig b/~dev_rating/application/views/dean_office/index.twig
similarity index 93%
rename from ~dev_rating/application/views/DeansOffice/index.twig
rename to ~dev_rating/application/views/dean_office/index.twig
index c581837a3065a5ac7aa7ebb3e106d0707bfeaf4c..bcf6554493e3dc21e59091723260c463888116b6 100644
--- a/~dev_rating/application/views/DeansOffice/index.twig
+++ b/~dev_rating/application/views/dean_office/index.twig
@@ -5,7 +5,7 @@
     {{ HTML.script('media/js/jquery.fileDownload.js')|raw }}
 
     {{ HTML.style('media/css/discipline.css')|raw }}
-    {{ HTML.script('media/js/GetData.js')|raw }}
+    {{ HTML.script('media/js/getFinalForms.js')|raw }}
 {% endblock %}
 
 {% block main_top_title %}Деканат > Ведомости{% endblock %}
@@ -18,10 +18,10 @@
                 <div class="title">Форма контроля:</div>
                 <div class="field">
                     <div class="ExamTypeDiv">
-                        <input id="ExamType" name="ExamType" type="radio" value="exam"> Экзамен
+                        <input id="ExamType" name="ExamType" type="radio" value="exam" disabled> Экзамен
                     </div>
                     <div class="ExamTypeDiv">
-                        <input id="ExamType" name="ExamType" type="radio" value="credit"> Зачет
+                        <input id="ExamType" name="ExamType" type="radio" value="credit" checked> Зачет
                     </div>
                 </div>
             </div>
diff --git a/~dev_rating/application/views/student/index.twig b/~dev_rating/application/views/student/index.twig
index c06909673f8cc40ee1778de9e1e59aa1d608a274..90d0fc25fc5d2b28cd23c7a0de670d9467963005 100644
--- a/~dev_rating/application/views/student/index.twig
+++ b/~dev_rating/application/views/student/index.twig
@@ -1,42 +1,42 @@
 {% extends 'base' %} 
  
 {% macro subject(i, HTML) %}
-	<tr class="course_content">
-                <td class="{{ i.ColorScheme }}">
-                    <div class='Circle'></div>
-                </td>
-		<td class = "course_name">
-                    {{ HTML.anchor('subject/' ~ i.ID, i.Title)|raw }}
-		</td>
+<tr class="course_content">
+    <td class="{{ i.ColorScheme }}">
+        <div class='Circle'></div>
+    </td>
+    <td class = "course_name">
+        {{ HTML.anchor('subject/' ~ i.ID, i.Title)|raw }}
+    </td>
 
-		<td class="course_teacher">
-                    {% for teacher in i.Teachers %}
-                        <div>{{ teacher }}</div>
-                    {% else %}
-                        ---
-                    {% endfor %}
-		</td>
+    <td class="course_teacher">
+        {% for teacher in i.Teachers %}
+            <div>{{ teacher }}</div>
+        {% else %}
+            ---
+        {% endfor %}
+    </td>
 
-		<td  class="course_form_control">
-                    {{ i.Control }}
-		</td>	
+    <td  class="course_form_control">
+        {{ i.Control }}
+    </td>
 
-		<td class="course_rating_value">
-                    {{ i.Rate|default('0') }} / {{ i.MaxCurrentRate|default('0') }} / {{ i.MaxRate }}
-		</td>
+    <td class="course_rating_value">
+        {{ i.Rate|default('0') }} / {{ i.MaxCurrentRate|default('0') }} / {{ i.MaxRate }}
+    </td>
 
-		<td class="course_rating_percent">
-                    {% if i.MaxCurrentRate != 0 %}
-						{% if i.Rate > i.MaxCurrentRate %}
-							100%
-						{% else %}
-							{{ (100 * i.Rate) // i.MaxCurrentRate }} %
-						{% endif %}
-                    {% else %}
-                        ---
-                    {% endif %}
-		</td>
-	</tr>	
+    <td class="course_rating_percent">
+        {% if i.MaxCurrentRate != 0 %}
+            {% if i.Rate > i.MaxCurrentRate %}
+                100%
+            {% else %}
+                {{ (100 * i.Rate) // i.MaxCurrentRate }} %
+            {% endif %}
+        {% else %}
+            ---
+        {% endif %}
+    </td>
+</tr>
 {% endmacro %}
 {% import 'student/index' as res %}
 
diff --git a/~dev_rating/application/views/teacher/rating.twig b/~dev_rating/application/views/teacher/rating.twig
index d2298cd4f8a06f3a0c055b1a97e03d76295abb14..88ec4e30ab665242e994e82b8b5ae580641842f4 100644
--- a/~dev_rating/application/views/teacher/rating.twig
+++ b/~dev_rating/application/views/teacher/rating.twig
@@ -12,6 +12,11 @@
 
 {% block main_top_title %}Выставление баллов{% endblock %}
 {% block main_content %}
+        {% if disciplineInfo.isMilestone > 0 %}
+            <p class="canNotEdit">
+                Семестр завершен. Выставление баллов <u>запрещено</u>.
+            </p>
+	{% endif %}
 	<h2 class="h2_titleSubject">{{ SubjectName }}</h2>
 
 	<button class="downloadExcel" style="display: none">Скачать в excel формате [dev version]</button>
@@ -92,7 +97,7 @@
 					<td id="student_{{ student.ID }}" class="studentCell staticCell">{{ student.Last }} {{ student.First }}</td>
 					{% for i in 1..CellCount %}
 						{% set j = j + 1 %}
-						{% if student.Rates[i].SubmoduleID >= 0 %}
+						{% if student.Rates[i].SubmoduleID >= 0 and disciplineInfo.isMilestone == 0  %}
 							<td id="col_{{ j }}" class="commonCell">
 								<input type="text" value="{{ student.Rates[i].Rate }}">
 							</td>
diff --git a/~dev_rating/deploy.php b/~dev_rating/deploy.php
index bd691ffee9c65058a9da69c1654824366b4d1666..71cb15a88a1e531058911b80556604e83057ef77 100644
--- a/~dev_rating/deploy.php
+++ b/~dev_rating/deploy.php
@@ -9,6 +9,8 @@
                 echo 'Беда!';
         if(!copy(CFGPATH.'twig.php', APPPATH.'config/twig.php'))
                 echo 'Беда!';   
+        if(!copy(CFGPATH.'session.php', APPPATH.'config/session.php'))
+                echo 'Беда!';  
     }
     
     if(!is_dir(APPPATH.'logs/'))
diff --git a/~dev_rating/media/css/rating.css b/~dev_rating/media/css/rating.css
index b26ddb6ee43021503de2ef78b44b46a1ef7a1f75..c91d73eb08517ff9c5e27ca825b44b80171985b9 100644
--- a/~dev_rating/media/css/rating.css
+++ b/~dev_rating/media/css/rating.css
@@ -193,3 +193,18 @@ div#tdInfo_wrap {
 	cursor: pointer;
 }
 /* end todo */
+
+
+/* Copied from discipline.css */
+.canNotEdit {
+	position: absolute;
+	padding: 6px 10px;
+	top: 0;
+	right: 0;
+	text-align: center;
+	font-size: 14px;
+	color: #a94442;
+	background: #f2dede;
+	border-radius: 0 0 0 5px;
+}
+
diff --git a/~dev_rating/media/css/student/index.css b/~dev_rating/media/css/student/index.css
index cb1ef170e363e43bca9e8788a8702a765a286f2a..100072dad840ee4e2167660aa8039654045535ce 100644
--- a/~dev_rating/media/css/student/index.css
+++ b/~dev_rating/media/css/student/index.css
@@ -96,27 +96,27 @@ tr.course_content td {
 }
 
 .ECTS-F > .Circle { 
-    background: #f60;
+    background: #8A2E15;
 }
 
 .ECTS-FX > .Circle { 
-    background: #e56800;
+    background: #D46141;
 }
 
 .ECTS-E > .Circle { 
-    background: #ffb100;
+    background: #EDEC51;
 }
 .ECTS-D > .Circle {
-    background: #ffd000;
+    background: #7EBA3C;
 }
 .ECTS-C > .Circle { 
-    background: #70c300;
+    background: #28AE57;
 }
 .ECTS-B > .Circle { 
-    background: #059e00;
+    background: #349920;
 }
 .ECTS-A > .Circle {
-    background: #009404;
+    background: #367F27;
 }
 
 .course_rating_percent > div 
diff --git a/~dev_rating/media/js/GetData.js b/~dev_rating/media/js/GetData.js
deleted file mode 100644
index b6f2a1dbac66f9b704f395e7115ad953bd6ee765..0000000000000000000000000000000000000000
--- a/~dev_rating/media/js/GetData.js
+++ /dev/null
@@ -1,52 +0,0 @@
-var $ = jQuery;
-$(function() {
-
-	//Получить список групп по ID курса
-    $("#SelectGrade").change(function() {
-        var gradeID = $(this).val(); 
-        if (gradeID >= 0)
-        {
-            $.post(
-                g_URLdir + "handler/GetData/GetGroups",
-                {   
-                    "GradeID": gradeID 
-                },
-                function(d){
-                    d = $.parseJSON(d);
-                    if(d.success === true) {
-                    	console.log(d.data);
-                    	var selectGroup = $("#SelectGroup");
-                    	var i = 0;
-                    	selectGroup.html("<option>-Не выбрана-</option>");
-                    	for (i in d.data)
-                    	{
-                    		group = d.data[i];
-                    		selectGroup.append("<option value='"+ group.ID +"'>Группа "+ group.GroupNum +" ("+ group.SpecAbbr +")</option>");
-                    		selectGroup.removeAttr("disabled");
-                    	}
-                    	$("#DownloadStatement").removeAttr("disabled");
-                    }
-                }
-            );
-        }
-    });
-
-    // Скачать ведомость
-     $('body').on('click', '#DownloadStatement', function(){
-        $.fileDownload( g_URLdir + 'handler/FileCreator/GenerateFullStatement', {
-            httpMethod: "POST",
-            data: 
-            {
-                "GroupID": parseInt($("#SelectGroup").val()),
-                "ExamType": $("#ExamType").val() 
-            },
-            successCallback: function () {
-
-            },
-            failCallback: function () {
-
-            }
-        });
-    });
-
-});
\ No newline at end of file
diff --git a/~dev_rating/media/js/getFinalForms.js b/~dev_rating/media/js/getFinalForms.js
new file mode 100644
index 0000000000000000000000000000000000000000..e0d63139d2f70b64e7f7bc305778f5f898b3730a
--- /dev/null
+++ b/~dev_rating/media/js/getFinalForms.js
@@ -0,0 +1,68 @@
+var $ = jQuery;
+$(function() {
+
+	var jDownloadStatement = $("#DownloadStatement");
+
+	//Получить список групп по ID курса
+    $("#SelectGrade").change(function() {
+        var gradeID = parseInt($(this).val()) || 0;
+        var jSelectGroup = $("#SelectGroup");
+        if (gradeID > 0)
+        {
+            $.post(
+                g_URLdir + "handler/GetData/GetGroups",
+                {   
+                    "GradeID": gradeID 
+                },
+                function(d){
+                    d = $.parseJSON(d);
+                    if(d.success === true) {
+                    	console.log(d.data);
+                    	var i = 0;
+                    	jSelectGroup.html("<option>-Не выбрана-</option>");
+                    	for (i in d.data)
+                    	{
+                    		group = d.data[i];
+                    		jSelectGroup.append("<option value='"+ group.ID +"'>Группа "+ group.GroupNum +" ("+ group.SpecAbbr +")</option>");
+                    	}
+                    	if (i > 0 )
+                    		jSelectGroup.removeAttr("disabled");
+                    }
+                }
+            );
+        }
+        else 
+        {
+        	jSelectGroup.attr("disabled", "disabled");
+        	jSelectGroup.html("<option>-Не выбрана-</option>");
+
+        	jDownloadStatement.attr("disabled", "disabled");
+        }
+    });
+
+	 $("#SelectGroup").change(function() {
+	 	var groupID = parseInt($(this).val()) || 0;
+	 	if (groupID > 0)
+	 		jDownloadStatement.removeAttr("disabled");
+	 	else jDownloadStatement.attr("disabled", "disabled");
+	 });
+
+    // Скачать ведомость
+     $('body').on('click', '#DownloadStatement', function(){
+        $.fileDownload( g_URLdir + 'handler/FileCreator/GenerateFinalFormsForGroup', {
+            httpMethod: "POST",
+            data: 
+            {
+                "GroupID": parseInt($("#SelectGroup").val()),
+                "ExamType": $("#ExamType:checked").val() 
+            },
+            successCallback: function () {
+
+            },
+            failCallback: function () {
+                EventInspector_ShowMsg('У выбранной группы отсутствуют дисциплины с зачетом', 'error');
+            }
+        });
+    });
+
+});
\ No newline at end of file