Skip to content

Commit

Permalink
Merge branch 'Edit-UI' of https://github.com/qinxutan/tp into Edit-UI
Browse files Browse the repository at this point in the history
* 'Edit-UI' of https://github.com/qinxutan/tp:
  Create tutorial teams (AY2324S2-CS2103T-T09-4#108)
  • Loading branch information
qinxutan committed Mar 25, 2024
2 parents f18d7f8 + 0c4cbdf commit df1aaeb
Show file tree
Hide file tree
Showing 19 changed files with 993 additions and 19 deletions.
158 changes: 158 additions & 0 deletions src/main/java/seedu/address/logic/commands/AddTeamCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
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_MODULECODE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAM_SIZE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.messages.ModuleMessages;
import seedu.address.model.Model;
import seedu.address.model.module.ModuleCode;
import seedu.address.model.module.ModuleTutorialPair;
import seedu.address.model.module.TutorialClass;
import seedu.address.model.module.TutorialTeam;

/**
* A class that handles the /add_team command execution.
*/
public class AddTeamCommand extends Command {
public static final String MESSAGE_ADD_TEAM_SUCCESS_WITHOUT_SIZE = "Added %1$s to %2$s %3$s";
public static final String MESSAGE_ADD_TEAM_SUCCESS_WITH_SIZE = "Added %1$s of size %2$s to %3$s %4$s";
public static final String MESSAGE_DUPLICATE_TEAM = "%1$s already added to %2$s %3$s!";
public static final String COMMAND_WORD = "/add_team";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Create a team with a name and an optional size, assigned to a particular tutorial class\n"
+ "Parameters: " + PREFIX_MODULECODE + "MODULE_CODE "
+ PREFIX_TUTORIALCLASS + "TUTORIAL_CLASS " + PREFIX_NAME + "TEAM_NAME " + PREFIX_TEAM_SIZE + "TEAM_SIZE\n"
+ "Example: " + COMMAND_WORD + " " + PREFIX_MODULECODE + "CS2103T "
+ PREFIX_TUTORIALCLASS + "T09 " + PREFIX_NAME + "Team 1 " + PREFIX_TEAM_SIZE + "5";

private final ModuleCode module;
private final TutorialClass tutorialClass;
private final String teamName;
private final int teamSize;

/**
* Constructs an AddTeamCommand to add the specified {@code TutorialTeam} to the
* specified {@code TutorialClass}, without the specified team size.
* @param module The module code of the tutorial class to be added.
* @param tutorialClass The tutorial class to be added.
* @param teamName The name of the team to be added.
*/
public AddTeamCommand(ModuleCode module, TutorialClass tutorialClass, String teamName) {
requireAllNonNull(module);
this.module = module;
this.tutorialClass = tutorialClass;
this.teamName = teamName;
this.teamSize = Integer.MAX_VALUE;
}

/**
* Constructs an AddTeamCommand to add the specified {@code TutorialTeam} to the
* specified {@code TutorialClass}, with the specified team size.
* @param module The module code of the tutorial class to be added.
* @param tutorialClass The tutorial class to be added.
* @param teamName The name of the team to be added.
* @param teamSize The size of the team to be added.
*/
public AddTeamCommand(ModuleCode module, TutorialClass tutorialClass, String teamName, int teamSize) {
requireAllNonNull(module);
this.module = module;
this.tutorialClass = tutorialClass;
this.teamName = teamName;
this.teamSize = teamSize;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
ModuleTutorialPair moduleAndTutorialClass = getModuleAndTutorialClass(model);
ModuleCode module = moduleAndTutorialClass.getModule();
TutorialClass tutorialClass = moduleAndTutorialClass.getTutorialClass();

TutorialTeam newTeam = new TutorialTeam(teamName, teamSize);

if (tutorialClass.hasTeam(newTeam)) {
throw new CommandException(String.format(MESSAGE_DUPLICATE_TEAM, teamName, module, tutorialClass));
} else {
tutorialClass.addTeam(newTeam);
}

if (teamSize != Integer.MAX_VALUE) {
return new CommandResult(generateSuccessMessage(module, tutorialClass, teamName, teamSize));
} else {
return new CommandResult(generateSuccessMessage(module, tutorialClass, teamName));
}
}

protected ModuleTutorialPair getModuleAndTutorialClass(Model model) throws CommandException {
requireNonNull(model);
ModuleCode module = getModule();
TutorialClass tutorialClass = getTutorialClass();
ModuleCode existingModule = model.findModuleFromList(module);
TutorialClass existingTutorialClass = model.findTutorialClassFromList(tutorialClass, existingModule);
if (existingModule == null) {
throw new CommandException(String.format(ModuleMessages.MESSAGE_MODULE_NOT_FOUND, module));
}
if (existingTutorialClass == null) {
throw new CommandException(
String.format(ModuleMessages.MESSAGE_TUTORIAL_DOES_NOT_BELONG_TO_MODULE, tutorialClass, module));
}
return new ModuleTutorialPair(existingModule, existingTutorialClass);
}

protected ModuleCode getModule() {
return module;
}

protected TutorialClass getTutorialClass() {
return tutorialClass;
}

/**
* Generates a command execution success message based on whether the tutorial
* team is added successfully and if the team size is not specified.
* @param module The module code of the tutorial class.
* @param tutorialString The tutorial class.
* @param teamName The name of the team.
* @return The success message.
*/
private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString, String teamName) {
return String.format(MESSAGE_ADD_TEAM_SUCCESS_WITHOUT_SIZE, teamName, module,
tutorialString);
}

/**
* Generates a command execution success message based on whether the tutorial
* team is added successfully and if the team size is specified.
* @param module The module code of the tutorial class.
* @param tutorialString The tutorial class.
* @param teamName The name of the team.
* @param teamSize The size of the team.
* @return The success message.
*/
private String generateSuccessMessage(ModuleCode module, TutorialClass tutorialString, String teamName,
int teamSize) {
return String.format(MESSAGE_ADD_TEAM_SUCCESS_WITH_SIZE, teamName, teamSize, module, tutorialString);
}

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

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

AddTeamCommand e = (AddTeamCommand) other;
return module.equals(e.module) && tutorialClass.equals(e.tutorialClass) && teamName.equals(e.teamName)
&& teamSize == e.teamSize;
}
}
70 changes: 70 additions & 0 deletions src/main/java/seedu/address/logic/parser/AddTeamCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULECODE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TEAM_SIZE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TUTORIALCLASS;

import java.util.stream.Stream;

import seedu.address.logic.commands.AddTeamCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.module.ModuleCode;
import seedu.address.model.module.TutorialClass;
import seedu.address.model.module.TutorialTeam;

/**
* Parses input arguments and creates a new {@code AddClassCommandParser} object
*/
public class AddTeamCommandParser implements Parser<AddTeamCommand> {
/**
* Parses the given {@code String} of arguments in the context of the
* {@code AddClassCommandParser}
* and returns a {@code AddClassCommandParser} object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public AddTeamCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS,
PREFIX_NAME, PREFIX_TEAM_SIZE);

if (!arePrefixesPresent(argMultimap, PREFIX_MODULECODE, PREFIX_TUTORIALCLASS, PREFIX_NAME)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTeamCommand.MESSAGE_USAGE));
}

boolean isTeamSizePresent = argMultimap.getValue(PREFIX_TEAM_SIZE).isPresent();
String moduleCode = argMultimap.getValue(PREFIX_MODULECODE).orElse("");
String tutorialClass = argMultimap.getValue(PREFIX_TUTORIALCLASS).orElse("");
String teamName = argMultimap.getValue(PREFIX_NAME).orElse("");
if (!(ModuleCode.isValidModuleCode(moduleCode))) {
throw new ParseException(ModuleCode.MESSAGE_CONSTRAINTS);
}
if (!(TutorialClass.isValidTutorialClass(tutorialClass))) {
throw new ParseException(TutorialClass.MESSAGE_CONSTRAINTS);
}

if (!TutorialTeam.isValidTeamName(teamName)) {
throw new ParseException(TutorialTeam.MESSAGE_NAME_CONSTRAINTS);
}
if (isTeamSizePresent) {
int teamSize = Integer.parseInt(argMultimap.getValue(PREFIX_TEAM_SIZE).get());
if (teamSize <= 0) {
throw new ParseException(TutorialTeam.MESSAGE_SIZE_CONSTRAINTS);
}
return new AddTeamCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass), teamName, teamSize);
} else {
return new AddTeamCommand(new ModuleCode(moduleCode), new TutorialClass(tutorialClass), teamName);
}
}

/**
* Returns true if all the prefixes are present in the given
* {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import seedu.address.commons.core.LogsCenter;
import seedu.address.logic.commands.AddClassCommand;
import seedu.address.logic.commands.AddStudentCommand;
import seedu.address.logic.commands.AddTeamCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.DeleteClassCommand;
Expand Down Expand Up @@ -98,6 +99,9 @@ public Command parseCommand(String userInput) throws ParseException {
case AddStudentToClassCommand.COMMAND_WORD:
return new AddStudentToClassCommandParser().parse(arguments);

case AddTeamCommand.COMMAND_WORD:
return new AddTeamCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package seedu.address.logic.parser;

/**
* Contains Command Line Interface (CLI) syntax definitions common to multiple commands
* Contains Command Line Interface (CLI) syntax definitions common to multiple
* commands
*/
public class CliSyntax {

Expand All @@ -14,4 +15,5 @@ public class CliSyntax {
public static final Prefix PREFIX_TUTORIALCLASS = new Prefix("tutorial/");
public static final Prefix PREFIX_TAG = new Prefix("tag/");
public static final Prefix PREFIX_DESCRIPTION = new Prefix("description/");
public static final Prefix PREFIX_TEAM_SIZE = new Prefix("size/");
}
16 changes: 6 additions & 10 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
import seedu.address.model.tag.Tag;

/**
* Contains utility methods used for parsing strings in the various *Parser classes.
* Contains utility methods used for parsing strings in the various *Parser
* classes.
*/
public class ParserUtil {

public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";

/**
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
* Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading
* and trailing whitespaces will be
* trimmed.
* @throws ParseException if the specified index is invalid (not non-zero unsigned integer).
* @throws ParseException if the specified index is invalid (not non-zero
* unsigned integer).
*/
public static Index parseIndex(String oneBasedIndex) throws ParseException {
String trimmedIndex = oneBasedIndex.trim();
Expand All @@ -39,7 +42,6 @@ public static Index parseIndex(String oneBasedIndex) throws ParseException {
/**
* Parses a {@code String name} into a {@code Name}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code name} is invalid.
*/
public static Name parseName(String name) throws ParseException {
Expand All @@ -54,7 +56,6 @@ public static Name parseName(String name) throws ParseException {
/**
* Parses a {@code String email} into an {@code Email}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code email} is invalid.
*/
public static Email parseEmail(String email) throws ParseException {
Expand All @@ -69,7 +70,6 @@ public static Email parseEmail(String email) throws ParseException {
/**
* Parses a {@code String studentId} into a {@code StudentId}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code studentId} is invalid.
*/
public static StudentId parseStudentId(String studentId) throws ParseException {
Expand All @@ -84,7 +84,6 @@ public static StudentId parseStudentId(String studentId) throws ParseException {
/**
* Parses a {@code String moduleCode} into an {@code ModuleCode}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code moduleCode} is invalid.
*/
public static ModuleCode parseModuleCode(String moduleCode) throws ParseException {
Expand All @@ -96,11 +95,9 @@ public static ModuleCode parseModuleCode(String moduleCode) throws ParseExceptio
return new ModuleCode(trimmedModuleCode);
}


/**
* Parses a {@code String tutorial} into an {@code TutorialClass}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code tutorial} is invalid.
*/
public static TutorialClass parseTutorialClass(String tutorial) throws ParseException {
Expand All @@ -115,7 +112,6 @@ public static TutorialClass parseTutorialClass(String tutorial) throws ParseExce
/**
* Parses a {@code String tag} into a {@code Tag}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code tag} is invalid.
*/
public static Tag parseTag(String tag) throws ParseException {
Expand Down
Loading

0 comments on commit df1aaeb

Please sign in to comment.