From 2840611709b44524ac8d8d97381afe4fb48eb3aa Mon Sep 17 00:00:00 2001
From: PavelBegunkov <asml.Silence@gmail.com>
Date: Wed, 10 Dec 2014 11:52:07 +0300
Subject: [PATCH] exam sql

---
 db/StoredProcedures.sql | 499 ++++++++++++++++++++++++++--------------
 db/Structure.sql        |   2 +-
 db/fix.sql              | 323 ++++++++++++++++++++++++--
 3 files changed, 622 insertions(+), 202 deletions(-)

diff --git a/db/StoredProcedures.sql b/db/StoredProcedures.sql
index 630024cbf..19e43cd15 100644
--- a/db/StoredProcedures.sql
+++ b/db/StoredProcedures.sql
@@ -143,18 +143,18 @@ CREATE FUNCTION `InternalIsMapCreated`		( 	`DisciplineID` INT
 											) 	RETURNS int(11)
     NO SQL
 BEGIN  
- 	DECLARE res INT;
- 	SET res = -1;
+	DECLARE res INT;
 
- 	SELECT SUM(submodules.MaxRate)
- 	INTO res
+	SELECT SUM(submodules.MaxRate) 
+	INTO res
 	FROM `modules`
-	LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID 
-	WHERE 	modules.DisciplineID = DisciplineID AND 
-	 		modules.Type != 3
+	LEFT JOIN `submodules` ON 	submodules.ModuleID = modules.ID
+	WHERE 	modules.DisciplineID = DisciplineID AND
+			(modules.Type = 1 OR ( modules.Type = 2 AND submodules.OrderNum = 1))
 	LIMIT 1;
 
-	RETURN (res IS NOT NULL AND res = 100);
+
+	RETURN (res = 100);
 END //
 
 
@@ -1247,32 +1247,32 @@ END //
 
 
 -- TODO: deprecated
-	-- DROP PROCEDURE IF EXISTS SearchTeachers//
-	-- CREATE PROCEDURE `SearchTeachers`		( 	IN `FacultyID` INT,
-	-- 											IN `DepartmentID` INT,
-	-- 											IN `Name` VARCHAR(100) CHARSET utf8 
-	-- 										)
-	--     NO SQL
-	-- BEGIN
-	-- 	SELECT 	teachers.ID 			AS 'TeacherID', 
-	-- 			teachers.LastName 		AS 'TeacherLast', 
-	-- 			teachers.FirstName 		AS 'TeacherFirst', 
-	-- 			teachers.SecondName		AS 'TeacherSecond', 
-	-- 			teachers.AccountID		AS 'TeacherAccID',
-	-- 			job_positions.Name 		AS 'JobPositionName', 
-	-- 			departments.ID 			AS 'DepID',
-	-- 			departments.Name 		AS 'DepName'
-	-- 	FROM `teachers`
-	-- 	INNER JOIN `departments` 	ON 	teachers.DepartmentID = departments.ID AND
-	-- 									( DepartmentID = 0 OR DepartmentID = departments.ID ) AND
-	-- 									FacultyID = departments.FacultyID 
-	-- 	INNER JOIN `job_positions` 	ON 	teachers.JobPositionID = job_positions.ID 
-	-- 	WHERE		CONCAT(teachers.LastName, teachers.FirstName, teachers.SecondName) LIKE CONCAT("%",Name,"%")
-	-- 	ORDER BY 	departments.FacultyID ASC, 
-	-- 				departments.Name ASC, 
-	-- 				teachers.LastName ASC, 
-	-- 				teachers.FirstName ASC, 
-	-- 				teachers.SecondName ASC;
+-- DROP PROCEDURE IF EXISTS SearchTeachers//
+-- CREATE PROCEDURE `SearchTeachers`		( 	IN `FacultyID` INT,
+-- 											IN `DepartmentID` INT,
+-- 											IN `Name` VARCHAR(100) CHARSET utf8 
+-- 										)
+--     NO SQL
+-- BEGIN
+-- 	SELECT 	teachers.ID 			AS 'TeacherID', 
+-- 			teachers.LastName 		AS 'TeacherLast', 
+-- 			teachers.FirstName 		AS 'TeacherFirst', 
+-- 			teachers.SecondName		AS 'TeacherSecond', 
+-- 			teachers.AccountID		AS 'TeacherAccID',
+-- 			job_positions.Name 		AS 'JobPositionName', 
+-- 			departments.ID 			AS 'DepID',
+-- 			departments.Name 		AS 'DepName'
+-- 	FROM `teachers`
+-- 	INNER JOIN `departments` 	ON 	teachers.DepartmentID = departments.ID AND
+-- 									( DepartmentID = 0 OR DepartmentID = departments.ID ) AND
+-- 									FacultyID = departments.FacultyID 
+-- 	INNER JOIN `job_positions` 	ON 	teachers.JobPositionID = job_positions.ID 
+-- 	WHERE		CONCAT(teachers.LastName, teachers.FirstName, teachers.SecondName) LIKE CONCAT("%",Name,"%")
+-- 	ORDER BY 	departments.FacultyID ASC, 
+-- 				departments.Name ASC, 
+-- 				teachers.LastName ASC, 
+-- 				teachers.FirstName ASC, 
+-- 				teachers.SecondName ASC;
 -- END //
 
 
@@ -1738,6 +1738,10 @@ END //
 
 
 
+
+
+
+
 -- -------------------------------------------------------------------------------------------
 -- Label: disciplines
 -- -------------------------------------------------------------------------------------------
@@ -1811,16 +1815,10 @@ BEGIN
 						teachers.SecondName 	AS 'Second', 
 						GetRateForDisc(StudentID, disciplines.ID ) 		AS 'Rate', 
 						GetMaxRateForDisc(disciplines.ID ) 				AS 'MaxCurrentRate',
-						InternalIsMapCreated(disciplines.ID)			AS 'isMapCreated',
-						rating_table.Rate 		AS 'ExamRate'
+						InternalIsMapCreated(disciplines.ID)			AS 'isMapCreated'
 	FROM `disciplines`
 	INNER JOIN 	`subjects` 			ON 	disciplines.SubjectID = subjects.ID 
-	INNER JOIN 	`teachers` 			ON 	disciplines.AuthorID = teachers.ID
-	LEFT JOIN 	`modules`			ON 	disciplines.ID = modules.DisciplineID AND
-										modules.Type = 2
-	LEFT JOIN 	`submodules` 		ON 	modules.ID = submodules.ModuleID
-	LEFT JOIN 	`rating_table`		ON 	submodules.ID = rating_table.SubmoduleID AND
-										rating_table.StudentID = StudentID									
+	INNER JOIN 	`teachers` 			ON 	disciplines.AuthorID = teachers.ID								
 	WHERE 	GetCurSemesterID() = disciplines.SemesterID AND 
 			InternalIsStudentAttached(StudentID, disciplines.ID)
 	ORDER BY disciplines.ExamType ASC, Rate DESC;    
@@ -1848,7 +1846,56 @@ BEGIN
 	INNER JOIN `modules` 		ON 	submodules.ModuleID = modules.ID AND 
 									DisciplineID = modules.DisciplineID
 	LEFT JOIN `rating_table` 	ON 	submodules.ID = rating_table.SubmoduleID AND 
-									StudentID = rating_table.StudentID  
+									StudentID = rating_table.StudentID 
+
+
+	WHERE 	modules.Type != 2 OR
+			submodules.ID = 
+				(	SELECT submodules.ID
+					FROM `submodules`
+					INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID
+					WHERE 	submodules.ModuleID = modules.ID AND
+							rating_table.StudentID = StudentID
+					ORDER BY submodules.OrderNum DESC
+					LIMIT 1
+				)  OR
+				((	SELECT submodules.ID
+					FROM `submodules`
+					INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID
+					WHERE 	submodules.ModuleID = modules.ID AND
+							rating_table.StudentID = StudentID
+					ORDER BY submodules.OrderNum DESC
+					LIMIT 1
+				) IS NULL AND submodules.OrderNum = 1)
+	ORDER BY 	modules.OrderNum ASC, 
+				submodules.OrderNum ASC;
+END //
+
+
+DROP PROCEDURE IF EXISTS GetMapForStudentExtra//
+CREATE PROCEDURE `GetMapForStudentExtra`	(	IN `StudentID` INT, 
+												IN `DisciplineID` INT
+											)
+	NO SQL
+BEGIN  
+	SELECT 	modules.ID 				AS 'ModuleID', 
+			modules.Name 			AS 'ModuleName', 
+			submodules.ID 			AS 'SubmoduleID', 
+			submodules.Name 		AS 'SubModuleName', 
+			submodules.Description 	AS 'SubmoduleDescription', 
+			submodules.MaxRate,
+			submodules.Type 		AS 'SubmoduleControl',
+			rating_table.Rate, 
+			rating_table.Date,
+			modules.Type 			AS 'ModuleType'
+	FROM `submodules`
+	INNER JOIN `modules` 		ON 	submodules.ModuleID = modules.ID AND 
+									DisciplineID = modules.DisciplineID
+	LEFT JOIN `rating_table` 	ON 	submodules.ID = rating_table.SubmoduleID AND 
+									StudentID = rating_table.StudentID 
+
+	WHERE 	modules.Type = 2 OR
+			modules.Type = 4
 	ORDER BY 	modules.OrderNum ASC, 
 				submodules.OrderNum ASC;
 END //
@@ -1880,13 +1927,47 @@ BEGIN
 		LEFT JOIN  `submodules` ON modules.ID = submodules.ModuleID
 		INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID
 		INNER JOIN `subjects` 	ON disciplines.SubjectID = subjects.ID
-		WHERE modules.DisciplineID = DisciplineID
+		WHERE 	modules.DisciplineID = DisciplineID AND
+				modules.Type != 4 AND
+				(modules.Type != 2 OR submodules.OrderNum = 1)
 		ORDER BY modules.OrderNum ASC, 
 				 submodules.OrderNum ASC;
  	END IF;
 END //
 
 
+DROP PROCEDURE IF EXISTS GetMapForDisciplineExtra//
+CREATE PROCEDURE `GetMapForDisciplineExtra`		(	IN `TeacherID` 		INT,
+													IN `DisciplineID` 	INT 
+												)
+    NO SQL
+BEGIN  
+	IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) 
+	THEN
+		SELECT 	NULL AS 'ID'
+		LIMIT 0;  
+	ELSE
+		SELECT 	subjects.ID 			AS 'SubjectID',
+				subjects.Name 			AS 'SubjectName',	
+				modules.ID 				AS 'ModuleID', 
+				modules.Name 			AS 'ModuleName', 
+				modules.Type  			AS 'ModuleType',
+				submodules.ID 			AS 'SubmoduleID', 
+				submodules.Name 		AS 'SubModuleName', 
+				submodules.Description 	AS 'SubmoduleDescription', 
+				submodules.MaxRate,
+				submodules.Type 		AS 'SubmoduleControl'
+		FROM `modules`
+		LEFT JOIN  `submodules` ON modules.ID = submodules.ModuleID
+		INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID
+		INNER JOIN `subjects` 	ON disciplines.SubjectID = subjects.ID
+		WHERE 	modules.DisciplineID = DisciplineID AND
+				modules.Type = 4 OR modules.Type = 2
+		ORDER BY modules.OrderNum ASC, 
+				 submodules.OrderNum ASC;
+ 	END IF;
+END //
+
 
 
 DROP PROCEDURE IF EXISTS GetDisciplineInfoByID//
@@ -2718,11 +2799,55 @@ BEGIN
 		RETURN -1; 
 	END IF;
 
+	SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl');
+	SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl');
 	SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl');
 	RETURN vModule;
 END //
 
 
+DROP FUNCTION IF EXISTS AddModuleExtra//
+CREATE FUNCTION `AddModuleExtra`	(	`TeacherID` 	INT, 
+										`DisciplineID` 	INT
+									) 	RETURNS int(11)
+    NO SQL
+BEGIN  
+    DECLARE checker, vModule INT;  					 	
+    IF 	NOT InternalIsTeacherAuthor(TeacherID,DisciplineID)
+    THEN
+    	RETURN -1;
+	END IF;
+
+	SET checker = -1;
+	SELECT modules.ID 
+	INTO checker
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4;
+	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
+	INTO vModule
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4
+	LIMIT 1;
+	IF vModule <= 0 THEN
+		RETURN -1; 
+	END IF;
+
+	SET checker = AddSubmodule(TeacherID, vModule, 6, '', NULL, 'LandmarkControl');
+	RETURN vModule;
+END //
+
 
 DROP FUNCTION IF EXISTS DeleteModule//
 CREATE FUNCTION `DeleteModule`	(	`TeacherID` INT,
@@ -3230,7 +3355,7 @@ CREATE FUNCTION `GetRateForDisc`	(	`StudentID` INT,
 									) 	RETURNS int(11)
     NO SQL
 BEGIN
-	DECLARE rate;
+	DECLARE rate INT;
 	SET rate = -1;
 
 	SELECT SUM(rating_table.Rate) 
@@ -3239,7 +3364,18 @@ BEGIN
 	INNER JOIN `submodules` ON 	rating_table.SubmoduleID = submodules.ID
 	INNER JOIN `modules`	ON 	submodules.ModuleID = modules.ID AND 
 								DisciplineID = modules.DisciplineID
-	WHERE 	rating_table.StudentID = StudentID
+	WHERE 	rating_table.StudentID = StudentID AND 
+			(	modules.Type != 2 OR
+				submodules.ID = 
+					(	SELECT submodules.ID
+						FROM `submodules`
+						INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID
+						WHERE 	submodules.ModuleID = modules.ID AND
+								rating_table.StudentID = StudentID
+						ORDER BY submodules.OrderNum DESC
+						LIMIT 1
+					) 
+			)
 	LIMIT 1;
 
 	RETURN 	rate;
@@ -3251,14 +3387,19 @@ CREATE FUNCTION `GetMaxRateForDisc`	(	`DisciplineID` INT
 									) 	RETURNS int(11)
     NO SQL
 BEGIN
-	RETURN 	(	SELECT SUM(submodules.MaxRate) 
-				FROM `modules`
-				LEFT JOIN `submodules` ON 	submodules.ModuleID = modules.ID
-				WHERE 	modules.DisciplineID = DisciplineID AND
-						submodules.isUsed != 0 AND
-						modules.Type != 3
-				LIMIT 1
-			);
+	DECLARE res INT;
+	SET res = 0;
+
+	SELECT SUM(submodules.MaxRate) 
+	INTO res
+	FROM `modules`
+	LEFT JOIN `submodules` ON 	submodules.ModuleID = modules.ID
+	WHERE 	modules.DisciplineID = DisciplineID AND
+			submodules.isUsed != 0 AND
+			(modules.Type = 1 OR ( modules.Type = 2 AND submodules.OrderNum = 1))
+	LIMIT 1;
+
+	RETURN 	(res);
 END //
 
 
@@ -3418,134 +3559,134 @@ END//
 
 
 -- DROP FUNCTION IF EXISTS SetRequestStatus//
-	-- CREATE FUNCTION `SetRequestStatus`	( 	`RequestID` INT,
-	-- 										`vStatus` VARCHAR(20) charset utf8
-	-- 									)	RETURNS int(11)
-	--     NO SQL
-	-- BEGIN
-	-- 	IF vStatus = "closed" THEN
-	-- 		INSERT INTO `requests_old`
-	-- 			(	requests.ID, requests.To, requests.From, 
-	-- 				requests.Field1, requests.Field2, requests.Field3, 
-	-- 				requests.Data, requests.DataExt, 
-	-- 				requests.Date, requests.Type, requests.Status
-	-- 			)
-	-- 					SELECT 	requests.ID, requests.To, requests.From, 
-	-- 							requests.Field1, requests.Field2, requests.Field3, 
-	-- 							requests.Data, requests.DataExt, 
-	-- 							requests.Date, requests.Type, 'closed' AS 'Status'
-	-- 					FROM `requests`
-	-- 					WHERE requests.ID = RequestID
-	-- 		LIMIT 1;
-
-	-- 		DELETE FROM `requests`
-	-- 		WHERE requests.ID = RequestID
-	-- 		LIMIT 1;
-
-
-
-	-- 	ELSE
-	-- 		UPDATE 	`requests`
-	-- 		SET requests.Status = vStatus
-	-- 		WHERE RequestID = requests.ID
-	-- 		LIMIT 1;
-	-- 	END IF;
-	-- 	RETURN 0;
-	-- END//
-
-
-	-- DROP PROCEDURE IF EXISTS GetRequests//
-	-- CREATE PROCEDURE `GetRequests`		( 	IN `AccountID` INT,
-	-- 										IN `Type` INT -- 0 to me, 1 - from me, 3 - all
-	-- 									)
-	--     NO SQL
-	-- BEGIN
-	-- 	SELECT 	requests.ID, 
-	-- 			requests.To, 
-	-- 			requests.From, 
-	-- 			requests.Field1, 
-	-- 			requests.Field2, 
-	-- 			requests.Field3, 
-	-- 			requests.Data, 
-	-- 			requests.DataExt, 
-	-- 			requests.Date, 
-	-- 			requests.Type, 
-	-- 			requests.Status
-	-- 	FROM `requests`
-	-- 	WHERE ((Type & 1) != 0 AND requests.To = AccountID) OR
-	-- 		  ((Type & 2) != 0 AND requests.From = AccountID)
-	--   	ORDER BY requests.To = AccountID DESC, requests.Type ASC, requests.ID ASC;
-	-- END//
-
-
-
-	-- DROP FUNCTION IF EXISTS RequestReport//
-	-- CREATE FUNCTION `RequestReport`		( 	`AccountID` INT,
-	-- 										`vTitle` VARCHAR(50) charset utf8,
-	-- 										`vDescription` TEXT charset utf8
-	-- 									)	RETURNS int(11)
-	--     NO SQL
-	-- BEGIN
-	-- 	INSERT INTO `requests`
-	-- 			(requests.To, requests.From, requests.Data, requests.DataExt, requests.Type)
-	-- 	VALUES	(0, AccountID, vDescription, vTitle, 4); -- 4 - report
-	-- 	RETURN LAST_INSERT_ID();
-	-- END//
+-- CREATE FUNCTION `SetRequestStatus`	( 	`RequestID` INT,
+-- 										`vStatus` VARCHAR(20) charset utf8
+-- 									)	RETURNS int(11)
+--     NO SQL
+-- BEGIN
+-- 	IF vStatus = "closed" THEN
+-- 		INSERT INTO `requests_old`
+-- 			(	requests.ID, requests.To, requests.From, 
+-- 				requests.Field1, requests.Field2, requests.Field3, 
+-- 				requests.Data, requests.DataExt, 
+-- 				requests.Date, requests.Type, requests.Status
+-- 			)
+-- 					SELECT 	requests.ID, requests.To, requests.From, 
+-- 							requests.Field1, requests.Field2, requests.Field3, 
+-- 							requests.Data, requests.DataExt, 
+-- 							requests.Date, requests.Type, 'closed' AS 'Status'
+-- 					FROM `requests`
+-- 					WHERE requests.ID = RequestID
+-- 		LIMIT 1;
+
+-- 		DELETE FROM `requests`
+-- 		WHERE requests.ID = RequestID
+-- 		LIMIT 1;
+
+
+
+-- 	ELSE
+-- 		UPDATE 	`requests`
+-- 		SET requests.Status = vStatus
+-- 		WHERE RequestID = requests.ID
+-- 		LIMIT 1;
+-- 	END IF;
+-- 	RETURN 0;
+-- END//
+
+
+-- DROP PROCEDURE IF EXISTS GetRequests//
+-- CREATE PROCEDURE `GetRequests`		( 	IN `AccountID` INT,
+-- 										IN `Type` INT -- 0 to me, 1 - from me, 3 - all
+-- 									)
+--     NO SQL
+-- BEGIN
+-- 	SELECT 	requests.ID, 
+-- 			requests.To, 
+-- 			requests.From, 
+-- 			requests.Field1, 
+-- 			requests.Field2, 
+-- 			requests.Field3, 
+-- 			requests.Data, 
+-- 			requests.DataExt, 
+-- 			requests.Date, 
+-- 			requests.Type, 
+-- 			requests.Status
+-- 	FROM `requests`
+-- 	WHERE ((Type & 1) != 0 AND requests.To = AccountID) OR
+-- 		  ((Type & 2) != 0 AND requests.From = AccountID)
+--   	ORDER BY requests.To = AccountID DESC, requests.Type ASC, requests.ID ASC;
+-- END//
+
+
+
+-- DROP FUNCTION IF EXISTS RequestReport//
+-- CREATE FUNCTION `RequestReport`		( 	`AccountID` INT,
+-- 										`vTitle` VARCHAR(50) charset utf8,
+-- 										`vDescription` TEXT charset utf8
+-- 									)	RETURNS int(11)
+--     NO SQL
+-- BEGIN
+-- 	INSERT INTO `requests`
+-- 			(requests.To, requests.From, requests.Data, requests.DataExt, requests.Type)
+-- 	VALUES	(0, AccountID, vDescription, vTitle, 4); -- 4 - report
+-- 	RETURN LAST_INSERT_ID();
+-- END//
 
 
 
-	-- DROP FUNCTION IF EXISTS RequestDelegateDiscipline//
-	-- CREATE FUNCTION `RequestDelegateDiscipline`	(	`AuthorID` INT,
-	-- 												`NewAuthorID` INT,
-	-- 												`DisciplineID` INT		
-	-- 							 				) 	RETURNS int(11)
-	--     NO SQL
-	-- BEGIN  
-	-- 	IF 	AuthorID = NewAuthorID OR
-	-- 		NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
-	-- 	THEN
-	-- 		RETURN -1;
-	-- 	END IF;
-
-	-- 	INSERT INTO `requests`
-	-- 		(requests.To, requests.From, requests.Field1, requests.Type)
-	-- 	VALUES	(NewAuthorID, AuthorID, DisciplineID, 1);
-	-- 	RETURN 0;
-	-- END //
-
-
-	-- DROP FUNCTION IF EXISTS RequestDeleteDiscipline//
-	-- CREATE FUNCTION `RequestDeleteDiscipline`	(	`AuthorID` INT,
-	-- 												`DisciplineID` INT		
-	-- 							 				) 	RETURNS int(11)
-	--     NO SQL
-	-- BEGIN  
-	-- 	IF  NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
-	-- 	THEN
-	-- 		RETURN -1;
-	-- 	END IF;
-
-	-- 	INSERT INTO `requests`
-	-- 		(requests.To, requests.From, requests.Field1, requests.Type)
-	-- 	VALUES	(0, AuthorID, DisciplineID, 2);
-	-- 	RETURN 0;
-	-- END //
-
-	-- DROP FUNCTION IF EXISTS RequestClearDiscipline//
-	-- CREATE FUNCTION `RequestClearDiscipline`	(	`AuthorID` INT,
-	-- 												`DisciplineID` INT		
-	-- 							 				) 	RETURNS int(11)
-	--     NO SQL
-	-- BEGIN  
-	-- 	IF  NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
-	-- 	THEN
-	-- 		RETURN -1;
-	-- 	END IF;
-
-	-- 	INSERT INTO `requests`
-	-- 		(requests.To, requests.From, requests.Field1, requests.Type)
-	-- 	VALUES	(0, AuthorID, DisciplineID, 3);
-	-- 	RETURN 0;
+-- DROP FUNCTION IF EXISTS RequestDelegateDiscipline//
+-- CREATE FUNCTION `RequestDelegateDiscipline`	(	`AuthorID` INT,
+-- 												`NewAuthorID` INT,
+-- 												`DisciplineID` INT		
+-- 							 				) 	RETURNS int(11)
+--     NO SQL
+-- BEGIN  
+-- 	IF 	AuthorID = NewAuthorID OR
+-- 		NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
+-- 	THEN
+-- 		RETURN -1;
+-- 	END IF;
+
+-- 	INSERT INTO `requests`
+-- 		(requests.To, requests.From, requests.Field1, requests.Type)
+-- 	VALUES	(NewAuthorID, AuthorID, DisciplineID, 1);
+-- 	RETURN 0;
+-- END //
+
+
+-- DROP FUNCTION IF EXISTS RequestDeleteDiscipline//
+-- CREATE FUNCTION `RequestDeleteDiscipline`	(	`AuthorID` INT,
+-- 												`DisciplineID` INT		
+-- 							 				) 	RETURNS int(11)
+--     NO SQL
+-- BEGIN  
+-- 	IF  NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
+-- 	THEN
+-- 		RETURN -1;
+-- 	END IF;
+
+-- 	INSERT INTO `requests`
+-- 		(requests.To, requests.From, requests.Field1, requests.Type)
+-- 	VALUES	(0, AuthorID, DisciplineID, 2);
+-- 	RETURN 0;
+-- END //
+
+-- DROP FUNCTION IF EXISTS RequestClearDiscipline//
+-- CREATE FUNCTION `RequestClearDiscipline`	(	`AuthorID` INT,
+-- 												`DisciplineID` INT		
+-- 							 				) 	RETURNS int(11)
+--     NO SQL
+-- BEGIN  
+-- 	IF  NOT InternalIsTeacherAuthor(AuthorID, DisciplineID)
+-- 	THEN
+-- 		RETURN -1;
+-- 	END IF;
+
+-- 	INSERT INTO `requests`
+-- 		(requests.To, requests.From, requests.Field1, requests.Type)
+-- 	VALUES	(0, AuthorID, DisciplineID, 3);
+-- 	RETURN 0;
 -- END //
 
 
diff --git a/db/Structure.sql b/db/Structure.sql
index e051d5e93..a5f9e7de0 100644
--- a/db/Structure.sql
+++ b/db/Structure.sql
@@ -226,7 +226,7 @@ CREATE TABLE IF NOT EXISTS `modules` (
   `Name` varchar(200) NOT NULL,
   `OrderNum` int(11) NOT NULL,
   `DisciplineID` int(11) NOT NULL,
-  `Type` enum('regular','exam','bonus') NOT NULL DEFAULT 'regular',
+  `Type` enum('regular','exam', 'bonus', 'extra') NOT NULL DEFAULT 'regular',
   PRIMARY KEY (`ID`),
   UNIQUE KEY `OrderNum` (`OrderNum`,`DisciplineID`),
   KEY `DisciplineID` (`DisciplineID`)
diff --git a/db/fix.sql b/db/fix.sql
index bf157872d..6ba58d896 100644
--- a/db/fix.sql
+++ b/db/fix.sql
@@ -1,34 +1,313 @@
 DELIMITER //
 
-CREATE TABLE IF NOT EXISTS `recovery_tokens` (
-  `ID` int(11) NOT NULL AUTO_INCREMENT,
-  `AccountID` int(11) NOT NULL,
-  `Date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  `Token` varchar(100) NOT NULL,
-  `isUsed`  tinyint(1) NOT NULL DEFAULT '0',
-  PRIMARY KEY (`ID`),
-  KEY `AccountID` (`AccountID`),
-  UNIQUE KEY `Token` (`Token`)
-) ENGINE=InnoDB  DEFAULT CHARSET=utf8//
+ALTER TABLE `modules` CHANGE `Type` `Type` enum('regular','exam', 'bonus', 'extra') NOT NULL DEFAULT 'regular'//
 
+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 = -1;
+	SELECT disciplines.ID 
+	INTO checker 
+	FROM `modules`
+	INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID
+	WHERE   TeacherID = disciplines.AuthorID AND
+			ModuleID = modules.ID 
+	LIMIT 1;
+	IF  checker <= 0
+	THEN
+			RETURN -1;
+	END IF;
 
-ALTER TABLE `recovery_tokens`
-  ADD CONSTRAINT `recovery_tokens_ibfk_1` FOREIGN KEY (`AccountID`) REFERENCES `accounts` (`ID`)//
 
+	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 INT;  					 	
+    IF 	NOT InternalIsTeacherAuthor(TeacherID,DisciplineID)
+    THEN
+    	RETURN -1;
+	END IF;
 
+	SET checker = -1;
+	SELECT modules.ID 
+	INTO checker
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4;
+	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
+	INTO vModule
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4
+	LIMIT 1;
+	IF vModule <= 0 THEN
+		RETURN -1; 
+	END IF;
+
+	SET checker = AddSubmodule(TeacherID, vModule, 6, '', 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 //
+
+
+
+
+
+SELECT  AddSubmodule(disciplines.AuthorID, modules.ID, 40, '', NULL, 'LandmarkControl') AS '1',
+		AddSubmodule(disciplines.AuthorID, modules.ID, 40, '', NULL, 'LandmarkControl') AS '2'
+FROM `modules`
+INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID
+WHERE modules.Type = 2//
+
+
+DELETE FROM `rating_table`
+WHERE rating_table.SubmoduleID IN 
+		(		SELECT submodules.ID
+				FROM `modules`
+				LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID
+				WHERE modules.Type = 2
+		)//
+
+
+SELECT AddModuleExtra(disciplines.AuthorID, disciplines.ID)
+FROM `disciplines`//
+
+
+
+
+
+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 = -1;
+	SELECT disciplines.ID 
+	INTO checker 
+	FROM `modules`
+	INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID
+	WHERE   TeacherID = disciplines.AuthorID AND
+			ModuleID = modules.ID 
+	LIMIT 1;
+	IF  checker <= 0 OR
+			InternalIsMapLocked(checker)
+	THEN
+			RETURN -1;
+	END IF;
+
+
+	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 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) OR
+    	InternalIsMapLocked(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 //
+
+
+DROP FUNCTION IF EXISTS AddModuleExtra//
+CREATE FUNCTION `AddModuleExtra`	(	`TeacherID` 	INT, 
+										`DisciplineID` 	INT
+									) 	RETURNS int(11)
+    NO SQL
+BEGIN  
+    DECLARE checker, vModule INT;  					 	
+    IF 	NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR
+    	InternalIsMapLocked(DisciplineID) 
+    THEN
+    	RETURN -1;
+	END IF;
+
+	SET checker = -1;
+	SELECT modules.ID 
+	INTO checker
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4;
+	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
+	INTO vModule
+	FROM `modules`
+	WHERE 	DisciplineID = modules.DisciplineID AND 
+			modules.Type = 4
+	LIMIT 1;
+	IF vModule <= 0 THEN
+		RETURN -1; 
+	END IF;
+
+	SET checker = AddSubmodule(TeacherID, vModule, 8, '', NULL, 'LandmarkControl');
+	RETURN vModule;
+END //
 
-ALTER TABLE `submodules`
-ADD `isUsed`  tinyint(1) NOT NULL DEFAULT '0'//
- 
-UPDATE `submodules`
-SET submodules.isUsed = 1
-WHERE submodules.ID IN 
-	(
-		SELECT DISTINCT rating_table.SubmoduleID
-		FROM `rating_table`
-	)//
 
 
 DELIMITER ;
\ No newline at end of file
-- 
GitLab