Просмотр исходного кода

+ Added EditGradesCommand
+ Finally make some progress

BlackPhreak 6 лет назад
Родитель
Сommit
520e020a77

+ 76 - 0
src/me/blackphreak/CommandHandling/AbstractEditCommandHandler.java

@@ -0,0 +1,76 @@
+package me.blackphreak.CommandHandling;
+
+import me.blackphreak.Database;
+import me.blackphreak.Debug.Debug;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static me.blackphreak.Lib.promptQuestion;
+
+public abstract class AbstractEditCommandHandler extends AbstractCommandHandler {
+	protected String lastCmd;
+	protected List<String> selectedStudentID;
+	
+	protected AbstractEditCommandHandler(String desc) {
+		super(desc);
+	}
+	
+	/**
+	 * Ask user to provide student ID before editing the targeted student(s).
+	 * @return true when selected at least one student, otherwise, false.
+	 */
+	protected boolean selectStudentByID(boolean allowMultiple) {
+		// reset
+		selectedStudentID = new ArrayList<>();
+		lastCmd = null;
+		
+		do {
+			if (allowMultiple)
+				System.out.println("\n** type \"next\" to stop providing StudentID **");
+			System.out.println("** type \"exit\" to back to main menu **");
+			
+			if (allowMultiple)
+				System.out.println("\nSelected StudentID(#"+selectedStudentID.size()+"): " + Arrays.toString(selectedStudentID.toArray()));
+			
+			var inp = promptQuestion("Please provide StudentID: ", false);
+			
+			if (allowMultiple && inp.equalsIgnoreCase("next"))
+			{
+				if (selectedStudentID.size() <= 0)
+					System.out.println("Please provide at least one student ID before edit.");
+				else
+					return true;
+			}
+			else if (inp.equalsIgnoreCase("exit"))
+			{
+				lastCmd = "exit";  // back to main menu
+				return false;
+			}
+			else
+			{
+				// query database to confirm that student is exist.
+				try {
+					if (Database.getInstance()
+							.query("SELECT COUNT(*) FROM Student WHERE StudentID = \""+inp+"\";")
+							.getInt(1) != 1)
+					{
+						System.out.println("Invalid StudentID, please try again. [Failed to select (!=1)]");
+						continue;
+					}
+				} catch (SQLException e) {
+					Debug.err("Failed to find student. (Database Error)");
+					e.printStackTrace();
+					lastCmd = "end";  // end the program
+					return false;
+				}
+				
+				selectedStudentID.add(inp);
+			}
+		} while (allowMultiple);
+		
+		return true;
+	}
+}

+ 1 - 1
src/me/blackphreak/CommandHandling/CommandManager.java

@@ -10,6 +10,6 @@ public class CommandManager {
 		CommandHandler.registerHandler("Search Student",    new SearchStudentCommand("Search student(s) from database with condition(s)"));
 		CommandHandler.registerHandler("Create Student",    new CreateStudentCommand("Insert a new student record to database"));
 		CommandHandler.registerHandler("Edit Student",      new EditStudentCommand("Modify a information of selected student"));
-		CommandHandler.registerHandler("Edit Grades",       new EditGradesCommand("Modify grades of a selected student"));
+		CommandHandler.registerHandler("Edit Grades & Subjects",       new EditGradesCommand("Modify grades & subjects of a selected student"));
 	}
 }

+ 312 - 3
src/me/blackphreak/CommandHandling/Handlers/EditGradesCommand.java

@@ -1,16 +1,325 @@
 package me.blackphreak.CommandHandling.Handlers;
 
-import me.blackphreak.CommandHandling.AbstractCommandHandler;
+import me.blackphreak.CommandHandling.AbstractEditCommandHandler;
+import me.blackphreak.Database;
+import me.blackphreak.Debug.Debug;
+import me.blackphreak.Grade.Grade;
+import me.blackphreak.Lib;
 
-public class EditGradesCommand extends AbstractCommandHandler {
+import java.sql.SQLException;
+import java.util.HashMap;
+
+import static me.blackphreak.Lib.promptQuestion;
+import static me.blackphreak.Lib.tryParseUInt;
+
+public class EditGradesCommand extends AbstractEditCommandHandler {
+	private HashMap<Integer, Grade> gradeMap;
+	private HashMap<Integer, String> subjMap = new HashMap<>();
 	
 	public EditGradesCommand(String desc) {
 		super(desc);
+		
+		try {
+			// query db to get all subjects
+			var result = Database.getInstance()
+					.query("SELECT SubjectID, Name FROM Subject;");
+			while (result.next()) {
+				subjMap.put(
+						result.getInt("SubjectID"),
+					result.getString("Name")
+				);
+			}
+		}
+		catch (SQLException e) {
+			Debug.err("Failed to fetch all subjects. [Database Error]");
+			e.printStackTrace();
+			Database.getInstance().close();
+			System.exit(1);  // exit with status code: 1
+		}
 	}
 	
 	@Override
 	public boolean handle() {
+		boolean nextFlag;
+		
+		do
+		{
+			nextFlag = selectStudentByID(false);
+			
+			// if lastCmd is set.
+			if (lastCmd != null) {
+				// in this case, lastCmd should be either "exit" nor "end".
+				return lastCmd.equalsIgnoreCase("exit");
+			}
+		} while (!nextFlag);
+		
+		return selectActionMenu();
+	}
+	
+	private boolean selectActionMenu() {
+		do {
+			int i = 1;
+			System.out.println(String.format(
+					"  %2s. %s",
+					(i++) + "",
+					"Edit Subjects"
+			));
+			
+			System.out.println(String.format(
+					"  %2s. %s",
+					(i++) + "",
+					"Edit Grades"
+			));
+			
+			// exit option
+			System.out.println(String.format(
+					"  %2s. %15s",
+					"99",
+					"Back to main menu"
+			));
+			
+			var inp = promptQuestion("Please select an action: ");
+			var selected = tryParseUInt(inp, "Invalid action number");
+			if (selected == -1)
+				continue;
+			
+			if (selected == 99)
+				return true;
+			
+			// get grade map from db
+			try {
+				gradeMap = Lib.dbToGradeMap(selectedStudentID.get(0));
+			} catch (SQLException e) {
+				Debug.err("Failed to parse to Subjects Map. [Database Error]");
+				e.printStackTrace();
+				return false;
+			}
+			
+			switch (selected) {
+				case 1:
+					return editSubjectMenu();
+				case 2:
+					return editGradeMenu();
+				default:
+					System.out.println("Invalid action!");
+			}
+		} while (true);
+	}
+	
+	private boolean editSubjectMenu() {
+		boolean endFlag;
+		do {
+			printCurrentSubjects();
+			
+			endFlag = selectAndEditSubject();
+		} while (!endFlag);
+		
+		return true;
+	}
+	
+	private void printCurrentSubjects() {
+		System.out.println("| Registered | SubjectID | Subject Name");
+		System.out.println("|------------|-----------|----------------->>");
+		
+		subjMap.forEach((id, name) ->
+				System.out.println(String.format(
+						"| %-5s | %9s | %s",
+						gradeMap.containsKey(id) ? "✓" : "✕",
+						id + "",
+						name
+				))
+		);
+		
+		System.out.println("|------------|------------|----------------->>");
+	}
+	
+	private boolean selectAndEditSubject() {
+		do {
+			var inp = promptQuestion("Please provide SubjectID before edit: ");
+			var sid = tryParseUInt(inp, "Invalid subjectID. [Parse Failed]");
+			
+			if (sid == -1)
+				continue;
+			
+			if (!subjMap.containsKey(sid)) {
+				System.out.println("Invalid subjectID. [Subject does not exist]");
+				continue;
+			}
+			
+			if (gradeMap.containsKey(sid)) {
+				System.out.println("This subject is already registered for this student.");
+				
+				// update subject. (del-reg)
+				var confirmation = promptQuestion("Are you sure to deregister subject["+sid+"] for student["+selectedStudentID.get(0)+"]? [confirm / No]");
+				if (confirmation.equals("confirm"))
+				{
+					Database.getInstance().update(String.format(
+							"DELETE FROM Grade WHERE StudentID = \"%s\" AND SubjectID = \"%d\"",
+							selectedStudentID.get(0),
+							sid
+					));
+					
+					System.out.println("Deregistered "+sid+" for student["+selectedStudentID.get(0)+"].");
+				}
+				else
+					System.out.println("No changes have been made.");
+			}
+			else
+			{
+				System.out.println("Registering new subject for student["+selectedStudentID.get(0)+"]");
+				
+				var obj = new Grade();
+				
+				Database.getInstance().update(String.format(
+						"INSERT INTO Grade (StudentID, SubjectID, Grade, Sem, InProgress) VALUES (\"%s\", \"%d\", \"%s\", \"%d\", \"%d\");",
+						selectedStudentID.get(0),
+						sid,
+						obj.getGrade(),
+						obj.getSem(),
+						obj.isInProgress() ? 1 : 0
+				));
+				
+				System.out.println("Registered new subject["+sid+"] for student["+selectedStudentID.get(0)+"]");
+			}
+			
+			var contin = promptQuestion("Would you like to continue edit Subject for the same student? [Y/n]");
+			return !contin.equalsIgnoreCase("n");
+		} while (true);
+	}
+	
+	// end of subject editing
+	
+	private boolean editGradeMenu() {
+		boolean endFlag;
+		do {
+			printCurrentGrades();
+			
+			endFlag = selectAndEditGrade();
+		} while (!endFlag);
+		
+		return true;
+	}
+	
+	private void printCurrentGrades() {
+		System.out.println("| SubjectID | Grade | Semester | InProgress | SubjectName");
+		System.out.println("|-----------|-------|----------|------------|--------------->>");
+		gradeMap.forEach((id, obj) -> System.out.println(String.format(
+				"| %9s | %5s | %8s | %10s | %s",
+				id + "",
+				obj.getGrade(),
+				obj.getSem(),
+				obj.isInProgress(),
+				subjMap.get(id)
+		)));
+		System.out.println("|-----------|-------|----------|------------|--------------->>");
+	}
+	
+	private boolean selectAndEditGrade() {
+		var subjID = -1;
+		do {
+			var inp = promptQuestion("Please provide SubjectID that you want to edit: ");
+			subjID = tryParseUInt(inp, "Invalid SubjectID. [Parse Failed]");
+			if (subjID == -1) {
+				continue;
+			}
+			
+			if (!gradeMap.containsKey(subjID))
+			{
+				System.out.println("Invalid SubjectID. [Does not exist]");
+			}
+		} while (subjID != -1);
+		
+		var selected = gradeMap.get(subjID);
+		boolean done = false;
+		
+		// print menu
+		do {
+			System.out.println("Columns:");
+			int i = 1;
+			System.out.println(String.format(
+					"  %2s. %s",
+					i++ + "",
+					"Grade"
+			));
+			System.out.println(String.format(
+					"  %2s. %s",
+					i++ + "",
+					"Semester"
+			));
+			System.out.println(String.format(
+					"  %2s. %s",
+					i++ + "",
+					"In Progress"
+			));
+			
+			var inp = promptQuestion("Please select a column to edit: ");
+			var col = tryParseUInt(inp, "Invalid column index. [Parse Failed]");
+			if (col == -1)
+				continue;
+			
+			switch (col) {
+				case 1:
+				{
+					var newGrade = promptQuestion("    Please provide new grade: ");
+					if (!newGrade.matches("^[A-F,0]$"))
+					{
+						System.out.println("Invalid grade. (Must within these: A, B, C, D, E, F / 0)");
+						continue;
+					}
+					
+					selected.setGrade(newGrade.equals("0") ? null : newGrade);
+					done = true;
+					break;
+				}
+				case 2:
+				{
+					var newSem = promptQuestion("    Please provide new semester: ");
+					if (!newSem.matches("^[0-9]{1,2}$"))
+					{
+						System.out.println("Invalid semester. (Min: 0, Max: 99)");
+						continue;
+					}
+					
+					selected.setSem(tryParseUInt(newSem));
+					done = true;
+					break;
+				}
+				case 3:
+				{
+					var isInProgress = promptQuestion("    Please provide new progress status [Y: in progress / N: Finished]: ");
+					if (!isInProgress.matches("^[YN]$"))
+					{
+						System.out.println("Invalid progress status. (Must be: Y / N)");
+						continue;
+					}
+					
+					selected.setInProgress(isInProgress.equals("Y"));
+					done = true;
+					break;
+				}
+				default:
+					System.out.println("Invalid column index. [Default Caught]");
+			}
+			
+		} while (!done);
+		
+		// update the database
+		gradeMap.forEach((id, o) -> {
+			if (!o.haveChanges)
+				return;
+			
+			Database.getInstance().update(String.format(
+				"UPDATE Grade SET Sem = \"%d\", Grade = \"%s\", InProgress = \"%d\" "
+						+ "WHERE SubjectID = \"%d\" AND StudentID = \"%s\";",
+				o.getSem(),
+				o.getGrade(),
+				o.isInProgress() ? 1 : 0,
+				id,
+				selectedStudentID.get(0)
+			));
+		});
 		
-		return false;
+		var inp = promptQuestion("Want to update another grade? [y/N]: ");
+		return inp.equalsIgnoreCase("y");
 	}
 }

+ 3 - 60
src/me/blackphreak/CommandHandling/Handlers/EditStudentCommand.java

@@ -1,20 +1,12 @@
 package me.blackphreak.CommandHandling.Handlers;
 
-import me.blackphreak.CommandHandling.AbstractCommandHandler;
+import me.blackphreak.CommandHandling.AbstractEditCommandHandler;
 import me.blackphreak.Database;
-import me.blackphreak.Debug.Debug;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 
 import static me.blackphreak.Lib.promptQuestion;
 import static me.blackphreak.Lib.tryParseUInt;
 
-public class EditStudentCommand extends AbstractCommandHandler {
-	private String lastCmd;
-	private List<String> selectedStudentID;
+public class EditStudentCommand extends AbstractEditCommandHandler {
 	private String selectedColumn;
 	
 	public EditStudentCommand(String desc) {
@@ -24,14 +16,11 @@ public class EditStudentCommand extends AbstractCommandHandler {
 	@Override
 	public boolean handle() {
 		boolean nextFlag;
-		// reset
-		selectedStudentID = new ArrayList<>();
-		lastCmd = null;
 		selectedColumn = null;
 		
 		do
 		{
-			nextFlag = selectStudentByID();
+			nextFlag = selectStudentByID(false);
 			
 			// if lastCmd is set.
 			if (lastCmd != null) {
@@ -53,52 +42,6 @@ public class EditStudentCommand extends AbstractCommandHandler {
 		return true;
 	}
 	
-	/**
-	 * Ask user to provide student ID before editing the targeted student(s).
-	 * @return true when selected at least one student, otherwise, false.
-	 */
-	private boolean selectStudentByID() {
-		do {
-			System.out.println("\n** type \"next\" to stop providing StudentID **");
-			System.out.println("** type \"exit\" to back to main menu **");
-			System.out.println("\nSelected StudentID(#"+selectedStudentID.size()+"): " + Arrays.toString(selectedStudentID.toArray()));
-			var inp = promptQuestion("Please provide StudentID: ", false);
-			
-			if (inp.equalsIgnoreCase("next"))
-			{
-				if (selectedStudentID.size() <= 0)
-					System.out.println("Please provide at least one student ID before edit.");
-				else
-					return true;
-			}
-			else if (inp.equalsIgnoreCase("exit"))
-			{
-				lastCmd = "exit";  // back to main menu
-				return false;
-			}
-			else
-			{
-				// query database to confirm that student is exist.
-				try {
-					if (Database.getInstance()
-						.query("SELECT COUNT(*) FROM Student WHERE StudentID = \""+inp+"\";")
-						.getInt(1) != 1)
-					{
-						System.out.println("Invalid StudentID, please try again. [Failed to select (!=1)]");
-						continue;
-					}
-				} catch (SQLException e) {
-					Debug.err("Failed to find student. (Database Error)");
-					e.printStackTrace();
-					lastCmd = "end";  // end the program
-					return false;
-				}
-				
-				selectedStudentID.add(inp);
-			}
-		} while (true);
-	}
-	
 	private boolean selectColumnToBeModified() {
 		do {
 			System.out.println("\nColumns:");

+ 106 - 0
src/me/blackphreak/Grade/Grade.java

@@ -0,0 +1,106 @@
+package me.blackphreak.Grade;
+
+import static me.blackphreak.Lib.promptQuestion;
+import static me.blackphreak.Lib.tryParseUInt;
+
+public class Grade {
+	private String _grade;
+	private int _sem;
+	private boolean _inProgress;
+	public boolean haveChanges = false;
+	
+	public Grade(String grade, int semester, boolean isInProgress) {
+		this._grade = grade;
+		this._sem = semester;
+		this._inProgress = isInProgress;
+	}
+	
+	public Grade() {
+		do {
+			var inp = promptQuestion("    That student still studying in this subject? [Y/N]");
+			if (inp.equalsIgnoreCase("y"))
+			{
+				this._inProgress = true;
+				break;
+			}
+			else if (inp.equalsIgnoreCase("n"))
+			{
+				this._inProgress = false;
+				break;
+			}
+			else
+				System.out.println("Invalid input. Try again.");
+		} while (true);
+		
+		if (!this._inProgress)
+		{
+			do {
+				var grade = promptQuestion("    What grade the student get in this subject? ");
+				if (grade.matches("^[A-F]$"))
+				{
+					this._grade = grade;
+					break;
+				}
+				
+				System.out.println("Out of range. Must be within [A, B, C, D, E, F]");
+			} while (true);
+		}
+		
+		do {
+			var inp = promptQuestion("    Which semester this student study this subject? ");
+			var sem = tryParseUInt(inp, "Invalid number. [Parse Failed]");
+			
+			if (sem == -1)
+				continue;
+			
+			if (sem < 0 || sem > 99)
+			{
+				System.out.println("Out of range. Must be within 1 - 99.");
+				continue;
+			}
+			
+			this._sem = sem;
+			break;
+		} while (true);
+		
+		this.haveChanges = true;
+	}
+	
+	
+	
+	public String getGrade() {
+		return _grade;
+	}
+	
+	public void setGrade(String _grade) {
+		if (this._grade.equals(_grade))
+			return;
+		
+		this._grade = _grade;
+		this.haveChanges = true;
+	}
+	
+	public int getSem() {
+		return _sem;
+	}
+	
+	public void setSem(int _sem) {
+		if (this._sem == _sem)
+			return;
+		
+		this._sem = _sem;
+		this.haveChanges = true;
+	}
+	
+	public boolean isInProgress() {
+		return _inProgress;
+	}
+	
+	public void setInProgress(boolean _inProgress) {
+		if (this._inProgress == _inProgress)
+			return;
+		
+		this._inProgress = _inProgress;
+		this.haveChanges = true;
+	}
+}

+ 19 - 0
src/me/blackphreak/Lib.java

@@ -3,6 +3,7 @@ package me.blackphreak;
 import com.google.gson.Gson;
 import me.blackphreak.Debug.Debug;
 import me.blackphreak.Debug.DebugLevel;
+import me.blackphreak.Grade.Grade;
 import me.blackphreak.Student.AbstractStudent;
 import me.blackphreak.Student.Types.LocalStudent;
 import me.blackphreak.Student.Types.OverseaStudent;
@@ -10,6 +11,8 @@ import me.blackphreak.Student.Types.OverseaStudent;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.sql.SQLException;
+import java.util.HashMap;
 
 public class Lib {
 	private static BufferedReader reader = new BufferedReader(
@@ -66,4 +69,20 @@ public class Lib {
 		}
 		return retn;
 	}
+	
+	public static HashMap<Integer, Grade> dbToGradeMap(String stuID) throws SQLException {
+		var map = new HashMap<Integer, Grade>();
+		var result = Database.getInstance()
+				.query("SELECT SubjectID, Grade, Sem, InProgress FROM grade WHERE StudentID = \""+stuID+"\";");
+		while (result.next()) {
+			// parse to Grade obj.
+			var subjectID = result.getInt("SubjectID");
+			var grade = result.getString("Grade");
+			var sem = result.getInt("Sem");
+			var inProgress = result.getBoolean("InProgress");
+			
+			map.put(subjectID, new Grade(grade, sem, inProgress));
+		}
+		return map;
+	}
 }