Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2223S1#85 from seox123/add-plan-command
Browse files Browse the repository at this point in the history
Add plan command
  • Loading branch information
seox123 authored Oct 23, 2022
2 parents 8f0e4f2 + 206ec39 commit 4ca89e9
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class EditItemCommand extends Command {
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the item identified "
+ "by the index number used in the displayed item list. "
+ "Existing values will be overwritten by the input values.\n"
+ "Parameters: "
+ "Parameters: INDEX (must be a positive integer) "
+ "[" + PREFIX_DESCRIPTION + "DESCRIPTION]"
+ "[" + PREFIX_PRIORITY + "PRIORITY]"
+ "[" + PREFIX_COST + "COST]"
Expand Down
79 changes: 79 additions & 0 deletions src/main/java/seedu/waddle/logic/commands/PlanCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package seedu.waddle.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.waddle.logic.parser.CliSyntax.PREFIX_DAY_NUMBER;
import static seedu.waddle.logic.parser.CliSyntax.PREFIX_START_TIME;

import java.time.LocalTime;

import seedu.waddle.commons.core.index.Index;
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.DayNumber;
import seedu.waddle.model.itinerary.Itinerary;

/**
* Plans an item in the itinerary wish list.
*/
public class PlanCommand extends Command {

public static final String COMMAND_WORD = "plan";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Schedules an item identified "
+ "by the index number used in the item list.\n"
+ "Parameters: INDEX (must be a positive integer) "
+ "[" + PREFIX_DAY_NUMBER + "DAY NUMBER] "
+ "[" + PREFIX_START_TIME + "START TIME] "
+ "Example: " + COMMAND_WORD + " 1 "
+ PREFIX_DAY_NUMBER + "1 "
+ PREFIX_START_TIME + "12:00 ";

public static final String MESSAGE_SUCCESS = "Item scheduled: %1$s";
public static final String MESSAGE_INVALID_DAY_NUMBER = "The day you have selected does not exist";

private final Index itemIndex;
private final DayNumber dayNumber;
private final LocalTime startTime;

/**
* Creates an AddItemCommand to add the specified {@code Item}
*/
public PlanCommand(Index itemIndex, DayNumber dayNumber, LocalTime startTime) {
requireNonNull(itemIndex);
requireNonNull(dayNumber);
requireNonNull(startTime);

this.itemIndex = itemIndex;
this.dayNumber = dayNumber;
this.startTime = startTime;
}

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

StageManager stageManager = StageManager.getInstance();

Itinerary itinerary = stageManager.getSelectedItinerary();

Item plannedItem;
try {
plannedItem = itinerary.planItem(itemIndex, dayNumber, startTime);
} catch (IndexOutOfBoundsException e) {
throw new CommandException(MESSAGE_INVALID_DAY_NUMBER);
}

return new CommandResult(String.format(MESSAGE_SUCCESS, plannedItem.getDescription()));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof PlanCommand // instanceof handles nulls
&& itemIndex.equals(((PlanCommand) other).itemIndex)
&& dayNumber == ((PlanCommand) other).dayNumber
&& startTime.equals(((PlanCommand) other).startTime));
}
}
1 change: 1 addition & 0 deletions src/main/java/seedu/waddle/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public class CliSyntax {
public static final Prefix PREFIX_PRIORITY = new Prefix("p/");
public static final Prefix PREFIX_COST = new Prefix("c/");
public static final Prefix PREFIX_DURATION = new Prefix("du/");
public static final Prefix PREFIX_DAY_NUMBER = new Prefix("d/");

}
14 changes: 14 additions & 0 deletions src/main/java/seedu/waddle/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import seedu.waddle.model.itinerary.Budget;
import seedu.waddle.model.itinerary.Country;
import seedu.waddle.model.itinerary.Date;
import seedu.waddle.model.itinerary.DayNumber;
import seedu.waddle.model.itinerary.ItineraryDuration;
import seedu.waddle.model.itinerary.Name;
import seedu.waddle.model.itinerary.People;
Expand Down Expand Up @@ -195,6 +196,19 @@ public static Cost parseCost(String cost) throws ParseException {
return new Cost(trimmedCost);
}

/**
* Parses a {@code int Day Number}.
* Leading and trailing whitespaces will be trimmed.
*/
public static DayNumber parseDayNumber(String dayNumber) throws ParseException {
requireNonNull(dayNumber);
String trimmedDayNumber = dayNumber.trim();
if (!DayNumber.isValidDayNumber(trimmedDayNumber)) {
throw new ParseException(DayNumber.MESSAGE_CONSTRAINTS);
}
return new DayNumber(trimmedDayNumber);
}

/**
* Parses a {@code String duration} into a {@code Duration}.
* Leading and trailing whitespaces will be trimmed.
Expand Down
46 changes: 32 additions & 14 deletions src/main/java/seedu/waddle/logic/parser/PlanCommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,55 @@

import static java.util.Objects.requireNonNull;
import static seedu.waddle.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.waddle.logic.parser.CliSyntax.PREFIX_DAY_NUMBER;
import static seedu.waddle.logic.parser.CliSyntax.PREFIX_START_TIME;

import java.time.LocalTime;
import java.util.stream.Stream;

import seedu.waddle.commons.core.index.Index;
import seedu.waddle.commons.exceptions.IllegalValueException;
import seedu.waddle.logic.commands.SelectCommand;
import seedu.waddle.logic.commands.PlanCommand;
import seedu.waddle.logic.parser.exceptions.ParseException;
import seedu.waddle.model.itinerary.DayNumber;

/**
* Parses input arguments and creates a new FindCommand object
* Parses input arguments and creates a new PlanCommand object
*/
public class PlanCommandParser {

/**
* Parses the given {@code String} of arguments in the context of the PlanCommand
* and returns a PlanCommand object for execution.
*
* @param args Arguments.
* @return PlanCommand.
* @throws ParseException If the user input does not conform the expected format.
* @throws ParseException if the user input does not conform to the expected format
*/
public SelectCommand parse(String args) throws ParseException {
public PlanCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args);
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_DAY_NUMBER, PREFIX_START_TIME);

if (!arePrefixesPresent(argMultimap, PREFIX_DAY_NUMBER, PREFIX_START_TIME)) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
PlanCommand.MESSAGE_USAGE));
}

Index index;
try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (IllegalValueException ive) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
SelectCommand.MESSAGE_USAGE), ive);
} catch (ParseException pe) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, PlanCommand.MESSAGE_USAGE), pe);
}

return new SelectCommand(index);
DayNumber dayNumber = ParserUtil.parseDayNumber(argMultimap.getValue(PREFIX_DAY_NUMBER).get());
LocalTime startTime = ParserUtil.parseStartTime(argMultimap.getValue(PREFIX_START_TIME).get());

return new PlanCommand(index, dayNumber, startTime);
}
}

/**
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
* {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}
}
38 changes: 38 additions & 0 deletions src/main/java/seedu/waddle/logic/parser/SelectCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package seedu.waddle.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.waddle.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.waddle.commons.core.index.Index;
import seedu.waddle.commons.exceptions.IllegalValueException;
import seedu.waddle.logic.commands.SelectCommand;
import seedu.waddle.logic.parser.exceptions.ParseException;

/**
* Parses input arguments and creates a new SelectCommand object
*/
public class SelectCommandParser {
/**
* Parses the given {@code String} of arguments in the context of the SelectCommand
* and returns a SelectCommand object for execution.
*
* @param args Arguments
* @return SelectCommand
* @throws ParseException If the user input does not conform to the expected format
*/
public SelectCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args);

Index index;
try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (IllegalValueException ive) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
SelectCommand.MESSAGE_USAGE), ive);
}

return new SelectCommand(index);
}
}

6 changes: 5 additions & 1 deletion src/main/java/seedu/waddle/logic/parser/WaddleParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import seedu.waddle.logic.commands.HelpCommand;
import seedu.waddle.logic.commands.HomeCommand;
import seedu.waddle.logic.commands.ListCommand;
import seedu.waddle.logic.commands.PlanCommand;
import seedu.waddle.logic.commands.SelectCommand;
import seedu.waddle.logic.commands.StageCommand;
import seedu.waddle.logic.parser.exceptions.ParseException;
Expand Down Expand Up @@ -96,7 +97,7 @@ public Command parseHomeCommand(String commandWord, String arguments) throws Par
return new ListCommand();

case SelectCommand.COMMAND_WORD:
return new PlanCommandParser().parse(arguments);
return new SelectCommandParser().parse(arguments);

case HomeCommand.COMMAND_WORD:
return new HomeCommand();
Expand Down Expand Up @@ -143,6 +144,9 @@ public Command parseWishCommand(String commandWord, String arguments) throws Par
case DeleteItemCommand.COMMAND_WORD:
return new DeleteItemCommandParser().parse(arguments);

case PlanCommand.COMMAND_WORD:
return new PlanCommandParser().parse(arguments);

//TODO: help commands must change here
case HelpCommand.COMMAND_WORD:
return new HelpCommand();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/waddle/model/item/Cost.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class Cost {
public Cost(String cost) {
requireNonNull(cost);
checkArgument(isValidCost(cost), MESSAGE_CONSTRAINTS);
this.cost = Float.valueOf(cost);
this.cost = Float.parseFloat(cost);
}

/**
Expand All @@ -28,7 +28,7 @@ public Cost(String cost) {
public static boolean isValidCost(String test) {
float value;
try {
value = Float.valueOf(test);
value = Float.parseFloat(test);
} catch (NumberFormatException e) {
return false;
}
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/seedu/waddle/model/itinerary/DayNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package seedu.waddle.model.itinerary;

import static java.util.Objects.requireNonNull;
import static seedu.waddle.commons.util.AppUtil.checkArgument;

/**
* Represents an Itinerary's day number element.
* Guarantees: immutable; is valid as declared in {@link #isValidDayNumber(String)}
*/
public class DayNumber {
public static final String MESSAGE_CONSTRAINTS =
"Day number should only contain positive numbers";
public static final String VALIDATION_REGEX = "\\d+";

public final int dayNumber;

/**
* Constructs a {@code DayNumber}.
*
* @param dayNumber A valid value.
*/
public DayNumber(String dayNumber) {
requireNonNull(dayNumber);
checkArgument(isValidDayNumber(dayNumber), MESSAGE_CONSTRAINTS);
this.dayNumber = Integer.parseInt(dayNumber);
}

/**
* Returns true if a given string is a valid day number.
*/
public static boolean isValidDayNumber(String test) {
return test.matches(VALIDATION_REGEX);
}


@Override
public String toString() {
return String.valueOf(dayNumber);
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof seedu.waddle.model.itinerary.DayNumber // instanceof handles nulls
&& dayNumber == ((seedu.waddle.model.itinerary.DayNumber) other).dayNumber); // state check
}
}
15 changes: 10 additions & 5 deletions src/main/java/seedu/waddle/model/itinerary/Itinerary.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import static seedu.waddle.commons.util.CollectionUtil.requireAllNonNull;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import seedu.waddle.commons.core.index.Index;
import seedu.waddle.commons.core.index.MultiIndex;
import seedu.waddle.logic.commands.exceptions.CommandException;
import seedu.waddle.model.item.Day;
Expand Down Expand Up @@ -182,16 +184,19 @@ public Item unplanItem(MultiIndex index) {
/**
* Plan an item.
* @param itemIndex Index of item in unscheduled list.
* @param dayIndex Day to include this item.
* @param dayNumber Day to include this item.
* @param startTime startTime of the item.
* @return The planned item.
* @throws CommandException When adding item to specific day leads to conflict in time.
*/
public void planItem(int itemIndex, int dayIndex, int startTime) throws CommandException {
Item item = this.unscheduledItemList.get(itemIndex);
Day day = this.days.get(dayIndex);
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.addItem(item);
this.unscheduledItemList.remove(itemIndex);
this.unscheduledItemList.remove(itemIndex.getZeroBased());
this.budget.updateSpending(item.getCost().getValue());
return item;
}

public Item getItem(MultiIndex index) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/seedu/waddle/model/itinerary/People.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
public class People {

public static final String MESSAGE_CONSTRAINTS =
"Number of people should only contain numbers";
"Number of people should only contain positive numbers";
public static final String VALIDATION_REGEX = "\\d+";

public final String numOfPeople;

/**
* Constructs a {@code Name}.
* Constructs a {@code People}.
*
* @param numOfPeople A valid value.
*/
Expand All @@ -28,7 +28,7 @@ public People(String numOfPeople) {
}

/**
* Returns true if a given string is a valid name.
* Returns true if a given string is a valid number of people.
*/
public static boolean isValidPeople(String test) {
return test.matches(VALIDATION_REGEX);
Expand Down

0 comments on commit 4ca89e9

Please sign in to comment.