Skip to content

Commit

Permalink
Merge pull request #133 from VaishakAnand/attendance
Browse files Browse the repository at this point in the history
Add Attendance command
  • Loading branch information
ong-yinggao98 authored Oct 27, 2020
2 parents bdc5844 + 33cf49f commit 2a15b5b
Show file tree
Hide file tree
Showing 48 changed files with 1,850 additions and 129 deletions.
6 changes: 0 additions & 6 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,6 @@ General Format: `detail COMMAND_WORD STUDENT_INDEX PARAMETERS`
* The command affects the student at the specified `STUDENT_INDEX`.
* `STUDENT_INDEX` **must be a positive integer** 1, 2, 3, …​
* The format of `PARAMETERS` varies with each `COMMAND_WORD` as explained below.
* `detail add` adds the given additional detail to the student at the specified `STUDENT_INDEX`.
* `detail add` requires the following optional field: `[d/DETAIL_TEXT]`.
* `detail edit` edits the additional detail at the specified `DETAIL_INDEX`, for the student at the specified `STUDENT_INDEX`
* `detail edit` requires the following optional fields: `[i/DETAIL_INDEX] [d/DETAIL_TEXT]`.
* `detail delete` deletes the additional detail at the specified `DETAIL_INDEX`, for the student at the specified `STUDENT_INDEX`
* `detail delete` requires the following optional field: `[i/DETAIL_INDEX]`.

Examples:
* `detail add 1 d/Smart` adds the "Smart" detail to the 1st student in **Reeve**.
Expand Down
109 changes: 109 additions & 0 deletions src/main/java/seedu/address/logic/commands/AddAttendanceCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ATTENDANCE_DATE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ATTENDANCE_FEEDBACK;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ATTENDANCE_STATUS;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_STUDENTS;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.student.Student;
import seedu.address.model.student.academic.Attendance;

public class AddAttendanceCommand extends AttendanceCommand {

public static final String COMMAND_WORD = "add";
public static final String MESSAGE_USAGE = AttendanceCommand.COMMAND_WORD + " " + COMMAND_WORD
+ ": adds an Attendance to the student identified "
+ "by the index number used in the displayed student list. \n"
+ "Parameters: STUDENT_INDEX (must be a positive integer) "
+ PREFIX_ATTENDANCE_DATE + "LESSON_DATE " + PREFIX_ATTENDANCE_STATUS + "ATTENDANCE_STATUS "
+ PREFIX_ATTENDANCE_FEEDBACK + "FEEDBACK\n"
+ "Example: " + AttendanceCommand.COMMAND_WORD + " " + COMMAND_WORD + " 2 "
+ PREFIX_ATTENDANCE_DATE + "14/02/2020 " + PREFIX_ATTENDANCE_STATUS + "attended "
+ PREFIX_ATTENDANCE_FEEDBACK + "attentive";
public static final String MESSAGE_SUCCESS = "Attendance added for %s: %s";
public static final String MESSAGE_INVALID_ATTENDANCE_DATE =
"There is already an existing attendance for the entered date! Please use another date, or delete the "
+ "existing attendance before adding a new one.";
private static Logger logger = Logger.getLogger("Add Attendance Log");

private final Index index;
private final Attendance attendanceToAdd;

/**
* Creates an AddAdditionalDetailCommand to add the specified {@code AdditionalDetail} to the student
* at the specified {@code Index}.
*/
public AddAttendanceCommand(Index index, Attendance attendanceToAdd) {
requireAllNonNull(index, attendanceToAdd);
this.index = index;
this.attendanceToAdd = attendanceToAdd;
}

/**
* Executes the command and returns the result message.
*
* @param model {@code Model} which the command should operate on.
* @return feedback message of the operation result for display
* @throws CommandException If an error occurs during command execution.
*/
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
logger.log(Level.INFO, "Beginning command execution");

List<Student> lastShownList = model.getSortedStudentList();
if (index.getZeroBased() >= lastShownList.size()) {
logger.log(Level.WARNING, "Invalid student index input error");
throw new CommandException(Messages.MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX);
}
Student studentToAddAttendance = lastShownList.get(index.getZeroBased());

List<Attendance> attendanceList = new ArrayList<>(studentToAddAttendance.getAttendance());
this.updateAttendanceList(attendanceList);

Student updatedStudent = super.updateStudentAttendance(studentToAddAttendance, attendanceList);

model.setStudent(studentToAddAttendance, updatedStudent);
model.updateFilteredStudentList(PREDICATE_SHOW_ALL_STUDENTS);
logger.log(Level.INFO, "Execution complete");

return new CommandResult(String.format(MESSAGE_SUCCESS, updatedStudent.getName(), attendanceToAdd));
}

private List<Attendance> updateAttendanceList(List<Attendance> attendanceList) throws CommandException {
boolean containsAttendanceAtDate = attendanceList
.stream()
.anyMatch(attendance -> attendance.getLessonDate().equals(attendanceToAdd.getLessonDate()));

if (containsAttendanceAtDate) {
throw new CommandException(MESSAGE_INVALID_ATTENDANCE_DATE);
}
attendanceList.add(attendanceToAdd);
return attendanceList;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}

if (!(obj instanceof AddAttendanceCommand)) {
return false;
}

AddAttendanceCommand other = (AddAttendanceCommand) obj;
return index.equals(other.index) && attendanceToAdd.equals(other.attendanceToAdd);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public CommandResult execute(Model model) throws CommandException {
exams.add(toAdd);
Student updatedStudent = new Student(selectedStudent.getName(), selectedStudent.getPhone(),
selectedStudent.getSchool(), selectedStudent.getYear(), selectedStudent.getAdmin(),
selectedStudent.getQuestions(), exams);
selectedStudent.getQuestions(), exams, selectedStudent.getAcademic());
model.setStudent(selectedStudent, updatedStudent);
model.updateFilteredStudentList(PREDICATE_SHOW_ALL_STUDENTS);
return new CommandResult(String.format(MESSAGE_EXAM_ADDED_SUCCESS, updatedStudent.getName(), toAdd));
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/seedu/address/logic/commands/AttendanceCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package seedu.address.logic.commands;

import java.util.List;

import seedu.address.model.student.Student;
import seedu.address.model.student.academic.Academic;
import seedu.address.model.student.academic.Attendance;

public abstract class AttendanceCommand extends Command {

public static final String COMMAND_WORD = "attendance";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds or deletes an Attendance from a student in "
+ " Reeve. \n" + "SUPPORTED COMMANDS: add, delete";

/**
* Creates a new Student, with the provided attendance.
* @param studentToAddAttendance student to add attendance to.
* @param attendanceList new list of additional attendanceList.
* @return updated Student.
*/
public Student updateStudentAttendance(Student studentToAddAttendance, List<Attendance> attendanceList) {
Academic academicToAddAttendance = studentToAddAttendance.getAcademic();
Academic updatedAcademic = new Academic(attendanceList);
Student updatedStudent = new Student(studentToAddAttendance.getName(), studentToAddAttendance.getPhone(),
studentToAddAttendance.getSchool(), studentToAddAttendance.getYear(), studentToAddAttendance.getAdmin(),
studentToAddAttendance.getQuestions(), studentToAddAttendance.getExams(),
updatedAcademic);

return updatedStudent;
}
}
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/commands/CommandResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ public int hashCode() {
return Objects.hash(feedbackToUser, showHelp, exit, toggleStudentCard);
}

@Override
public String toString() {
return this.feedbackToUser;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ATTENDANCE_DATE;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_STUDENTS;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.student.Student;
import seedu.address.model.student.academic.Attendance;

public class DeleteAttendanceCommand extends AttendanceCommand {

public static final String COMMAND_WORD = "delete";
public static final String MESSAGE_USAGE = AttendanceCommand.COMMAND_WORD + " " + COMMAND_WORD
+ ": deletes an Attendance from the student identified "
+ "by the date of the lesson. \n"
+ "Parameters: STUDENT_INDEX (must be a positive integer) "
+ PREFIX_ATTENDANCE_DATE + "LESSON_DATE\n"
+ "Example: " + AttendanceCommand.COMMAND_WORD + " " + COMMAND_WORD + " 2 "
+ PREFIX_ATTENDANCE_DATE + "14/02/2020";
public static final String MESSAGE_SUCCESS = "Attendance deleted for %s for the date of %s";
public static final String MESSAGE_INVALID_ATTENDANCE_DATE = "There is no existing attendance for the entered date";

private static Logger logger = Logger.getLogger("Delete Attendance Log");

private final Index index;
private final LocalDate attendanceDate;

/**
* Creates an EditAdditionalDetailCommand to add the specified {@code AdditionalDetail} to the student
* at the specified {@code Index}.
*/
public DeleteAttendanceCommand(Index index, LocalDate attendanceDate) {
requireAllNonNull(index, attendanceDate);
this.index = index;
this.attendanceDate = attendanceDate;
}

/**
* Executes the command and returns the result message.
*
* @param model {@code Model} which the command should operate on.
* @return feedback message of the operation result for display
* @throws CommandException If an error occurs during command execution.
*/
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
logger.log(Level.INFO, "Beginning command execution");

List<Student> lastShownList = model.getSortedStudentList();
if (index.getZeroBased() >= lastShownList.size()) {
logger.log(Level.WARNING, "Invalid student index input error");
throw new CommandException(Messages.MESSAGE_INVALID_STUDENT_DISPLAYED_INDEX);
}
Student studentToDeleteAttendance = lastShownList.get(index.getZeroBased());

List<Attendance> attendanceList = new ArrayList<>(studentToDeleteAttendance.getAttendance());
List<Attendance> updatedAttendanceList = this.updateAttendanceList(attendanceList);

Student updatedStudent = super.updateStudentAttendance(studentToDeleteAttendance, updatedAttendanceList);

model.setStudent(studentToDeleteAttendance, updatedStudent);
model.updateFilteredStudentList(PREDICATE_SHOW_ALL_STUDENTS);
logger.log(Level.INFO, "Execution complete");

return new CommandResult(String.format(MESSAGE_SUCCESS, updatedStudent.getName(), getUserInputDateString()));
}

private List<Attendance> updateAttendanceList(List<Attendance> attendanceList) throws CommandException {
boolean containsAttendanceAtDate = attendanceList
.stream()
.anyMatch(attendance -> attendance.getLessonDate().equals(attendanceDate));

if (!containsAttendanceAtDate) {
throw new CommandException(MESSAGE_INVALID_ATTENDANCE_DATE);
}

Stream<Attendance> matchingAttendance = attendanceList.stream()
.filter(attendance -> attendance.getLessonDate().equals(attendanceDate));
Attendance attendanceToDelete = matchingAttendance.findFirst().get();
attendanceList.remove(attendanceToDelete);

return attendanceList;
}

private String getUserInputDateString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy");
return attendanceDate.format(formatter);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}

if (!(obj instanceof DeleteAttendanceCommand)) {
return false;
}

DeleteAttendanceCommand other = (DeleteAttendanceCommand) obj;
return index.equals(other.index) && attendanceDate.equals(other.attendanceDate);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public Student updateStudentDetail(Student studentToAddDetail, List<Detail> deta
adminToAddDetail.getFee(), adminToAddDetail.getPaymentDate(), details);
Student updatedStudent = new Student(studentToAddDetail.getName(), studentToAddDetail.getPhone(),
studentToAddDetail.getSchool(), studentToAddDetail.getYear(), updatedAdmin,
studentToAddDetail.getQuestions(), studentToAddDetail.getExams());
studentToAddDetail.getQuestions(), studentToAddDetail.getExams(), studentToAddDetail.getAcademic());

return updatedStudent;
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import seedu.address.model.student.School;
import seedu.address.model.student.Student;
import seedu.address.model.student.Year;
import seedu.address.model.student.academic.Academic;
import seedu.address.model.student.academic.exam.Exam;
import seedu.address.model.student.admin.Admin;
import seedu.address.model.student.admin.ClassTime;
Expand Down Expand Up @@ -136,7 +137,10 @@ private static Student createEditedStudent(Student studentToEdit, EditStudentDes
List<Question> questions = studentToEdit.getQuestions();
// Exams should not be edited through this command
List<Exam> exams = studentToEdit.getExams();
return new Student(updatedName, updatedPhone, updatedSchool, updatedYear, updatedAdmin, questions, exams);
// Academic should not be edited through this command
Academic academic = studentToEdit.getAcademic();
return new Student(updatedName, updatedPhone, updatedSchool, updatedYear, updatedAdmin, questions, exams,
academic);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ public abstract class ExamCommand extends Command {
public Student updateStudentExam(Student studentToUpdate, ArrayList<Exam> exams) {
return new Student(studentToUpdate.getName(), studentToUpdate.getPhone(),
studentToUpdate.getSchool(), studentToUpdate.getYear(), studentToUpdate.getAdmin(),
studentToUpdate.getQuestions(), exams);
studentToUpdate.getQuestions(), exams, studentToUpdate.getAcademic());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import seedu.address.model.student.School;
import seedu.address.model.student.Student;
import seedu.address.model.student.Year;
import seedu.address.model.student.academic.Academic;
import seedu.address.model.student.academic.Attendance;
import seedu.address.model.student.academic.exam.Exam;
import seedu.address.model.student.admin.Admin;
import seedu.address.model.student.admin.ClassTime;
Expand Down Expand Up @@ -63,12 +65,14 @@ public AddCommand parse(String args) throws ParseException {
Fee fee = ParserUtil.parseFee(argMultimap.getValue(PREFIX_FEE).get());
PaymentDate paymentDate = ParserUtil.parsePaymentDate(argMultimap.getValue(PREFIX_PAYMENT).orElse(TODAY));
List<Detail> detailList =
ParserUtil.parseAdditionalDetails(argMultimap.getAllValues(PREFIX_DETAILS));
ParserUtil.parseDetails(argMultimap.getAllValues(PREFIX_DETAILS));

Admin admin = new Admin(classVenue, classTime, fee, paymentDate, detailList);
List<Question> questions = new ArrayList<>();
ArrayList<Exam> exams = new ArrayList<>();
Student student = new Student(name, phone, school, year, admin, questions, exams);
List<Attendance> attendanceList = new ArrayList<>();
Academic academic = new Academic(attendanceList);
Student student = new Student(name, phone, school, year, admin, questions, exams, academic);
return new AddCommand(student);
}

Expand Down
Loading

0 comments on commit 2a15b5b

Please sign in to comment.