diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 271c7caed66..677105f366d 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -5,6 +5,7 @@ import java.util.stream.Stream; import seedu.address.logic.parser.Prefix; +import seedu.address.model.appointment.Appointment; import seedu.address.model.person.Person; /** @@ -19,6 +20,7 @@ public class Messages { public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; 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!"; /** * Returns an error message indicating the duplicate prefixes. @@ -51,4 +53,20 @@ public static String format(Person person) { return builder.toString(); } + /** + * Formats the {@code appointment} for display to the user. + */ + public static String format(Appointment appointment) { + final StringBuilder builder = new StringBuilder(); + builder.append("Patient involved: ") + .append(appointment.getPatient()) + .append("; Doctor involved: ") + .append(appointment.getDoctor()) + .append("; Time of appointment: ") + .append(appointment.getAppointmentTime()) + .append("; Status: ") + .append(appointment.getStatus()); + return builder.toString(); + } + } diff --git a/src/main/java/seedu/address/logic/commands/DeleteAppointmentCommand.java b/src/main/java/seedu/address/logic/commands/DeleteAppointmentCommand.java new file mode 100644 index 00000000000..4473cc6d1d7 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeleteAppointmentCommand.java @@ -0,0 +1,78 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.appointment.Appointment; + +/** + * Deletes a person identified using it's displayed index from the address book. + */ +public class DeleteAppointmentCommand extends Command { + + public static final String COMMAND_WORD = "delete-appt"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Deletes the person identified by specified index in the Appointments list.\n" + + "Parameters: valid integer as shown in Appointments list \n" + + "Example: " + COMMAND_WORD + " 1"; + + public static final String MESSAGE_DELETE_APPOINTMENT_SUCCESS = "Deleted Appointment: %1$s"; + private static final Logger logger = LogsCenter.getLogger(DeleteAppointmentCommand.class); + + private final int targetIndex; + + public DeleteAppointmentCommand(int targetIndex) { + this.targetIndex = targetIndex; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownList = new ArrayList<>(); + lastShownList.addAll(model.getFilteredAppointmentList()); + try { + Appointment target = lastShownList.get(targetIndex - 1); + model.deleteAppointment(target); + List updatedList = new ArrayList<>(); + updatedList.addAll(model.getFilteredAppointmentList()); + assert updatedList.size() < lastShownList.size(); + logger.info("Successfully deleted appointment"); + return new CommandResult(String.format(MESSAGE_DELETE_APPOINTMENT_SUCCESS, Messages.format(target))); + } catch (IndexOutOfBoundsException e) { + logger.warning("Appointment does not exist"); + throw new CommandException(Messages.MESSAGE_APPOINTMENT_NOT_FOUND); + } + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof DeleteAppointmentCommand)) { + return false; + } + + DeleteAppointmentCommand otherDeleteAppointmentCommand = (DeleteAppointmentCommand) other; + return targetIndex == otherDeleteAppointmentCommand.targetIndex; + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("targetIc", targetIndex) + .toString(); + } +} + diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index c328d25f820..ac354af757b 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -14,6 +14,7 @@ import seedu.address.logic.commands.AddPatientCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.DeleteAppointmentCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; @@ -71,6 +72,9 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteCommand.COMMAND_WORD: return new DeleteCommandParser().parse(arguments); + case DeleteAppointmentCommand.COMMAND_WORD: + return new DeleteAppointmentCommandParser().parse(arguments); + case ClearCommand.COMMAND_WORD: return new ClearCommand(); diff --git a/src/main/java/seedu/address/logic/parser/DeleteAppointmentCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteAppointmentCommandParser.java new file mode 100644 index 00000000000..6d50cae6846 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeleteAppointmentCommandParser.java @@ -0,0 +1,34 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.logging.Logger; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.logic.commands.DeleteAppointmentCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new DeleteCommand object + */ +public class DeleteAppointmentCommandParser implements Parser { + private static final Logger logger = LogsCenter.getLogger(DeleteCommandParser.class); + /** + * 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 { + String trimmedArgs = args.trim(); + try { + int index = Integer.parseInt(trimmedArgs); + logger.info("Successfully parsed integer from DeleteAppointmentCommand: " + index); + return new DeleteAppointmentCommand(index); + } catch (NumberFormatException e) { + logger.warning("Invalid user input for delete appointment command"); + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteAppointmentCommand.MESSAGE_USAGE), e); + } + } + +} diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index bfc5c6e180d..11bb66860c8 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -80,6 +80,8 @@ public interface Model { */ void addPerson(Person person); + void deleteAppointment(Appointment appointment); + /** * Replaces the given person {@code target} with {@code editedPerson}. * {@code target} must exist in the address book. diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 5a7184579d9..3f8bd58a580 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -172,6 +172,13 @@ public void addAppointment(Appointment appointment) { updateFilteredAppointmentList(PREDICATE_SHOW_ALL_APPOINTMENTS); } + @Override + public void deleteAppointment(Appointment appointment) { + updateBackup(); + addressBook.removeAppointment(appointment); + updateFilteredAppointmentList(PREDICATE_SHOW_ALL_APPOINTMENTS); + } + @Override public void setPerson(Person target, Person editedPerson) { requireAllNonNull(target, editedPerson); diff --git a/src/test/java/seedu/address/logic/commands/AddDoctorCommandTest.java b/src/test/java/seedu/address/logic/commands/AddDoctorCommandTest.java index dd006436d78..a5f7e280226 100644 --- a/src/test/java/seedu/address/logic/commands/AddDoctorCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddDoctorCommandTest.java @@ -127,6 +127,11 @@ public void addPerson(Person person) { throw new AssertionError("This method should not be called."); } + @Override + public void deleteAppointment(Appointment appointment) { + throw new AssertionError("This method should not be called."); + } + @Override public void setAddressBook(ReadOnlyAddressBook newData) { throw new AssertionError("This method should not be called."); diff --git a/src/test/java/seedu/address/logic/commands/AddPatientCommandTest.java b/src/test/java/seedu/address/logic/commands/AddPatientCommandTest.java index b303414f3fb..c5ff15b1fcd 100644 --- a/src/test/java/seedu/address/logic/commands/AddPatientCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddPatientCommandTest.java @@ -127,6 +127,11 @@ public void addPerson(Person person) { throw new AssertionError("This method should not be called."); } + @Override + public void deleteAppointment(Appointment appointment) { + throw new AssertionError("This method should not be called."); + } + @Override public void setAddressBook(ReadOnlyAddressBook newData) { throw new AssertionError("This method should not be called."); diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index ebb406370d4..6a51ab4b681 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -11,6 +11,7 @@ import seedu.address.logic.commands.AddPatientCommand; import seedu.address.logic.commands.ClearCommand; +import seedu.address.logic.commands.DeleteAppointmentCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.EditCommand.EditPersonDescriptor; @@ -49,6 +50,13 @@ public void parseCommand_delete() throws Exception { assertEquals(new DeleteCommand(FIRST_NRIC), command); } + @Test + public void parseCommand_deleteAppointment() throws Exception { + DeleteAppointmentCommand command = (DeleteAppointmentCommand) parser.parseCommand( + DeleteAppointmentCommand.COMMAND_WORD + " 1"); + assertEquals(new DeleteAppointmentCommand(1), command); + } + @Test public void parseCommand_edit() throws Exception { Patient person = new PatientBuilder().build(); diff --git a/src/test/java/seedu/address/logic/parser/DeleteAppointmentCommandParserTest.java b/src/test/java/seedu/address/logic/parser/DeleteAppointmentCommandParserTest.java new file mode 100644 index 00000000000..448baab0690 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/DeleteAppointmentCommandParserTest.java @@ -0,0 +1,24 @@ +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.DeleteAppointmentCommand; + +public class DeleteAppointmentCommandParserTest { + private DeleteAppointmentCommandParser parser = new DeleteAppointmentCommandParser(); + + @Test + public void parseValidArgs_returnsDeleteAppointmentCommand() { + assertParseSuccess(parser, "1", new DeleteAppointmentCommand(1)); + } + + @Test + public void parseInvalidArgs_throwsParseException() { + assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DeleteAppointmentCommand.MESSAGE_USAGE)); + } +}