Skip to content

Commit

Permalink
Merge pull request AY2425S1-CS2103T-T11-2#110 from SwaminathanViswa/b…
Browse files Browse the repository at this point in the history
…ranch-markUnmarkCommand

Add mark and unmark command
  • Loading branch information
SwaminathanViswa authored Oct 24, 2024
2 parents 83670cd + 23dc063 commit f6cb5cb
Show file tree
Hide file tree
Showing 32 changed files with 832 additions and 45 deletions.
6 changes: 6 additions & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public class Messages {
public static final String MESSAGE_DUPLICATE_FIELDS =
"Multiple values specified for the following single-valued field(s): ";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_NAME = "The person name provided is invalid";
public static final String MESSAGE_MARK_SUCCESS = "%1$s is marked present for week %2$d";
public static final String MESSAGE_INVALID_WEEK = "Invalid week number.";
public static final String MESSAGE_MARK_ALREADY_SUCCESS = "Attendance is already marked for this student!";
public static final String MESSAGE_UNMARK_ALREADY_SUCCESS = "Attendance is already unmarked for this student";
public static final String MESSAGE_UNMARK_SUCCESS = "%1$s is marked as absent for week %2$d";


/**
* Returns an error message indicating the duplicate prefixes.
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/seedu/address/logic/commands/MarkCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_NAME;
import static seedu.address.logic.Messages.MESSAGE_MARK_ALREADY_SUCCESS;
import static seedu.address.logic.Messages.MESSAGE_MARK_SUCCESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_WEEK;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
* Marks a specific student as present for that particular week.
*/
public class MarkCommand extends Command {

public static final String COMMAND_WORD = "mark";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Marks the name as present for that particular "
+ "week. The max week number is 13.\n "
+ "Parameters: " + PREFIX_NAME + "NAME " + PREFIX_WEEK + "WEEK NUMBER "
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_NAME + "John Doe "
+ PREFIX_WEEK + "1";

public final int week;
private final Name name;

/**
* Constuctor for MarkCommand.
*
* @param name the name of the student to be marked
* @param week the week number in which the student is being marked as present
*/
public MarkCommand(Name name, int week) {
this.name = name;
this.week = week;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

Optional<Person> optionalPersonToMark = model.getPerson(name);
if (!optionalPersonToMark.isPresent()) {
throw new CommandException(String.format(MESSAGE_INVALID_PERSON_DISPLAYED_NAME, name));
}

Person personToMark = optionalPersonToMark.get();
Set<Integer> updatedWeeksPresent = new HashSet<>(personToMark.getWeeksPresent());

if (!updatedWeeksPresent.add(week)) {
return new CommandResult(String.format(MESSAGE_MARK_ALREADY_SUCCESS, name, week));
}

Person updatedPerson = new Person(
personToMark.getName(),
personToMark.getPhone(),
personToMark.getAddress(),
personToMark.getEmail(),
personToMark.getTelegram(),
personToMark.getGithub(),
personToMark.getAssignment(),
updatedWeeksPresent, // Updated weeks present
personToMark.getTags());

model.setPerson(personToMark, updatedPerson);

return new CommandResult(String.format(MESSAGE_MARK_SUCCESS, name, week));

}

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

// instanceof handles nulls
if (!(other instanceof MarkCommand)) {
return false;
}

MarkCommand otherMarkCommand = (MarkCommand) other;
return name.equals(otherMarkCommand.name) && week == otherMarkCommand.week;
}

@Override
public String toString() {
return String.format("MarkCommand{name=%s, week=%d}", name, week);
}
}
99 changes: 99 additions & 0 deletions src/main/java/seedu/address/logic/commands/UnmarkCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_NAME;
import static seedu.address.logic.Messages.MESSAGE_UNMARK_ALREADY_SUCCESS;
import static seedu.address.logic.Messages.MESSAGE_UNMARK_SUCCESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_WEEK;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
* Unmarks a specific student as present for that particular week.
* Marks the student as absent.
*/
public class UnmarkCommand extends Command {

public static final String COMMAND_WORD = "unmark";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Unmarks the name as present for that particular "
+ "week.\n "
+ "Parameters: " + PREFIX_NAME + "NAME" + PREFIX_WEEK + "WEEK NUMBER"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_NAME + "John Doe "
+ PREFIX_WEEK + "1";

public final int week;
private final Name name;

/**
* Constuctor for UnmarkCommand.
*
* @param name the name of the student to be unmarked
* @param week the week number
*/
public UnmarkCommand(Name name, int week) {
this.name = name;
this.week = week;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

Optional<Person> optionalPersonToUnmark = model.getPerson(name);
if (!optionalPersonToUnmark.isPresent()) {
throw new CommandException(String.format(MESSAGE_INVALID_PERSON_DISPLAYED_NAME, name));
}

Person personToUnmark = optionalPersonToUnmark.get();
Set<Integer> updatedWeeksPresent = new HashSet<>(personToUnmark.getWeeksPresent());

if (!updatedWeeksPresent.remove(week)) {
return new CommandResult(String.format(MESSAGE_UNMARK_ALREADY_SUCCESS, name, week));
}

Person updatedPerson = new Person(
personToUnmark.getName(),
personToUnmark.getPhone(),
personToUnmark.getAddress(),
personToUnmark.getEmail(),
personToUnmark.getTelegram(),
personToUnmark.getGithub(),
personToUnmark.getAssignment(),
updatedWeeksPresent, // Updated weeks present
personToUnmark.getTags());

model.setPerson(personToUnmark, updatedPerson);

return new CommandResult(String.format(MESSAGE_UNMARK_SUCCESS, name, week));
}

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

// instanceof handles nulls
if (!(other instanceof UnmarkCommand)) {
return false;
}

UnmarkCommand otherUnmarkCommand = (UnmarkCommand) other;
return name.equals(otherUnmarkCommand.name) && week == otherUnmarkCommand.week;
}

@Override
public String toString() {
return String.format("UnmarkCommand{name=%s, week=%d}", name, week);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ImportCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.MarkCommand;
import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.commands.UnmarkCommand;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -93,6 +95,11 @@ public Command parseCommand(String userInput) throws ParseException {
case FilterCommand.COMMAND_WORD:
return new FilterCommandParser().parse(arguments);

case MarkCommand.COMMAND_WORD:
return new MarkCommandParser().parse(arguments);

case UnmarkCommand.COMMAND_WORD:
return new UnmarkCommandParser().parse(arguments);
case SortCommand.COMMAND_WORD:
return new SortCommandParser().parse(arguments);

Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class CliSyntax {
public static final Prefix PREFIX_SCORE = new Prefix("s/");
public static final Prefix PREFIX_TELEGRAM = new Prefix("telegram/");
public static final Prefix PREFIX_GITHUB = new Prefix("github/");
public static final Prefix PREFIX_WEEK = new Prefix("w/");
public static final Prefix PREFIX_SORTORDER = new Prefix("order/");
public static final Prefix PREFIX_PATH = new Prefix("path/");
}
45 changes: 45 additions & 0 deletions src/main/java/seedu/address/logic/parser/MarkCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_WEEK;

import java.util.stream.Stream;

import seedu.address.logic.commands.MarkCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Name;

/**
* Parses input arguments and creates a new MarkCommand object
*/
public class MarkCommandParser implements Parser<MarkCommand> {

/**
* Parses the given {@code String} of arguments in the context of the seedu.address.logic.commands.MarkCommand
* and returns a seedu.address.logic.commands.MarkCommand object for execution.
*
* @throws ParseException if the user input does not conform the expected format
*/
public MarkCommand parse(String args) throws ParseException {
ArgumentMultimap argumentMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_WEEK);

if (!arePrefixesPresent(argumentMultimap, PREFIX_NAME, PREFIX_WEEK)
|| !argumentMultimap.getPreamble().isEmpty()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, MarkCommand.MESSAGE_USAGE)
);
}

argumentMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_WEEK);

Name name = ParserUtil.parseName(argumentMultimap.getValue(PREFIX_NAME).get());
int week = ParserUtil.parseWeek(argumentMultimap.getValue(PREFIX_WEEK).get());

return new MarkCommand(name, week);
}

private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
28 changes: 28 additions & 0 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.StringUtil;
import seedu.address.logic.Messages;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Address;
import seedu.address.model.person.Email;
Expand All @@ -23,6 +24,8 @@
public class ParserUtil {

public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";
// Assuming that a typical semester has 13 weeks.
public static final int MAX_WEEK = 13;

/**
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing
Expand Down Expand Up @@ -171,4 +174,29 @@ public static Github parseGithub(String username) throws ParseException {
}
return new Github(trimmedUsername);
}

/**
* Parses a {@code String week} into an {@code int}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code week} is invalid.
*/
public static int parseWeek(String week) throws ParseException {
requireNonNull(week);
String trimmedWeek = week.trim();

try {
int parsedWeek = Integer.parseInt(trimmedWeek);
if (parsedWeek < 0) {
throw new ParseException("Week number must be a non-negative integer.");
}
if (parsedWeek > MAX_WEEK) {
throw new ParseException("Week number cannot exceed 13.");
}
return parsedWeek;
} catch (NumberFormatException e) {
throw new ParseException(Messages.MESSAGE_INVALID_WEEK);
}
}

}
45 changes: 45 additions & 0 deletions src/main/java/seedu/address/logic/parser/UnmarkCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_WEEK;

import java.util.stream.Stream;

import seedu.address.logic.commands.UnmarkCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Name;

/**
* Parses input arguments and creates a new UnmarkCommand object
*/
public class UnmarkCommandParser implements Parser<UnmarkCommand> {

/**
* Parses the given {@code String} of arguments in the context of the seedu.address.logic.commands.UnmarkCommand
* and returns a seedu.address.logic.commands.UnmarkCommand object for execution.
*
* @throws ParseException if the user input does not conform the expected format
*/
public UnmarkCommand parse(String args) throws ParseException {
ArgumentMultimap argumentMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_WEEK);

if (!arePrefixesPresent(argumentMultimap, PREFIX_NAME, PREFIX_WEEK)
|| !argumentMultimap.getPreamble().isEmpty()) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, UnmarkCommand.MESSAGE_USAGE)
);
}

argumentMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_WEEK);

Name name = ParserUtil.parseName(argumentMultimap.getValue(PREFIX_NAME).get());
int week = ParserUtil.parseWeek(argumentMultimap.getValue(PREFIX_WEEK).get());

return new UnmarkCommand(name, week);
}

private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
Loading

0 comments on commit f6cb5cb

Please sign in to comment.