From d61d75490d4ce91f8f788f84b67f61c070053759 Mon Sep 17 00:00:00 2001 From: seox123 Date: Mon, 24 Oct 2022 04:11:22 +0800 Subject: [PATCH] Add unplan command --- .../waddle/commons/core/index/MultiIndex.java | 12 +++- .../waddle/logic/commands/PlanCommand.java | 2 +- .../waddle/logic/commands/UnplanCommand.java | 63 +++++++++++++++++++ .../seedu/waddle/logic/parser/ParserUtil.java | 5 +- .../logic/parser/UnplanCommandParser.java | 27 ++++++++ .../waddle/logic/parser/WaddleParser.java | 4 ++ .../waddle/model/itinerary/DayNumber.java | 6 +- .../waddle/model/itinerary/Itinerary.java | 2 +- 8 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 src/main/java/seedu/waddle/logic/commands/UnplanCommand.java create mode 100644 src/main/java/seedu/waddle/logic/parser/UnplanCommandParser.java diff --git a/src/main/java/seedu/waddle/commons/core/index/MultiIndex.java b/src/main/java/seedu/waddle/commons/core/index/MultiIndex.java index b819c87fca4..d56c5c4591a 100644 --- a/src/main/java/seedu/waddle/commons/core/index/MultiIndex.java +++ b/src/main/java/seedu/waddle/commons/core/index/MultiIndex.java @@ -7,6 +7,9 @@ * Represents a series of Index objects. */ public class MultiIndex { + public static final String MESSAGE_CONSTRAINTS = + "Index should only contain positive integers separated by a decimal point"; + public static final String VALIDATION_REGEX = "\\d+\\.\\d+"; private List indices; public MultiIndex() { @@ -60,8 +63,15 @@ private Index getIndex(int pos) { return indices.get(pos - 1); } + /** + * Returns true if a given string is a valid multi index. + */ + public static boolean isValidMultiIndex(String test) { + return test.matches(VALIDATION_REGEX); + } + private boolean isValidPos(int pos) { - if (pos < 1 || pos >= indices.size()) { + if (pos < 1 || pos > indices.size()) { return false; } return true; diff --git a/src/main/java/seedu/waddle/logic/commands/PlanCommand.java b/src/main/java/seedu/waddle/logic/commands/PlanCommand.java index baea5f3a125..00919f76c48 100644 --- a/src/main/java/seedu/waddle/logic/commands/PlanCommand.java +++ b/src/main/java/seedu/waddle/logic/commands/PlanCommand.java @@ -38,7 +38,7 @@ public class PlanCommand extends Command { private final LocalTime startTime; /** - * Creates an AddItemCommand to add the specified {@code Item} + * Creates a PlanCommand to add the specified {@code Item} */ public PlanCommand(Index itemIndex, DayNumber dayNumber, LocalTime startTime) { requireNonNull(itemIndex); diff --git a/src/main/java/seedu/waddle/logic/commands/UnplanCommand.java b/src/main/java/seedu/waddle/logic/commands/UnplanCommand.java new file mode 100644 index 00000000000..fb0f38d823e --- /dev/null +++ b/src/main/java/seedu/waddle/logic/commands/UnplanCommand.java @@ -0,0 +1,63 @@ +package seedu.waddle.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.waddle.commons.core.index.MultiIndex; +import seedu.waddle.logic.StageManager; +import seedu.waddle.logic.commands.exceptions.CommandException; +import seedu.waddle.model.Model; +import seedu.waddle.model.item.Item; +import seedu.waddle.model.itinerary.Itinerary; + +/** + * Unplans an item in the itinerary day list. + */ +public class UnplanCommand extends Command { + + public static final String COMMAND_WORD = "unplan"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Unschedules an item identified " + + "by the index number used in the day list.\n" + + "Parameters: DAY_INDEX.TASK_INDEX (must be an existing index) " + + "Example: " + COMMAND_WORD + " 1.2 "; + + public static final String MESSAGE_SUCCESS = "Item unscheduled: %1$s"; + public static final String MESSAGE_INVALID_INDEX_NUMBER = "The index you have selected does not exist"; + + private final MultiIndex multiIndex; + + /** + * Creates an UnplanCommand to add the specified {@code Item} + */ + public UnplanCommand(MultiIndex multiIndex) { + requireNonNull(multiIndex); + + this.multiIndex = multiIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + StageManager stageManager = StageManager.getInstance(); + + Itinerary itinerary = stageManager.getSelectedItinerary(); + + Item unplannedItem; + try { + System.out.println(multiIndex.toString()); + unplannedItem = itinerary.unplanItem(multiIndex); + } catch (IndexOutOfBoundsException e) { + throw new CommandException(MESSAGE_INVALID_INDEX_NUMBER); + } + + return new CommandResult(String.format(MESSAGE_SUCCESS, unplannedItem.getDescription())); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UnplanCommand // instanceof handles nulls + && multiIndex.equals(((UnplanCommand) other).multiIndex)); + } +} diff --git a/src/main/java/seedu/waddle/logic/parser/ParserUtil.java b/src/main/java/seedu/waddle/logic/parser/ParserUtil.java index 3ac0f42c443..356da6fe663 100644 --- a/src/main/java/seedu/waddle/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/waddle/logic/parser/ParserUtil.java @@ -48,7 +48,10 @@ public static Index parseIndex(String oneBasedIndex) throws ParseException { */ public static MultiIndex parseMultiIndex(String oneBasedMultiIndex) throws ParseException { String trimmedMultiIndex = oneBasedMultiIndex.trim(); - String[] oneBasedIndexList = trimmedMultiIndex.split(".", 2); + if (!MultiIndex.isValidMultiIndex(trimmedMultiIndex)) { + throw new ParseException(MultiIndex.MESSAGE_CONSTRAINTS); + } + String[] oneBasedIndexList = trimmedMultiIndex.split("\\.", 2); MultiIndex multiIndex = new MultiIndex(); for (String oneBasedIndex : oneBasedIndexList) { Index index = parseIndex(oneBasedIndex); diff --git a/src/main/java/seedu/waddle/logic/parser/UnplanCommandParser.java b/src/main/java/seedu/waddle/logic/parser/UnplanCommandParser.java new file mode 100644 index 00000000000..300f716b4ab --- /dev/null +++ b/src/main/java/seedu/waddle/logic/parser/UnplanCommandParser.java @@ -0,0 +1,27 @@ +package seedu.waddle.logic.parser; + +import static java.util.Objects.requireNonNull; + +import seedu.waddle.commons.core.index.MultiIndex; +import seedu.waddle.logic.commands.UnplanCommand; +import seedu.waddle.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new UnplanCommand object + */ +public class UnplanCommandParser { + + /** + * Parses the given {@code String} of arguments in the context of the UnplanCommand + * and returns an UnplanCommand object for execution. + * @throws ParseException if the user input does not conform to the expected format + */ + public UnplanCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args); + + MultiIndex multiIndex = ParserUtil.parseMultiIndex(argMultimap.getPreamble()); + + return new UnplanCommand(multiIndex); + } +} diff --git a/src/main/java/seedu/waddle/logic/parser/WaddleParser.java b/src/main/java/seedu/waddle/logic/parser/WaddleParser.java index 4e9529fe096..fca166a639a 100644 --- a/src/main/java/seedu/waddle/logic/parser/WaddleParser.java +++ b/src/main/java/seedu/waddle/logic/parser/WaddleParser.java @@ -25,6 +25,7 @@ import seedu.waddle.logic.commands.PlanCommand; import seedu.waddle.logic.commands.SelectCommand; import seedu.waddle.logic.commands.StageCommand; +import seedu.waddle.logic.commands.UnplanCommand; import seedu.waddle.logic.parser.exceptions.ParseException; /** @@ -147,6 +148,9 @@ public Command parseWishCommand(String commandWord, String arguments) throws Par case PlanCommand.COMMAND_WORD: return new PlanCommandParser().parse(arguments); + case UnplanCommand.COMMAND_WORD: + return new UnplanCommandParser().parse(arguments); + //TODO: help commands must change here case HelpCommand.COMMAND_WORD: return new HelpCommand(); diff --git a/src/main/java/seedu/waddle/model/itinerary/DayNumber.java b/src/main/java/seedu/waddle/model/itinerary/DayNumber.java index 0bce147d61c..f41a0e6cbdc 100644 --- a/src/main/java/seedu/waddle/model/itinerary/DayNumber.java +++ b/src/main/java/seedu/waddle/model/itinerary/DayNumber.java @@ -3,6 +3,8 @@ import static java.util.Objects.requireNonNull; import static seedu.waddle.commons.util.AppUtil.checkArgument; +import seedu.waddle.commons.core.index.Index; + /** * Represents an Itinerary's day number element. * Guarantees: immutable; is valid as declared in {@link #isValidDayNumber(String)} @@ -12,7 +14,7 @@ public class DayNumber { "Day number should only contain positive numbers"; public static final String VALIDATION_REGEX = "\\d+"; - public final int dayNumber; + public final Index dayNumber; /** * Constructs a {@code DayNumber}. @@ -22,7 +24,7 @@ public class DayNumber { public DayNumber(String dayNumber) { requireNonNull(dayNumber); checkArgument(isValidDayNumber(dayNumber), MESSAGE_CONSTRAINTS); - this.dayNumber = Integer.parseInt(dayNumber); + this.dayNumber = Index.fromOneBased(Integer.parseInt(dayNumber)); } /** diff --git a/src/main/java/seedu/waddle/model/itinerary/Itinerary.java b/src/main/java/seedu/waddle/model/itinerary/Itinerary.java index a56cdf8f082..5ec8bc14607 100644 --- a/src/main/java/seedu/waddle/model/itinerary/Itinerary.java +++ b/src/main/java/seedu/waddle/model/itinerary/Itinerary.java @@ -192,7 +192,7 @@ public Item unplanItem(MultiIndex index) { public Item planItem(Index itemIndex, DayNumber dayNumber, LocalTime startTime) throws CommandException { Item item = this.unscheduledItemList.get(itemIndex.getZeroBased()); item.setStartTime(startTime); - Day day = this.days.get(dayNumber.dayNumber); + Day day = this.days.get(dayNumber.dayNumber.getZeroBased()); day.addItem(item); this.unscheduledItemList.remove(itemIndex.getZeroBased()); this.budget.updateSpending(item.getCost().getValue());