Skip to content

Commit

Permalink
Merge pull request #84 from Ella-e/branch-reformat-apt
Browse files Browse the repository at this point in the history
Reformat appointment command
  • Loading branch information
MaYuehan authored Mar 26, 2024
2 parents bac086e + 19321be commit 91e46c2
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 158 deletions.
68 changes: 31 additions & 37 deletions src/main/java/vitalconnect/logic/commands/CreateAptCommand.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package vitalconnect.logic.commands;

import static vitalconnect.logic.Messages.MESSAGE_PERSON_NOT_FOUND;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

import vitalconnect.logic.commands.exceptions.CommandException;
import vitalconnect.model.Appointment;
Expand All @@ -10,7 +12,6 @@
import vitalconnect.model.person.identificationinformation.Name;
import vitalconnect.model.person.identificationinformation.Nric;


/**
* Represents a command to create an appointment for a patient in the address book.
* This command schedules appointments by specifying the patient's NRIC
Expand All @@ -21,24 +22,24 @@ public class CreateAptCommand extends Command {
public static final String COMMAND_WORD = "adda";
public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Adds an appointment for a person in the address book. "
+ "Parameters: NRIC /time DATE TIME\n"
+ "Parameters: ic/ NRIC time/ DATE TIME\n"
+ "Example: " + COMMAND_WORD + " "
+ "S1234567D /time 02/02/2024 1330\n"
+ "Note: Ensure the date and time are in DD/MM/YYYY HHMM format.";
+ "ic/S1234567D time/ 02/02/2024 1330\n"
+ "Note: Ensure the date and time are in dd/MM/yyyy HHmm format.";

private final String patientIc;
private final String dateTimeStr;
private final Nric nric;
private final LocalDateTime dateTime;
private String patientName = null;

/**
* Constructs a {@code CreateAptCommand} to schedule an appointment.
*
* @param patientIc The NRIC of the patient for whom the appointment is being created.
* @param dateTimeStr The date and time of the appointment, in DD/MM/YYYY HHMM format.
* @param nric The NRIC of the patient for whom the appointment is being created.
* @param dateTime The date and time of the appointment, in DD/MM/YYYY HHMM format.
*/
public CreateAptCommand(String patientIc, String dateTimeStr) {
this.patientIc = patientIc;
this.dateTimeStr = dateTimeStr;
public CreateAptCommand(Nric nric, LocalDateTime dateTime) {
this.nric = nric;
this.dateTime = dateTime;
}


Expand All @@ -58,38 +59,31 @@ public CreateAptCommand(String patientIc, String dateTimeStr) {
*/
@Override
public CommandResult execute(Model model) throws CommandException {
try {
// Check if a person with the exact name exists
if (!model.doesIcExist(patientIc)) {
throw new CommandException("OOPS! The appointment cannot be created as the NRIC does not exist.");
}
// Parse and validate date time
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm");
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);
Nric nric = new Nric(patientIc);
Person person = model.findPersonByNric(nric);
Name name = person.getIdentificationInformation().getName();
this.patientName = name.toString();
Appointment appointment = new Appointment(patientName, patientIc, dateTime);
model.addAppointment(appointment);
// Check if a person with the exact name exists
// if person not exist, throw error
Person person = model.findPersonByNric(nric);
if (person == null) {
throw new CommandException(MESSAGE_PERSON_NOT_FOUND);
}

return new CommandResult(String.format("Created an appointment successfully!\nName: %s\nNRIC: %s\nTime: %s",
patientName, patientIc, dateTime.format(DateTimeFormatter.ofPattern("d MMM yyyy HH:mm"))),
false, false, CommandResult.Type.SHOW_APPOINTMENTS);
Name name = person.getIdentificationInformation().getName();
this.patientName = name.toString();
String patientIc = nric.toString();
Appointment appointment = new Appointment(patientName, patientIc, dateTime);
model.addAppointment(appointment);

} catch (DateTimeParseException e) {
throw new CommandException("OOPS! The appointment cannot be created "
+ "as the time is empty or not in the correct format.");
}
return new CommandResult(String.format("Created an appointment successfully!\nName: %s\nNRIC: %s\nTime: %s",
patientName, patientIc, dateTime.format(DateTimeFormatter.ofPattern("d MMM yyyy HH:mm"))),
false, false, CommandResult.Type.SHOW_APPOINTMENTS);
}

/**
* Returns the NRIC of the patient associated with this appointment.
*
* @return The patient's NRIC as a {@code String}.
*/
public String getPatientIc() {
return patientIc;
public Nric getPatientIc() {
return nric;
}

/**
Expand All @@ -105,7 +99,7 @@ public String getPatientName() {
*
* @return The date and time of the appointment in "dd/MM/yyyy HHmm" format.
*/
public String getDateTimeStr() {
return dateTimeStr;
public LocalDateTime getDateTimeStr() {
return dateTime;
}
}
41 changes: 11 additions & 30 deletions src/main/java/vitalconnect/logic/commands/DeleteAptCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.format.DateTimeFormatter;
import java.util.List;

import vitalconnect.commons.core.index.Index;
import vitalconnect.logic.commands.exceptions.CommandException;
import vitalconnect.model.Appointment;
import vitalconnect.model.Model;
Expand All @@ -15,23 +16,19 @@
*/
public class DeleteAptCommand extends Command {
public static final String COMMAND_WORD = "deletea";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes an appointment of a patient by the index "
+ "in the list and patient name.\n"
+ "Parameters: INDEX (must be a positive integer) /name NAME\n"
+ "Example: " + COMMAND_WORD + " 1 /name John Doe";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes an appointment of a patient by the index\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";

private final int index;
private final String patientName;
private final Index index;

/**
* Constructs a {@code DeleteAptCommand} with the specified index and patient name.
*
* @param index The index of the appointment to be deleted, as displayed to the user.
* @param patientName The name of the patient whose appointment is to be deleted.
*/
public DeleteAptCommand(int index, String patientName) {
public DeleteAptCommand(Index index) {
this.index = index;
this.patientName = patientName;
}

/**
Expand All @@ -55,20 +52,17 @@ public CommandResult execute(Model model) throws CommandException {
throw new CommandException("OOPS! The appointment list is empty.");
}

if (index < 1 || index > lastShownList.size()) {
if (index.getOneBased() < 1 || index.getOneBased() > lastShownList.size()) {
throw new CommandException("OOPS! The deletion of the appointment failed as the index of "
+ "appointment is out of range.");
}

Appointment appointmentToDelete = lastShownList.get(index - 1);
if (!appointmentToDelete.getPatientName().equals(patientName)) {
throw new CommandException("OOPS! The deletion of the appointment failed as the appointment of "
+ patientName + " does not exist in the appointment list.");
}
Appointment appointmentToDelete = lastShownList.get(index.getZeroBased());
String name = appointmentToDelete.getPatientName();

model.deleteAppointment(appointmentToDelete);
return new CommandResult(String.format("Deleted the appointment successfully:\nName: %s\nTime: %s",
patientName,
name,
appointmentToDelete.getDateTime().format(DateTimeFormatter.ofPattern("d MMM uuuu HH:mm"))),
false, false, CommandResult.Type.SHOW_APPOINTMENTS);
}
Expand All @@ -81,20 +75,7 @@ public CommandResult execute(Model model) throws CommandException {
*
* @return The index of the appointment to be deleted.
*/
public int getIndex() {
public Index getIndex() {
return index;
}

/**
* Gets the name of the patient associated with the appointment to be deleted.
* <p>
* This name is used to ensure that the correct appointment is deleted, especially
* in cases where there may be multiple appointments at the same index across
* different instances of lists displayed to the user.
*
* @return The name of the patient whose appointment is to be deleted.
*/
public String getPatientName() {
return patientName;
}
}
1 change: 1 addition & 0 deletions src/main/java/vitalconnect/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public class CliSyntax {
public static final Prefix PREFIX_ALLERGYTAG = new Prefix("t/");
public static final Prefix PREFIX_HEIGHT = new Prefix("h/");
public static final Prefix PREFIX_WEIGHT = new Prefix("w/");
public static final Prefix PREFIX_TIME = new Prefix("time/");

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package vitalconnect.logic.parser;

import static vitalconnect.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static vitalconnect.logic.parser.CliSyntax.PREFIX_NRIC;
import static vitalconnect.logic.parser.CliSyntax.PREFIX_TIME;

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

import vitalconnect.logic.commands.CreateAptCommand;
import vitalconnect.logic.parser.exceptions.ParseException;

import vitalconnect.model.person.identificationinformation.Nric;

/**
* Parses input arguments and creates a new CreateAptCommand object.
Expand All @@ -20,24 +27,40 @@ public class CreateAptCommandParser {
* the '/time' keyword and the appointment datetime in 'dd/MM/yyyy HHmm' format.
* If the arguments do not conform to this expected format, a ParseException is thrown.
*
* @param args The input arguments to be parsed, including the patient's NRIC and
* @param userInput The input arguments to be parsed, including the patient's NRIC and
* the appointment datetime.
* @return A new CreateAptCommand object encapsulating the parsed patient NRIC
* and appointment datetime.
* @throws ParseException If the provided arguments do not conform to the expected
* format or if other parsing errors occur.
*/
public CreateAptCommand parse(String args) throws ParseException {
final String[] nameAndDateTime = args.trim().split("/time", 2);
public CreateAptCommand parse(String userInput) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(userInput, PREFIX_NRIC, PREFIX_TIME);

if (nameAndDateTime.length < 2) {
throw new ParseException(CreateAptCommand.MESSAGE_USAGE);
if (!arePrefixesPresent(argMultimap, PREFIX_NRIC)
|| !arePrefixesPresent(argMultimap, PREFIX_TIME)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, CreateAptCommand.MESSAGE_USAGE));
}

String ic = nameAndDateTime[0].trim();
String dateTimeStr = nameAndDateTime[1].trim();

Nric ic = ParserUtil.parseNric(argMultimap.getValue(PREFIX_NRIC).get());
LocalDateTime dateTimeStr = null;
if (argMultimap.getValue(PREFIX_TIME).isPresent()) {
dateTimeStr = ParserUtil.parseTime(argMultimap.getValue(PREFIX_TIME).get());
}
if (dateTimeStr == null) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, CreateAptCommand.MESSAGE_USAGE));
}

return new CreateAptCommand(ic, dateTimeStr);
}

/**
* 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());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package vitalconnect.logic.parser;

import static vitalconnect.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import vitalconnect.commons.core.index.Index;
import vitalconnect.logic.commands.DeleteAptCommand;
import vitalconnect.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -28,26 +31,11 @@ public class DeleteAptCommandParser implements Parser<DeleteAptCommand> {
*/
public DeleteAptCommand parse(String args) throws ParseException {
try {
String trimmedArgs = args.trim();
if (!trimmedArgs.matches("\\d+ /name .+")) {
throw new ParseException(DeleteAptCommand.MESSAGE_USAGE);
}

String[] parts = trimmedArgs.split("/name");
if (parts.length != 2) {
throw new ParseException(DeleteAptCommand.MESSAGE_USAGE);
}

int index = Integer.parseInt(parts[0].trim());
String patientName = parts[1].trim();

if (index <= 0) {
throw new ParseException("Index must be a positive integer.");
}

return new DeleteAptCommand(index, patientName);
} catch (NumberFormatException e) {
throw new ParseException("The index provided is not a valid integer.");
Index index = ParserUtil.parseIndex(args);
return new DeleteAptCommand(index);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteAptCommand.MESSAGE_USAGE), pe);
}
}
}
19 changes: 18 additions & 1 deletion src/main/java/vitalconnect/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -113,7 +115,22 @@ public static Email parseEmail(String email) throws ParseException {
return new Email(trimmedEmail);
}


/**
* Parses a {@code String dateTimeStr} into a {@code Date}.
* @param dateTimeStr A string representing the date and time.
* @return A {@code Date} object representing the date and time.
* @throws ParseException if the given {@code String dateTimeStr} is invalid.
*/
public static LocalDateTime parseTime(String dateTimeStr) throws ParseException {
requireNonNull(dateTimeStr);
// Parse and validate date time
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm");
try {
return LocalDateTime.parse(dateTimeStr, formatter);
} catch (Exception e) {
throw new ParseException("Invalid date time format. Please enter in the format 'dd/MM/yyyy HHmm'.");
}
}

/**
* Parses a {@code String allergytag} into a {@code AllergyTag}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package vitalconnect.logic.commands;

import static vitalconnect.logic.Messages.MESSAGE_PERSON_NOT_FOUND;
import static vitalconnect.testutil.Assert.assertThrows;

import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
Expand All @@ -12,6 +14,8 @@
import javafx.collections.ObservableList;
import vitalconnect.commons.core.GuiSettings;
import vitalconnect.logic.commands.exceptions.CommandException;
import vitalconnect.logic.parser.ParserUtil;
import vitalconnect.logic.parser.exceptions.ParseException;
import vitalconnect.model.Appointment;
import vitalconnect.model.Model;
import vitalconnect.model.ReadOnlyClinic;
Expand All @@ -31,16 +35,14 @@
public class CreateAptCommandTest {

@Test
public void execute_icNotExist_throwsCommandException() {
public void execute_icNotExist_throwsCommandException() throws ParseException {
ModelStub modelStub = new ModelStubWithoutPerson();
String patientIc = "S1222222D";
String dateTimeStr = "02/02/2024 1330";
Nric patientIc = new Nric("S4848058F");
LocalDateTime dateTimeStr = ParserUtil.parseTime("02/02/2024 1330");
CreateAptCommand createAptCommand = new CreateAptCommand(patientIc, dateTimeStr);

assertThrows(CommandException.class,
"OOPS! The appointment cannot be created as the NRIC does not exist.", (

) -> createAptCommand.execute(modelStub));
MESSAGE_PERSON_NOT_FOUND, () -> createAptCommand.execute(modelStub));
}


Expand Down
Loading

0 comments on commit 91e46c2

Please sign in to comment.