Overview
Doctor on Call is a secure desktop address book application used for doctors to keep records of their patients' details, status and appointment details. The doctor logs in with his username and password. He interacts with it using a CLI and can print a timetable showing him a list of all patients who have appointments with him. He is also able to refer patients to other doctors. Do note that the "person" in the traditional addresbook shall now be named patient.
Summary of contributions
-
First Major enhancement: added an
appointment
feature that generates a timetable for the doctor, displaying in chronological order the appointments he has.-
What it does: First, it searches for all patients who are patients of this doctor. Then, it sorts them by their appointment date. Lastly, it removes the unimportant information of the patient and displays it on the UI.
-
Justification: This feature improves the productivity and time management skills of a doctor because in one glance, he is able to see all the appointments that he has.
-
Highlights: This enhancement required the implementation of new attributes to a person. Two new columns were added to store the information about the doctor and the appointment date. It required changes to the existing add command and in-depth analysis of the parser, logic, person and mainwindow classes. The implementation of this command utilized several methods and packages such as the LocalDateTime package. The methods used to implement the new classes here were studied and used by other team members, especially for the
SortAppointment
command.
-
-
Second Major enhancement: added a
apptDate
feature that prints out the timetable for a doctor on a specific day.-
What it does: First, it searches for all patients who are patients of this doctor. Then, it sorts them by their appointment date. Lastly, it traverses this list of persons to select only those who have appointments on the specified date.
-
Justification: This feature allows doctor to see a beautiful timeline of his appointments for that day.
-
Highlights: Its a beautiful timeline that was tedious to implement
-
Credits: {utilized the Java package LocalDateTime, and adapted much code from the name class corresponding to a person}
-
-
Minor enhancement: added two new columns that allows a doctor to add appointment date and doctors corresponding to a patient.
-
Code contributed: [Reposense]
-
Other contributions:
-
Project management:
-
Booked group study rooms for weekly meetings and helped organize timings to meet.
-
-
Enhancements to existing features: ***Created the two classes on doctor and appointment, of which various other commands and sorts require these classes.
-
Documentation:
-
Did tweaks to the user guide and developer guide.
-
-
Community:
-
Reviewed the Pull requests of other members
-
Reported bugs and fixed them for v1.3
-
-
Tools:
-
Integrated a java package LocalDateTime.
-
-
{you can add/remove categories in the list above}
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Adding a person: add
Adds a person to the address book.
Format: add NAME [p]p/PHONE_NUMBER [p]e/EMAIL [p]a/ADDRESS m/APPOINTMENTDATE d/DOCTORNAME s/STATUS [t/TAG]…
Examples:
-
add John Doe p/98765432 e/johnd@gmail.com a/John street, block 123, #01-01 m/2020 12 11 14 30 d/DoctorTan s/Observation
-
add Betsy Crowe pp/1234567 e/betsycrowe@gmail.com pa/Newgate Prison m/2020 11 04 08 00 d/DoctorTan s/Observation t/criminal t/friend
Listing all appointments of a Doctor : appointment
Displays a list of all patients who have appointments with a specific doctor. The list of persons are sorted by on chronological order of their appointment dates. For easy-readability, only the name and appointment date of each person is displayed.
Format: appointment DOCTOR_NAME
Examples:
-
appointment DoctorTan
Shows a list of all patients who have appointments with DoctorTan.
Printing out the timetable (day) of a Doctor : apptDate
Displays the doctor’s appointment timetable for a specific day. A nice timeline will be shown. Can be used for dates older than the current date. (appointment history) Each time slot is 15 minutes. The timeline shows all the slots in the day, and indicates which slots are available or occupied.
Format: apptDate DOCTOR_NAME m/YYYY MM DD
Examples:
-
apptDate DoctorTan m/2020 11 04
Shows a list of all patients who have appointments with DoctorTan on 4th of November.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Add Doctor feature
Current Implementation
the add doctor feature facilitated by the Doctor
class, it implements the following operations:
-
Doctor(String)
— The constructor for the classDoctor
. -
toString()
— Returns a String containing the name of the patient’s doctor. -
isValidName()
— Checks if the date is alphanumeric. -
equals(Object)
— Checks if two patients' doctors are equal.
In addition to the Appointment class, we update the ReadOnlyPerson interface and the Person class (which implements the interface) to ensure that every Person object is constructed with an Appointment class. To be specific, the following operations are added or updated.
-
Person(Doctor doctor)
— The classPerson
now requires a Doctor object during its construction. -
getDoctor()
— The classPerson
implements a method that returns the Doctor object of a Person. -
getAsTextShowAll()
— This operation is updated to allow a person’s doctor to be printed when an addresbook’s lastShownList is printed onto the UI.
The example usage scenario is similar to the scenario of the Add appointment feature below.
Add Appointment feature
Current Implementation
the add appointment feature is facilitated by the Appointment
class, it implements the following operations:
-
Appointment(String)
— The constructor for the classAppointment
. -
toString()
— Returns a String containing the date of the appointment. -
isValidDate()
— Checks if the date is alphanumeric. -
equals(Object)
— Checks if two appointment dates are equal.
In addition to the Appointment class, we update the ReadOnlyPerson interface and the Person class (which implements the interface) to ensure that every Person object is constructed with an Appointment class. To be specific, the following operations are added or updated.
-
Person(Apppointment appointment)
— The classPerson
now requires an Appointment object during its construction. -
getAppointment()
— The classPerson
implements a method that returns the Appointment object of a Person. -
getAsTextShowAll()
— This operation is updated to allow a person’s appointment date to be printed when an addresbook’s lastShownList is printed onto the UI.
Next, the parser is updated to recognize user input corresponding to the Appointment object of a person. It works together with an updated Add
Command. When adding a new person through the add command, the user has to write m/APPOINTMENTDATE' to signify the `Appointment
portion of a Person
.
Given below is an example usage scenario and how the Appointment
feature is incorporated at each step.
Step 1. The user executes command Add NAME [p]p/PHONE [p]e/EMAIL [p]a/ADDRESS m/APPOINTMENT [t/TAG]…\n\t"
Step 2. The parser parses the user command, verifying that the APPOINTMENT is of the 24 hour format YYYY MM DD HH MM. Then, it creates the relevant object for Appointment
, Address
etc, and a new Person
object is constructed. The Logic
class executes the AddCommand
with the prepared arguments.
Step 3. The Addressbook
tries to add the new person into the uniquePersonList
. But first, the uniquePersonList
checks if the new Person object is a duplicate of an existing Person object in the Addressbook. If the Person is not a duplicate, it is added into the Addresbook and the Addressbook is saved. Note that two patients cannot have the same appointment timing with the same doctor.
Step 4. The successful execution returns a MESSAGE_SUCCESS along with the added person. The MainWindow displays the result and prints the added person into the GUI.
DoctorAppointments feature
Current Implementation
This is a new feature, that is executed as appointment DOCTORNAME
. It finds all Persons in the addressbook that are assigned to a doctor with the same name as DOCTORNAME. Then, it prints out a list of them sorted according to Appointment dates. The first person from the top has the earliest appointment date. Let us split the implementation documentation into two parts. (1) Returning a list of persons corresponding to the user input’s name of the doctor in chronological order. (2)Printing only the relevant information of these persons in a neat manner similar to a time-table.
For the first part, finding and sorting the list of corresponding persons is facilitated by the DoctorAppointmentsCommand
class and the Person
class. The following operations are implemented in the DoctorAppointmentsCommand
class.
-
execute()
— Upon execution, a newIndicator
class stores information indicating thatDoctorAppointmentsCommand
is the most recently invoked command. Then, the following methodgetPersonsWithName(doctor)
is called. -
getPersonsWithName(doctor)
— This method is adapted from theFindCommand
class method. In addition to the original command, this method utilizes the package on LocalDate and Collections.Sort. This method updates aLocalDateTime
field in aPerson
object (to be explained in the next paragraph). This method also calls SortDate() which is a separate sorting class that helps to compareLocalDate
dates and sort them based on chronological order. This method returns an ArrayList of Persons that have the doctor’s name corresponding to the user input’s doctor. The ArrayList is sorted based on their appointment dates.
We update the Person
class to contain an additional field LocalDateTime date
which is originally set to null for every person in the addressbook. Then the following getters and setters are implemented in the Person
class and their method signatures are updated in the ReadOnlyPerson
interface.
-
getLocalDateTime()
-
setLocalDateTime()
Given below is an example usage scenario and how the Persons corresponding to a certain doctor are sorted and listed in Chronological order.
Step 1. The user executes command appointment DOCTORNAME"
Step 2. The parser parses the command and prepares the keyword arguments for the DoctorAppointmentsCommand
class.
Step 3. DoctorAppointmentsCommand
is executed and the Indicator
class records that this is the most recently invoked command. The execute command calls getPersonsWithName(doctor)
. For each Person in the existing addressbook, if the Person’s doctor corresponds to DOCTORNAME, the LocalDateTime
class parses the person’s appointment date, and the Person’s LocalDateTime
date field is set to be the parsed appointment date.
Step 4. The person is added into the matchedPersons list.
Step 5. The list of matchedPersons are sorted based on the LocaldateTime
date field in each person.
Step 6. The sorted list of matchedPersons are returned and displayed in a table format (explained in second part)
For the second part of the implementation, we discuss how the list of matchedPersons is formatted to print in a certain manner. To facilitate the printing, we mainly update the format() method of the UI Formatter
class.
To facilitate the update, a new Indicator
class is created and a new method is implemented in the ReadonlyPerson
interface.
-
Indicator.setLastCommand(String)
--when called, stores a String that records the last invoked user Command. -
Indicator.getLastCommand()
--when called, provides information on the last invoked user Command. -
getAsTextNameDateDoctor()
--This is a method of theReadOnlyPerson
interface. It is a new String builder that builds a String of information about the Person. The information contains only the name and appointment date of the person. The String is padded on the right with whitespace to ensure a tabular format.
The UI Formatter
is updated in the following way.
-
format(Persons)
--Checks if the last invoked user Command is theDoctorAppointmentsCommand
. If it is, calls the new String builder methodgetAsTextNameDateDoctor()
for each Person to be formatted.
Given below is an example usage scenario and the formatter formats the Person to be printed in a tabular format. It continues from Step 6 above.
Step 7. When the display method is called in step 6, the format method in Formatter
is called.
Step 8. A separate String builder method getAsTextNameDateDoctor() is called, and the String is padded on the right by whitespace.
Step 9. The MainWindow
displays the newly formatted Persons in neat rows, displaying only the relevant information on Name and Appointment Date.
The sequence diagram below shows the interactions between the various classes when the appointment DOCTOR
command is executed.
ApptDate feature
Current Implementation
This feature displays a doctor’s appointment timetable for a specific day.
This is a new feature, that is executed as apptDate DOCTORNAME m/YYYY MM DD
.
When the parser parses the user command that starts with the apptDate
commandword, it instantiates an object of the class ApptDate.
The user specfied date and doctor’s name are stored as static fields in the class.
Next, the logic class calls this object to be executed.
The method execute()
is similar in implementation to the execute()
method of the previous appointment feature.
In summary, the execute()
method calls the method getPersonsWithSameDoctorSameDate()
.
getPersonsWithSameDoctorSameDate()
finds all Persons in the addressbook that have the same doctor as the user’s specified doctor.
Then, it traverses the lists of matchedPersons to select only the Persons that have the same appointment date as the user specified date that is of the format YYYY MM DD.
Then, it returns a matchedPersonsList that is used for the Command Result and for the last shown list.
At the same time, we build a long string called timetable
. This formatting of this string is tedious.
Some methods involve padding of whitespaces and printing out time-slots of 15min starting from 6am.
If anyone is confused by the 'for' loop, the iterator 'i' signifies the number of minutes that have elapsed since 00:00 hours of that day.
We convert the appointment time of each matchedPerson into the number of minutes from 00:00.
If the iterator 'i' matches the appointment timing of a Person, we print out the Person beside that time-slot.
The UI Formatter
facilitates the printing of timetable.
-
format(Persons)
--Checks if the last invoked user Command is theApptDateCommand
. If it is, it retrieves the timetable from theApptDate
class, and prints out the neatly formatted timetable.
Appendix A: Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
Add Appointment feature
-
Invalid appointment value
-
Prerequisites: please ensure that the addressbook is cleared. You can do this by the
clear
command. -
Test case 1:
add John p/98765432 e/john@gmail.com a/John street, block 123, #01-01 m/1800 12 11 12 30 d/DoctorTan s/Observation
Expected: The test case fails because appointments earlier than the current time are not allowed.
Prints outInvalid command format!
message followed by a reminder
Appointment timings must not be earlier than current time,
must be in the 24hr format of yyyy MM dd hh mm.
Additionally appointment slots are in blocks of 15min.
Thus, the time in minutes must be 00, 15, 30 or 45. No appointments earlier than 6am.
-
-
Invalid Doctor’s name
-
Same appointment timing with the same doctor
-
Same appointment timing with another Person, but different doctor
-
Duplicate person details but different appointment
-
Successful adding of person
DoctorAppointments feature
-
appointment command
ApptDate feature
-
apptDate command