diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 677105f366d..45e29a8ac0a 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -21,6 +21,7 @@ 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_APPOINTMENT_NOT_FOUND = "Specified appointment does not exist!"; + public static final String MESSAGE_APPOINTMENTS_FOUND_OVERVIEW = "%1d appointments found!"; /** * Returns an error message indicating the duplicate prefixes. diff --git a/src/main/java/seedu/address/logic/commands/AddAppointmentCommand.java b/src/main/java/seedu/address/logic/commands/AddAppointmentCommand.java index f46c7ce2eb6..cdc03bfe5b1 100644 --- a/src/main/java/seedu/address/logic/commands/AddAppointmentCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddAppointmentCommand.java @@ -61,6 +61,7 @@ public CommandResult execute(Model model) throws CommandException { checkValidAppointment(chosenPatient, chosenDoctor, toAdd); chosenPatient.addAppointment(toAdd); chosenDoctor.addAppointment(toAdd); + model.addAppointment(toAdd); return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd)); } diff --git a/src/main/java/seedu/address/logic/commands/FindAppointmentCommand.java b/src/main/java/seedu/address/logic/commands/FindAppointmentCommand.java new file mode 100644 index 00000000000..6e470fcadbd --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FindAppointmentCommand.java @@ -0,0 +1,68 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.model.Model; +import seedu.address.model.appointment.Appointment; + +/** + * Finds and lists all persons in in address book whose attributes match the predicate. + * Keyword matching is case insensitive. + */ +public class FindAppointmentCommand extends Command { + + public static final String COMMAND_WORD = "find-appt"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all appointments who involve the " + + "the specified case-sensitive NRIC and displays them as a list with index numbers.\n" + + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + + "Example: " + COMMAND_WORD + " T1234567Z"; + + private final Predicate predicate; + /** + * Finds and lists all persons in address book whose attributes match the predicate. + * Keyword matching is case insensitive. + */ + public FindAppointmentCommand(Predicate predicate) { + requireNonNull(predicate); + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredAppointmentList(predicate); + List searchList = new ArrayList<>(); + searchList.addAll(model.getFilteredAppointmentList()); + return new CommandResult( + String.format(Messages.MESSAGE_APPOINTMENTS_FOUND_OVERVIEW, searchList.size())); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof FindAppointmentCommand)) { + return false; + } + + FindAppointmentCommand otherFindAppointmentCommand = (FindAppointmentCommand) other; + return predicate.equals(otherFindAppointmentCommand.predicate); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("predicate", predicate) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java index 84be6ad2596..ea1d36fec2b 100644 --- a/src/main/java/seedu/address/logic/commands/ListCommand.java +++ b/src/main/java/seedu/address/logic/commands/ListCommand.java @@ -1,6 +1,7 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_APPOINTMENTS; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; import seedu.address.model.Model; @@ -19,6 +20,7 @@ public class ListCommand extends Command { public CommandResult execute(Model model) { requireNonNull(model); model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + model.updateFilteredAppointmentList(PREDICATE_SHOW_ALL_APPOINTMENTS); return new CommandResult(MESSAGE_SUCCESS); } } diff --git a/src/main/java/seedu/address/logic/parser/AddAppointmentCommandParser.java b/src/main/java/seedu/address/logic/parser/AddAppointmentCommandParser.java index 16ce0987ebb..4ac4611c288 100644 --- a/src/main/java/seedu/address/logic/parser/AddAppointmentCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddAppointmentCommandParser.java @@ -26,6 +26,7 @@ public class AddAppointmentCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the DeleteCommand * and returns a DeleteCommand object for execution. + * * @throws ParseException if the user input does not conform the expected format */ public DeleteCommand parse(String args) throws ParseException { diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java index 5806ed37863..1fe4072deb8 100644 --- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/EditCommandParser.java @@ -35,6 +35,7 @@ public class EditCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the EditCommand * and returns an EditCommand object for execution. + * * @throws ParseException if the user input does not conform the expected format */ public EditCommand parse(String args) throws ParseException { diff --git a/src/main/java/seedu/address/logic/parser/FindAppointmentCommandParser.java b/src/main/java/seedu/address/logic/parser/FindAppointmentCommandParser.java new file mode 100644 index 00000000000..bd67fcdad0f --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FindAppointmentCommandParser.java @@ -0,0 +1,40 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.logic.commands.FindAppointmentCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.appointment.AppointmentIcPredicate; + +/** + * Parses input arguments and creates a new FindCommand object + */ +public class FindAppointmentCommandParser implements Parser { + private static final Logger logger = LogsCenter.getLogger(FindAppointmentCommandParser.class); + + /** + * Parses the given {@code String} of arguments in the context of the FindCommand + * and returns a FindCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + public FindAppointmentCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + Pattern nricPattern = Pattern.compile("^[ST]\\d{7}[A-Z]$"); + Matcher nricMatcher = nricPattern.matcher(trimmedArgs); + if (trimmedArgs.isEmpty() || !nricMatcher.matches()) { + logger.warning("Can't parse find command - invalid input"); + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindAppointmentCommand.MESSAGE_USAGE)); + } + logger.info("Successfully parsed Find Command"); + AppointmentIcPredicate icPredicate = new AppointmentIcPredicate(trimmedArgs); + return new FindAppointmentCommand(icPredicate); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index 34706f94b99..8a7b10e2c85 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -17,6 +17,7 @@ public class FindCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the FindCommand * and returns a FindCommand object for execution. + * * @throws ParseException if the user input does not conform the expected format */ public FindCommand parse(String args) throws ParseException { diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/address/logic/parser/Parser.java index d6551ad8e3f..ce644a9c6fd 100644 --- a/src/main/java/seedu/address/logic/parser/Parser.java +++ b/src/main/java/seedu/address/logic/parser/Parser.java @@ -10,6 +10,7 @@ public interface Parser { /** * Parses {@code userInput} into a command and returns it. + * * @throws ParseException if {@code userInput} does not conform the expected format */ T parse(String userInput) throws ParseException; diff --git a/src/main/java/seedu/address/model/appointment/AppointmentIcPredicate.java b/src/main/java/seedu/address/model/appointment/AppointmentIcPredicate.java new file mode 100644 index 00000000000..0c7bda2655f --- /dev/null +++ b/src/main/java/seedu/address/model/appointment/AppointmentIcPredicate.java @@ -0,0 +1,46 @@ +package seedu.address.model.appointment; + +import java.util.function.Predicate; + +import seedu.address.commons.util.ToStringBuilder; + +/** + * Checks if an {@code appointment} has a patient or doctor, matching + * the query Ic {@code keywords}. + */ +public class AppointmentIcPredicate implements Predicate { + private final String keywords; + + public AppointmentIcPredicate(String keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Appointment appointment) { + if (keywords.equalsIgnoreCase(appointment.getPatient().toString())) { + return true; + } + return keywords.equalsIgnoreCase(appointment.getDoctor().toString()); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AppointmentIcPredicate)) { + return false; + } + + AppointmentIcPredicate otherAppointmentIcPredicate = (AppointmentIcPredicate) other; + return keywords.equals(otherAppointmentIcPredicate.keywords); + } + + @Override + public String toString() { + return new ToStringBuilder(this).add("keywords", keywords).toString(); + } +} + diff --git a/src/main/java/seedu/address/ui/AppointmentCard.java b/src/main/java/seedu/address/ui/AppointmentCard.java index 6484e080d3d..d67a060106d 100644 --- a/src/main/java/seedu/address/ui/AppointmentCard.java +++ b/src/main/java/seedu/address/ui/AppointmentCard.java @@ -39,7 +39,7 @@ public class AppointmentCard extends UiPart { public AppointmentCard(Appointment appointment, int displayedIndex) { super(FXML); this.appointment = appointment; - id.setText(displayedIndex + ". "); + id.setText("APPOINTMENT " + displayedIndex); patientIc.setText("Patient IC: " + this.appointment.getPatient().toString()); doctorIc.setText("Doctor IC: " + this.appointment.getDoctor().toString()); appointmentTime.setText("Time of appointment: " + this.appointment.getAppointmentTime().toString()); diff --git a/src/main/resources/view/AppointmentListCard.fxml b/src/main/resources/view/AppointmentListCard.fxml index 361fe04af76..7fcabe022e8 100644 --- a/src/main/resources/view/AppointmentListCard.fxml +++ b/src/main/resources/view/AppointmentListCard.fxml @@ -26,7 +26,7 @@