Skip to content

Commit

Permalink
Merge pull request #84 from Vangmay/feature-addAppointment
Browse files Browse the repository at this point in the history
Feature add appointment
  • Loading branch information
jayjay19630 authored Oct 16, 2024
2 parents 97b891f + d595bb8 commit 344b8e5
Show file tree
Hide file tree
Showing 11 changed files with 421 additions and 6 deletions.
17 changes: 17 additions & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.stream.Stream;

import seedu.address.logic.parser.Prefix;
import seedu.address.model.appointment.AppointmentDescriptor;
import seedu.address.model.person.Person;
import seedu.address.model.person.PersonDescriptor;

Expand Down Expand Up @@ -56,4 +57,20 @@ public static String formatPerson(PersonDescriptor person) {
return builder.toString();
}

/**
* Formats the {@code appointment} for display to the user.
*/
public static String formatAppointment(AppointmentDescriptor appointment) {
final StringBuilder builder = new StringBuilder();
builder.append(appointment.getAppointmentType())
.append("; Id: ")
.append(appointment.getPersonId())
.append("; Date and Time")
.append(appointment.getAppointmentDateTime())
.append("; Sickness: ")
.append(appointment.getSickness())
.append("; Medicine: ")
.append(appointment.getMedicine());
return builder.toString();
}
}
121 changes: 121 additions & 0 deletions src/main/java/seedu/address/logic/commands/AddAppointmentCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_APPOINTMENT_TYPE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DATETIME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_MEDICINE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PERSON_ID;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SICKNESS;

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.AppointmentDescriptor;

/**
* Adds an appointment to the appointment book.
*/
public class AddAppointmentCommand extends AddCommand {
public static final String COMMAND_WORD = "add appt";
public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Adds an appointment to the appointment book. "
+ "Parameters: "
+ PREFIX_APPOINTMENT_TYPE + "Appointment_TYPE"
+ PREFIX_PERSON_ID + "PersonId"
+ PREFIX_DATETIME + "Date"
+ PREFIX_SICKNESS + "Sickness"
+ PREFIX_MEDICINE + "Medicine"
+ "Example: " + COMMAND_WORD
+ PREFIX_APPOINTMENT_TYPE + "Check up"
+ PREFIX_DATETIME + "16/10/2024 12:00"
+ PREFIX_PERSON_ID + "1"
+ PREFIX_SICKNESS + "Common Cold"
+ PREFIX_MEDICINE + "Paracetamol";

public static final String MESSAGE_SUCCESS = "New appointment added: %1$s";
public static final String MESSAGE_DUPLICATE_APPOINTMENT = "This appointment already exists in the address book";

private final AppointmentDescriptor toAdd;

/**
* Creates an AddAppointmentCommand to add the specified {@code Appointment}
*/
public AddAppointmentCommand(AppointmentDescriptor appointment) {
requireNonNull(appointment);
toAdd = appointment;
}

/*
* Checks if the entity being added to model already exists.
*/
@Override
protected boolean alreadyExists(Model model) {
return model.hasAppointment(toAdd);
};

/*
* Adds the entity to the model.
*/
@Override
protected void addEntity(Model model) {
model.addAppointment(toAdd);
};

/*
* Returns success message to display upon adding entity.
*/
@Override
protected String getSuccessMessage() {
return MESSAGE_SUCCESS;
};

/*
* Returns the message to display when there is a duplicate.
*/
@Override
protected String getDuplicateEntityMessage() {
return MESSAGE_DUPLICATE_APPOINTMENT;
};

/**
* Formats the entity for displaying in the success message.
*/
@Override
protected String formatEntity() {
return Messages.formatAppointment(toAdd);
};

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

if (alreadyExists(model)) {
throw new CommandException(getDuplicateEntityMessage());
}

addEntity(model);
return new CommandResult(String.format(getSuccessMessage(), formatEntity()));
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof AddAppointmentCommand otherAddAppointmentCommand)) {
return false;
}

return toAdd.equals(otherAddAppointmentCommand.toAdd);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("toAdd", toAdd)
.toString();
}
}
36 changes: 34 additions & 2 deletions src/main/java/seedu/address/logic/parser/AddCommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,30 @@

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_APPOINTMENT_TYPE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DATETIME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
import static seedu.address.logic.parser.CliSyntax.PREFIX_MEDICINE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PERSON_ID;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SICKNESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
import static seedu.address.logic.parser.ParserUtil.APPOINTMENT_ENTITY_STRING;
import static seedu.address.logic.parser.ParserUtil.PERSON_ENTITY_STRING;

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

import seedu.address.logic.commands.AddAppointmentCommand;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.AddPersonCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.appointment.AppointmentDescriptor;
import seedu.address.model.appointment.AppointmentType;
import seedu.address.model.appointment.Medicine;
import seedu.address.model.appointment.Sickness;
import seedu.address.model.person.Address;
import seedu.address.model.person.Email;
import seedu.address.model.person.Name;
Expand All @@ -34,7 +45,9 @@ public class AddCommandParser implements Parser<AddCommand> {
*/
public AddCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
PREFIX_TAG, PREFIX_PERSON_ID, PREFIX_DATETIME,
PREFIX_APPOINTMENT_TYPE, PREFIX_SICKNESS, PREFIX_MEDICINE);
String entityType = argMultimap.getEntityType();

switch (entityType) {
Expand All @@ -54,7 +67,26 @@ public AddCommand parse(String args) throws ParseException {

return new AddPersonCommand(person);
case APPOINTMENT_ENTITY_STRING:
//TODO: Instantiate and return AddAppointmentCommand
if (!arePrefixesPresent(argMultimap, PREFIX_PERSON_ID, PREFIX_DATETIME,
PREFIX_APPOINTMENT_TYPE, PREFIX_SICKNESS, PREFIX_MEDICINE)) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddAppointmentCommand.MESSAGE_USAGE));
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_PERSON_ID, PREFIX_DATETIME,
PREFIX_APPOINTMENT_TYPE, PREFIX_SICKNESS, PREFIX_MEDICINE);
int personId = ParserUtil.parsePersonId(argMultimap.getValue(PREFIX_PERSON_ID).get());
LocalDateTime appointmentDateTime = ParserUtil.parseAppointmentDateTime(
argMultimap.getValue(PREFIX_DATETIME).get());
AppointmentType appointmentType = ParserUtil.parseAppointmentType(
argMultimap.getValue(PREFIX_APPOINTMENT_TYPE).get());
Sickness sickness = ParserUtil.parseSickness(argMultimap.getValue(PREFIX_SICKNESS).get());
Medicine medicine = ParserUtil.parseMedicine(argMultimap.getValue(PREFIX_MEDICINE).get());

AppointmentDescriptor appointment = new AppointmentDescriptor(
appointmentType, appointmentDateTime, personId, sickness, medicine);

return new AddAppointmentCommand(appointment);
default:
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class CliSyntax {
public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
public static final Prefix PREFIX_TAG = new Prefix("t/");

public static final Prefix PREFIX_PERSON_ID = new Prefix("i/");
public static final Prefix PREFIX_DATETIME = new Prefix("d/");
public static final Prefix PREFIX_APPOINTMENT_TYPE = new Prefix("t/");
public static final Prefix PREFIX_MEDICINE = new Prefix("m/");
public static final Prefix PREFIX_SICKNESS = new Prefix("s/");
Expand Down
84 changes: 84 additions & 0 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.StringUtil;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.appointment.AppointmentType;
import seedu.address.model.appointment.Medicine;
import seedu.address.model.appointment.Sickness;
import seedu.address.model.person.Address;
import seedu.address.model.person.Email;
import seedu.address.model.person.Name;
Expand Down Expand Up @@ -123,4 +129,82 @@ public static Set<Tag> parseTags(Collection<String> tags) throws ParseException
}
return tagSet;
}

/**
* Parses a {@code String personId} into a {@code int personId}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code personId} is invalid.
*/
public static int parsePersonId(String personId) throws ParseException {
requireNonNull(personId);
String trimmerPersonId = personId.trim();
int parsedPersonId = Integer.parseInt(trimmerPersonId);
if (parsedPersonId < 0) {
throw new ParseException("person Id needs to be a positive intger");
}
return parsedPersonId;
};


/**
* Parses a {@code String appointmentDateTime} into a {@code LocalDateTime}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code appointmentDateTime} is invalid.
*/
public static LocalDateTime parseAppointmentDateTime(String appointmentDateTime) throws ParseException {
requireNonNull(appointmentDateTime);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
try {
return LocalDateTime.parse(appointmentDateTime, formatter);
} catch (DateTimeParseException e) {
throw new ParseException("Invalid date-time format. Expected format: YYYY-MM-DD HH:mm:ss", e);
}
}

/**
* Parses a {@code String appointmentType} into a {@code AppointmentType}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code appointmentType} is invalid.
*/
public static AppointmentType parseAppointmentType(String appointmentType) throws ParseException {
requireNonNull(appointmentType);
String trimmedAppointmentType = appointmentType.trim();
if (!AppointmentType.isValidAppointmentType(trimmedAppointmentType)) {
throw new ParseException(AppointmentType.MESSAGE_CONSTRAINTS);
}
return new AppointmentType(trimmedAppointmentType);
}

/**
* Parses a {@code String sickness} into a {@code Sickness}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code sickness} is invalid.
*/
public static Sickness parseSickness(String sickness) throws ParseException {
requireNonNull(sickness);
String trimmedSickness = sickness.trim();
if (!Sickness.isValidSickness(sickness)) {
throw new ParseException(Sickness.MESSAGE_CONSTRAINTS);
}
return new Sickness(trimmedSickness);
}

/**
* Parses a {@code String medicine} into a {@code Medicine}.
* Leading and trailing whitespaces will be trimmed.
*
* @throws ParseException if the given {@code medicine} is invalid.
*/
public static Medicine parseMedicine(String medicine) throws ParseException {
requireNonNull(medicine);
String trimmedMedicine = medicine.trim();
if (!Medicine.isValidMedicine(medicine)) {
throw new ParseException(Medicine.MESSAGE_CONSTRAINTS);
}
return new Medicine(trimmedMedicine);
}
}
19 changes: 19 additions & 0 deletions src/main/java/seedu/address/model/AppointmentBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.appointment.Appointment;
import seedu.address.model.appointment.AppointmentDescriptor;
import seedu.address.model.appointment.UniqueAppointmentList;

/**
Expand Down Expand Up @@ -67,6 +68,14 @@ public boolean hasAppointment(Appointment appointment) {
return appointments.contains(appointment);
}

/**
* Returns true if an appointment with the same identity as {@code appointment} exists in the appointment book.
*/
public boolean hasAppointment(AppointmentDescriptor appointmentDescriptor) {
requireNonNull(appointmentDescriptor);
return appointments.contains(appointmentDescriptor);
}

/**
* Adds an appointment to the appointment book.
* The appointment must not already exist in the appointment book.
Expand All @@ -76,6 +85,16 @@ public String addAppointment(Appointment appointment) {
return appointment.toString();
}

/**
* Adds an appointment to the appointment book.
* The appointment must not already exist in the appointment book.
*/
public String addAppointment(AppointmentDescriptor appointmentDescriptor) {
requireNonNull(appointmentDescriptor);
appointments.add(new Appointment(appointmentDescriptor));
return appointmentDescriptor.toString();
}

/**
* Replaces the given appointment {@code target} in the list with {@code editedAppointment}.
* {@code target} must exist in the appointment book.
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.appointment.Appointment;
import seedu.address.model.appointment.AppointmentDescriptor;
import seedu.address.model.person.Person;
import seedu.address.model.person.PersonDescriptor;

Expand Down Expand Up @@ -104,7 +105,7 @@ public interface Model {
/**
* Returns true if an appointment with the same identity as {@code appointment} exists in the appointment book.
*/
boolean hasAppointment(Appointment appointment);
boolean hasAppointment(AppointmentDescriptor appointmentDescriptor);

/**
* Deletes the given appointment.
Expand All @@ -116,7 +117,7 @@ public interface Model {
* Adds the given appointment.
* {@code appointment} must not already exist in the appointment book.
*/
void addAppointment(Appointment appointment);
void addAppointment(AppointmentDescriptor appointmentDescriptor);

/**
* Replaces the given appointment {@code target} with {@code editedAppointment}.
Expand Down
Loading

0 comments on commit 344b8e5

Please sign in to comment.