Skip to content

Commit 27a53af

Browse files
authored
Merge pull request nus-cs2103-AY2021S1#72 from khor-jingqian/improve-routine
Improve routine
2 parents 9ca5fdc + 95eeb7e commit 27a53af

12 files changed

Lines changed: 227 additions & 8 deletions

File tree

docs/DeveloperGuide.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
263263
| `* * *` | student who has no knowledge of working out|view what exercise routines the application has|choose the right one for me
264264
| `* * *` | busy student | add workout routines into my schedule | have the time to exercise
265265
| `* * *` | student | delete a workout routine | keep my schedule up-to-date
266-
| `* * *` | NUS student | see my timetable | slot in my workout sessions with ease
266+
| `* * *` | NUS student | see my timetable | slot in my workout sessions with ease
267267

268268
*{More to be added}*
269269

@@ -293,7 +293,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
293293
* 3a1. AddressBook shows an error message.
294294

295295
Use case resumes at step 2.
296-
296+
297297
**Use case: Create a new routine**
298298

299299
**MSS**
@@ -312,7 +312,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
312312
* 3a1. fitNUS shows an error message.
313313

314314
Use case resumes at step 2.
315-
315+
316316
**Use case: Delete a routine**
317317

318318
**MSS**

docs/UserGuide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fitNUS is **optimized for use via a Command Line Interface** (CLI) while still
1616

1717
--------------------------------------------------------------------------------------------------------------------
1818
<a name="quick-start"></a>
19-
## Quick start
19+
## Quick start
2020

2121
1. Ensure you have Java `11` or above installed in your Computer.
2222

src/main/java/seedu/address/logic/commands/routines/RoutineAddExerciseCommand.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import seedu.address.model.Model;
1111
import seedu.address.model.person.Exercise;
1212
import seedu.address.model.person.Routine;
13+
import seedu.address.model.person.exceptions.DuplicateExerciseException;
1314

1415
/**
1516
* Adds an Routine to fitNUS.
@@ -30,6 +31,8 @@ public class RoutineAddExerciseCommand extends Command {
3031
public static final String MESSAGE_SUCCESS = "Exercise added to Routine: %1$s";
3132
public static final String MESSAGE_MISSING_ROUTINE = "This routine does not exist in fitNUS";
3233
public static final String MESSAGE_MISSING_EXERCISE = "This exercise does not exist in fitNUS";
34+
public static final String MESSAGE_DUPLICATE_EXERCISE = "This exercise already exist in the routine!";
35+
3336

3437
private final Routine routineToAdd;
3538
private final Exercise exerciseToAdd;
@@ -53,8 +56,12 @@ public CommandResult execute(Model model) throws CommandException {
5356
throw new CommandException(MESSAGE_MISSING_EXERCISE);
5457
}
5558

56-
model.addExerciseToRoutine(routineToAdd, exerciseToAdd);
57-
return new CommandResult(String.format(String.format(MESSAGE_SUCCESS, routineToAdd), exerciseToAdd));
59+
try {
60+
model.addExerciseToRoutine(routineToAdd, exerciseToAdd);
61+
return new CommandResult(String.format(String.format(MESSAGE_SUCCESS, routineToAdd), exerciseToAdd));
62+
} catch (DuplicateExerciseException error) {
63+
throw new CommandException(MESSAGE_DUPLICATE_EXERCISE);
64+
}
5865
}
5966

6067
@Override
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package seedu.address.logic.commands.routines;
2+
3+
import static java.util.Objects.requireNonNull;
4+
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
5+
import static seedu.address.logic.parser.CliSyntax.PREFIX_ROUTINE;
6+
7+
import seedu.address.logic.commands.Command;
8+
import seedu.address.logic.commands.CommandResult;
9+
import seedu.address.logic.commands.exceptions.CommandException;
10+
import seedu.address.model.Model;
11+
import seedu.address.model.person.Exercise;
12+
import seedu.address.model.person.Routine;
13+
14+
/**
15+
* Deletes a routine identified using it's displayed index from fitNUS.
16+
*/
17+
public class RoutineDeleteExerciseCommand extends Command {
18+
19+
public static final String COMMAND_WORD = "routine_delete_exercise";
20+
21+
public static final String MESSAGE_USAGE = COMMAND_WORD
22+
+ ": Deletes the mentioned Exercise used in the specified Routine.\n"
23+
+ "Parameters: "
24+
+ PREFIX_ROUTINE + "ROUTINE_NAME "
25+
+ PREFIX_EMAIL + "EXERCISE_NAME"
26+
+ "\n"
27+
+ "Example: " + COMMAND_WORD + " "
28+
+ PREFIX_ROUTINE + "Leg Day Session "
29+
+ PREFIX_EMAIL + "Squats ";
30+
31+
public static final String MESSAGE_DELETE_EXERCISE_SUCCESS = "Deleted Exercise from Routine: %1$s";
32+
public static final String MESSAGE_MISSING_ROUTINE = "Deleted Exercise from Routine: %1$s";
33+
public static final String MESSAGE_MISSING_EXERCISE = "Deleted Exercise from Routine: %1$s";
34+
35+
private final Routine routine;
36+
private final Exercise exercise;
37+
38+
/**
39+
* Creates a RoutineDeleteExericseCommand object.
40+
* @param routine Specified Routine that the user wants to delete an Exercise from.
41+
* @param exercise Specified Exercise that the user wants to delete.
42+
*/
43+
public RoutineDeleteExerciseCommand(Routine routine, Exercise exercise) {
44+
this.routine = routine;
45+
this.exercise = exercise;
46+
}
47+
48+
@Override
49+
public CommandResult execute(Model model) throws CommandException {
50+
requireNonNull(model);
51+
52+
if (!model.hasRoutine(routine)) {
53+
throw new CommandException(MESSAGE_MISSING_ROUTINE);
54+
} else if (!model.hasExercise(exercise)) {
55+
throw new CommandException(MESSAGE_MISSING_EXERCISE);
56+
}
57+
58+
model.deleteExerciseToRoutine(routine, exercise);
59+
return new CommandResult(String.format(String.format(MESSAGE_DELETE_EXERCISE_SUCCESS,
60+
routine), exercise));
61+
}
62+
63+
@Override
64+
public boolean equals(Object other) {
65+
return other == this // short circuit if same object
66+
|| (other instanceof RoutineDeleteExerciseCommand // instanceof handles nulls
67+
&& exercise.equals(((RoutineDeleteExerciseCommand) other).exercise) // state check
68+
&& routine.equals(((RoutineDeleteExerciseCommand) other).routine)); // state check
69+
}
70+
}

src/main/java/seedu/address/logic/parser/AddressBookParser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
import seedu.address.logic.commands.routines.RoutineAddExerciseCommand;
3131
import seedu.address.logic.commands.routines.RoutineCreateCommand;
3232
import seedu.address.logic.commands.routines.RoutineDeleteCommand;
33+
import seedu.address.logic.commands.routines.RoutineDeleteExerciseCommand;
3334
import seedu.address.logic.commands.routines.RoutineListCommand;
3435
import seedu.address.logic.commands.routines.RoutineViewCommand;
3536
import seedu.address.logic.parser.exceptions.ParseException;
3637
import seedu.address.logic.parser.routines.RoutineAddExerciseCommandParser;
3738
import seedu.address.logic.parser.routines.RoutineCreateCommandParser;
3839
import seedu.address.logic.parser.routines.RoutineDeleteCommandParser;
40+
import seedu.address.logic.parser.routines.RoutineDeleteExerciseCommandParser;
3941
import seedu.address.logic.parser.routines.RoutineViewCommandParser;
4042

4143
/**
@@ -140,6 +142,10 @@ public Command parseCommand(String userInput) throws ParseException {
140142
case AddWeightCommand.COMMAND_WORD:
141143
return new AddWeightCommandParser().parse(arguments);
142144

145+
146+
case RoutineDeleteExerciseCommand.COMMAND_WORD:
147+
return new RoutineDeleteExerciseCommandParser().parse(arguments);
148+
143149
default:
144150
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
145151
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package seedu.address.logic.parser.routines;
2+
3+
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
4+
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
5+
import static seedu.address.logic.parser.CliSyntax.PREFIX_ROUTINE;
6+
7+
import java.util.HashSet;
8+
import java.util.Set;
9+
import java.util.stream.Stream;
10+
11+
import seedu.address.logic.commands.routines.RoutineDeleteExerciseCommand;
12+
import seedu.address.logic.parser.ArgumentMultimap;
13+
import seedu.address.logic.parser.ArgumentTokenizer;
14+
import seedu.address.logic.parser.Parser;
15+
import seedu.address.logic.parser.ParserUtil;
16+
import seedu.address.logic.parser.Prefix;
17+
import seedu.address.logic.parser.exceptions.ParseException;
18+
import seedu.address.model.person.Exercise;
19+
import seedu.address.model.person.Name;
20+
import seedu.address.model.person.Routine;
21+
import seedu.address.model.tag.Tag;
22+
23+
/**
24+
* Parses input arguments and creates a new AddCommand object
25+
*/
26+
public class RoutineDeleteExerciseCommandParser implements Parser<RoutineDeleteExerciseCommand> {
27+
28+
/**
29+
* Parses the given {@code String} of arguments in the context of the RoutineDeleteExerciseCommand
30+
* and returns an RoutineDeleteExerciseCommand object for execution.
31+
* @throws ParseException if the user input does not conform the expected format
32+
*/
33+
public RoutineDeleteExerciseCommand parse(String args) throws ParseException {
34+
ArgumentMultimap argMultimap =
35+
ArgumentTokenizer.tokenize(args, PREFIX_ROUTINE, PREFIX_EMAIL);
36+
37+
if (!arePrefixesPresent(argMultimap, PREFIX_ROUTINE, PREFIX_EMAIL)
38+
|| !argMultimap.getPreamble().isEmpty()) {
39+
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT,
40+
RoutineDeleteExerciseCommand.MESSAGE_USAGE));
41+
}
42+
43+
Name routineName = ParserUtil.parseName(argMultimap.getValue(PREFIX_ROUTINE).get());
44+
45+
Name exerciseName = ParserUtil.parseName(argMultimap.getValue(PREFIX_EMAIL).get());
46+
Routine routine = new Routine(routineName);
47+
Set<Tag> tagList = new HashSet<>();
48+
Exercise exercise = new Exercise(exerciseName, tagList);
49+
50+
return new RoutineDeleteExerciseCommand(routine, exercise);
51+
}
52+
53+
/**
54+
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
55+
* {@code ArgumentMultimap}.
56+
*/
57+
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
58+
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
59+
}
60+
61+
}

src/main/java/seedu/address/model/AddressBook.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ public void removePerson(Person key) {
227227
*/
228228
public void removeExercise(Exercise key) {
229229
exercises.remove(key);
230+
routines.deleteExercise(key);
230231
}
231232

232233
/**
@@ -359,4 +360,18 @@ public Routine retrieveRoutine(Routine routine) {
359360
return routines.retrieveRoutine(routine);
360361
}
361362

363+
/**
364+
* Deletes an existing Exercise in fitNUS from an existing Routine.
365+
*
366+
* @param r Existing Routine.
367+
* @param e Existing Exercise.
368+
*/
369+
public void deleteExerciseToRoutine(Routine r, Exercise e) {
370+
requireNonNull(r);
371+
requireNonNull(e);
372+
373+
Exercise retrievedExercise = exercises.retrieveExercise(e);
374+
Routine retrievedRoutine = routines.retrieveRoutine(r);
375+
routines.deleteExerciseFromRoutine(retrievedRoutine, retrievedExercise);
376+
}
362377
}

src/main/java/seedu/address/model/Model.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,4 +229,11 @@ public interface Model {
229229
* @return Routine object that exists within fitNUS that the user is looking for.
230230
*/
231231
Routine retrieveRoutine(Routine routine);
232+
233+
/**
234+
* Deletes the specified exercise from an existing routine.
235+
* {@code routine} must already exist within fitNUS.
236+
* {@code exercise} must already exist within fitNUS.
237+
*/
238+
void deleteExerciseToRoutine(Routine routine, Exercise exercise);
232239
}

src/main/java/seedu/address/model/ModelManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ public void addExerciseToRoutine(Routine r, Exercise e) {
170170
updateFilteredExerciseList(PREDICATE_SHOW_ALL_EXERCISES);
171171
}
172172

173+
@Override
174+
public void deleteExerciseToRoutine(Routine r, Exercise e) {
175+
addressBook.deleteExerciseToRoutine(r, e);
176+
updateFilteredRoutineList(PREDICATE_SHOW_ALL_ROUTINES);
177+
updateFilteredExerciseList(PREDICATE_SHOW_ALL_EXERCISES);
178+
}
179+
173180
@Override
174181
public boolean hasExercise(Exercise exercise) {
175182
requireNonNull(exercise);

src/main/java/seedu/address/model/person/UniqueRoutineList.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
import java.util.Iterator;
77
import java.util.List;
8+
import java.util.Set;
89

910
import javafx.collections.FXCollections;
1011
import javafx.collections.ObservableList;
12+
import seedu.address.model.person.exceptions.DuplicateExerciseException;
1113
import seedu.address.model.person.exceptions.DuplicateRoutineException;
1214
import seedu.address.model.person.exceptions.RoutineNotFoundException;
1315

@@ -52,7 +54,8 @@ public void add(Routine toAdd) {
5254

5355
/**
5456
* Adds an existing Exercise within fitNUS into an existing Routine within fitNUS.
55-
* @param r Existing Routine.
57+
*
58+
* @param r Existing Routine.
5659
* @param exercise Existing Exercise.
5760
*/
5861
public void addExercise(Routine r, Exercise exercise) {
@@ -62,6 +65,10 @@ public void addExercise(Routine r, Exercise exercise) {
6265
} else {
6366
for (Routine routine : internalList) {
6467
if (routine.isSameActivity(r)) {
68+
Set<Exercise> routineExercises = routine.getExercises();
69+
if (routineExercises.contains(exercise)) {
70+
throw new DuplicateExerciseException();
71+
}
6572
routine.addExercise(exercise);
6673
break;
6774
}
@@ -71,6 +78,7 @@ public void addExercise(Routine r, Exercise exercise) {
7178

7279
/**
7380
* Returns the toString method of the Routine that the user wants to view.
81+
*
7482
* @param index Index of the Routine that the user wants to view.
7583
* @return The toString method of the Routine that the user wants to see.
7684
*/
@@ -80,6 +88,7 @@ public String viewRoutine(int index) {
8088

8189
/**
8290
* Lists out all the Routine objects in UniqueRoutineList.
91+
*
8392
* @return String containing all the Routine object toString method.
8493
*/
8594
public String listRoutines() {
@@ -126,6 +135,7 @@ public void remove(Routine toRemove) {
126135

127136
/**
128137
* Returns the size of the UniqueRoutineList.
138+
*
129139
* @return Integer of the size of the UniqueRoutineList.
130140
*/
131141
public int checkSize() {
@@ -190,6 +200,7 @@ private boolean routinesAreUnique(List<Routine> routines) {
190200

191201
/**
192202
* Retrieves the Routine object from UniqueRoutineList that the user specified.
203+
*
193204
* @param r Routine object that the user wants.
194205
* @return Routine object that exists within fitNUS that the user is looking for.
195206
*/
@@ -201,4 +212,34 @@ public Routine retrieveRoutine(Routine r) {
201212
}
202213
return r;
203214
}
215+
216+
/**
217+
* Deletes the specified Exercise from the specified Routine.
218+
*
219+
* @param retrievedRoutine User-specified Routine.
220+
* @param retrievedExercise User-specified Exercise.
221+
*/
222+
public void deleteExerciseFromRoutine(Routine retrievedRoutine, Exercise retrievedExercise) {
223+
if (!internalList.contains(retrievedRoutine)) {
224+
throw new RoutineNotFoundException();
225+
} else {
226+
for (Routine routine : internalList) {
227+
if (routine.isSameActivity(retrievedRoutine)) {
228+
routine.deleteExercise(retrievedExercise);
229+
break;
230+
}
231+
}
232+
}
233+
}
234+
235+
/**
236+
* Deletes specified Exercise from all Routines.
237+
* @param retrievedExercise User-specified Exercise to remove from all Routines.
238+
*/
239+
public void deleteExercise(Exercise retrievedExercise) {
240+
for (Routine routine : internalList) {
241+
Set<Exercise> routineExercises = routine.getExercises();
242+
routineExercises.remove(retrievedExercise);
243+
}
244+
}
204245
}

0 commit comments

Comments
 (0)