Skip to content

Commit

Permalink
Merge pull request #151 from chonguschonguschongus/branch-findAppoint…
Browse files Browse the repository at this point in the history
…ment

Add function to find Appointments by ICs of those involved
  • Loading branch information
chonguschonguschongus committed Nov 2, 2023
2 parents ddf47f6 + 053aa58 commit 8c330cc
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Appointment> predicate;
/**
* Finds and lists all persons in address book whose attributes match the predicate.
* Keyword matching is case insensitive.
*/
public FindAppointmentCommand(Predicate<Appointment> predicate) {
requireNonNull(predicate);
this.predicate = predicate;
}

@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredAppointmentList(predicate);
List<Appointment> 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();
}
}
2 changes: 2 additions & 0 deletions src/main/java/seedu/address/logic/commands/ListCommand.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class AddAppointmentCommandParser implements Parser<AddAppointmentCommand
*
* @throws ParseException if the user input does not conform the expected format
*/
@Override
public AddAppointmentCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_PATIENT_IC, PREFIX_DOCTOR_IC, PREFIX_APPOINTMENT_TIME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FindAppointmentCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
Expand Down Expand Up @@ -81,6 +82,9 @@ public Command parseCommand(String userInput) throws ParseException {
case FindCommand.COMMAND_WORD:
return new FindCommandParser().parse(arguments);

case FindAppointmentCommand.COMMAND_WORD:
return new FindAppointmentCommandParser().parse(arguments);

case ListCommand.COMMAND_WORD:
return new ListCommand();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class DeleteAppointmentCommandParser implements Parser<DeleteAppointmentC
/**
* 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 DeleteAppointmentCommand parse(String args) throws ParseException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class DeleteCommandParser implements Parser<DeleteCommand> {
/**
* 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class EditCommandParser implements Parser<EditCommand> {
/**
* 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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<FindAppointmentCommand> {
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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class FindCommandParser implements Parser<FindCommand> {
/**
* 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 {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public interface Parser<T extends Command> {

/**
* 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Appointment> {
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();
}
}

2 changes: 1 addition & 1 deletion src/main/java/seedu/address/ui/AppointmentCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class AppointmentCard extends UiPart<Region> {
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());
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/view/AppointmentListCard.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</HBox>
<Label fx:id="patientIc" styleClass="cell_small_label" text="\$patientIc"/>
<Label fx:id="doctorIc" styleClass="cell_small_label" text="\$doctorIc"/>
<Label fx:id="appointmentTime" styleClass="cell_small_label" text="\$appointmentTime"/>
<Label fx:id="appointmentTime" styleClass="cell_small_label" text="\$appointmentTime" wrapText="true"/>
</VBox>
</GridPane>
</HBox>
6 changes: 3 additions & 3 deletions src/main/resources/view/MainWindow.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@
</StackPane>

<HBox styleClass="pane-with-border" prefWidth="340" VBox.vgrow="ALWAYS">
<VBox fx:id="patientList" styleClass="pane-with-border" minWidth="340" prefWidth="340" HBox.hgrow="ALWAYS">
<VBox fx:id="patientList" styleClass="pane-with-border" minWidth="200" prefWidth="300" HBox.hgrow="ALWAYS">
<padding>
<Insets top="10" right="10" bottom="10" left="10"/>
</padding>
<StackPane fx:id="patientListPanelPlaceholder" VBox.vgrow="ALWAYS"/>
</VBox>
<VBox fx:id="doctorList" styleClass="pane-with-border" minWidth="340" prefWidth="340" HBox.hgrow="ALWAYS">
<VBox fx:id="doctorList" styleClass="pane-with-border" minWidth="200" prefWidth="300" HBox.hgrow="ALWAYS">
<padding>
<Insets top="10" right="10" bottom="10" left="10"/>
</padding>
<StackPane fx:id="doctorListPanelPlaceholder" VBox.vgrow="ALWAYS"/>
</VBox>
<VBox fx:id="appointmentList" styleClass="pane-with-border" minWidth="340" prefWidth="340" HBox.hgrow="ALWAYS">
<VBox fx:id="appointmentList" styleClass="pane-with-border" minWidth="100" prefWidth="100" HBox.hgrow="ALWAYS">
<padding>
<Insets top="10" right="10" bottom="10" left="10"/>
</padding>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;

import org.junit.jupiter.api.Test;

import seedu.address.logic.commands.FindAppointmentCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.appointment.AppointmentIcPredicate;

public class FindAppointmentCommandParserTest {
private FindAppointmentCommandParser parser = new FindAppointmentCommandParser();

private String testInput = "T1111111G";

@Test
public void parse_emptyArg_throwsParseException() {
assertParseFailure(parser, " ", String.format(MESSAGE_INVALID_COMMAND_FORMAT,
FindAppointmentCommand.MESSAGE_USAGE));
}

@Test
public void parse_validArgs_returnsFindCommand() throws ParseException {
// no leading and trailing whitespaces
FindAppointmentCommand expectedFindAppointmentCommand =
new FindAppointmentCommand(new AppointmentIcPredicate(testInput));
assertParseSuccess(parser, "T1111111G", expectedFindAppointmentCommand);
}
}

0 comments on commit 8c330cc

Please sign in to comment.