Parser class and its functions are adapted with inspiration from Ria’s IP and help from regex101.
Storage class and its functions are largely adapted from Dhanish’s IP on Duke.
OneDoc
from here.tp.jar
into an empty folder.java -jar tp.jar
into the command line. The app should start running.The architecture diagram above shows the high-level design of the application.
Below is a quick overview of the main components and how each component interacts with one another.
OneDoc
is the main class of the application. It is responsible for
The rest of the app consists of six components, with three of them having a similar nature.
UI
: The user interface of the app.Parser
: Parses the user commands and initiates different action to the list.XyzList
: The lists for manipulating patients, visits and prescriptions. (Xyz is a placeholder for Patient
,
Visit
or Prescription
)Storage
: Reads data from and writes data to the hard disk.The object diagram below shows how are the instances of the components are connected on initialization.
The following two sequence diagrams shows how the main flow of the app is navigating between main menu and the three sub
menus. OneDoc
component mainly interacts with UI
and Parser
components. (Xyz is a placeholder for Patient
,
Visit
or Prescription
. For example for Patient
, the main menu state enum is MainMenuState.PATIENT
and the parser
function is patientParser(input)
)
The sequence diagram below shows how the components interact with each other for the scenario where the user issues the
command activate x/1
in the Prescription Sub Menu.
Each of the main components defines its API in a class with the same name as the component. The sections below give more details of each component.
The PatientList
Component,
The Patient and PatientList classes are used in conjunction to manage patients, and the list of patients. Each patient has a name, a unique ID, a date of birth and gender. The PatientList class holds an ArrayList of Patients and manipulates them accordingly, using a UI object to print output where necessary.
At the start of the program, a new PatientList object is instantiated. Through methods in the Storage class, invalid data is ignored while valid data is read from the relevant text files to create Patients that existed prior to the last closure of the program. The patients are then added to the ArrayList in PatientList. A final call to savePatientData rewrites the data files such that only valid data remain in them. This finishes the initial set-up.
The above is a summary of the aforementioned process, omitting some commands in the code that has to do with Visits, Prescriptions and UI classes and related methods.
PatientList
classaddPatient
- this method takes in the aforementioned variables through UI class and parses them. If they are all valid, a new
Patient
is created and added to the list of Patient
s in PatientList.findPatient
- this method takes in an ID
, iterates through the list of Patients and compares the ID
with the ID
of each of the
existing Patient
s in the list. If there is a match, the corresponding Patient
is returned. Else, returns null.retrievePatient
- this method is very similar to findPatient, but instead of returning the Patient found, it prints out the details
of the Patient
using the toString
method in the Patient
class.listPatients
- this method first checks if the list of Patient
s is non-empty. If not so, it prints a message that there are
no patients in the system currently and terminates.
Else, it iterates through the list of Patient
s and uses the toString
method in Patient
to print out the details of each Patient
.modifyPatientDetails
- this method takes in name
, birthDate
, gender
and ID
. It tries to find the patient with a matching ID
.
If the Patient
is not found, returns. Else, if the name is not an empty String
, replace the existing name
with the input name
.
Repeat for birthDate
and gender
.The VisitList
Component,
UI
class (as the VisitList
component interacts with user through the UI component, and makes use of its methods to print details)VisitList
classaddVisit
- This method allows user to add a visit to the VisitList
by specifying id
of patient, dateOfVisit
, timeOfVisit
and reason
. reason
is optional, and it can be left blank, and be modified later on via the editReason
method.editReason
- This method allows user to edit reason for an existing visit, by specifying index
of visit and reason
for visit. reason
must not be left blank here,
as it is equivalent to deleting a reason, for which a user should use the deleteReason
method instead.deleteReason
- This method allows user to delete reason for an existing visit, by specifying index
of the visit.viewAll
- This method iterates through the list of all visits, and prints each visit recordviewPatient
- This method iterates through the list of all visits, and prints the visit records that match the specified id
of patientviewVisit
- This method iterates through the list of all visits, and prints the visit record that matches the specified index
of the visitVisitList
is first called to add a new visit with the required details. This calls the constructor class of Visit
class to create an instance of Visit
ArrayList<Visit>
API: PrescriptionList.java
The PrescriptionList
component,
UI
class (because the PrescriptionList
component needs to interact with user through the UI
component)PrescriptionList
classadd
- This method allow user to add prescription into the list by specifying patientId
, medicine
, dosage
and
timeInterval
.viewAll
- This method iterates through the list of all prescriptions and print the details of prescriptions from
all patients.viewPatientPrescription
- This method iterates through the list of prescriptions and print the details of
prescriptions from the specified patientId
.viewActivePatientPrescription
- This method iterates through the list of prescriptions and print the details of
all active prescriptions with the specified patientId
edit
- This method allows user to edit the medicine
, dosage
or timeInterval
of the prescription of the
specified indexactivatePrescription
- This method allows user to set the prescription of specified index as active.deactivatePrescription
- This method allows user to set the prescription of specified index as inactive.loadPrescription
- This method assists the Storage
component to load prescriptions from the .txt storage.Prescription
classmedicine
- Stores the medicine nametimeInterval
- The time Interval the medicine is taken betweenpatientId
- The identification number of patientdosage
isActive
- Whether is the prescription currently active or notUsers are allowed to add new prescriptions. The action works as follows:
PrescriptionList
is called to add a new prescription with the given details, it calls the constructor of the
Prescription
class to create the Prescription
instance.prescriptionList
, then it is added to the list. And
ui
prints an acknowledgement message of what the new prescription has.ui
prints a message that the prescription is already existing, and print the details of the existing
prescription.There are 3 viewing methods that users can view a list of prescriptions in different filter. The filters are:
viewAll
viewPatientPrescription
viewActivePatientPrescription
Here is an example of how viewing with a patient prescription filter works:
viewPatientPrescription(ui, patientId)
is called, it first checks whether the list is empty and
has no prescription associated with the given patientId
. If either case is satisfied, ui
prints a no
matching prescription message and returns.prescriptionList
is iterated. Whenever a prescription
’s patientId
matches the given patientId
,
ui
prints the prescription
details.The other 2 filters work similarly with slightly different conditions checked.
Users are allowed to edit the medicine name, dosage and time interval of the prescription. However, it is only allowed if the updated prescription does not repeat other existing prescriptions. The action works as follow:
edit
function is called, it returns if the prescriptionNumber
is invalid.prescriptionNumber
is valid, prescriptionEdited
is retrieved from the ArrayList<>
, and newPrescription
object is created to represent the updated prescription.newPrescription
has a duplicate in the list, it returns with a prescription duplicated message from ui
.prescriptionEdited
is updated with a confirmation message from ui
.Users are allowed to activate or deactivate a prescription to track whether a prescription is currently being prescribed to patients or not. Both actions work in a similar manner. The action works as follows:
activate(ui, prescriptionNumber)
initiates an action in the PrescriptionList
, it converts the
prescriptionNumber
into the index in the array.null
, i.e invalid, the function is returned.prescriptionEdited
from the ArrayList<>
with the resolved index.prescriptionEdited
is set active.UI
prints an acknowledgement message of the most updated details of the prescription.The Storage
component,
The class diagram summarises the functions of the Storage
component at a glance.
The Storage
class has dependencies on the Scanner
(used to read files) and FileWriter
(used to write to files) classes.
It also has a composition relationship with 3 File
objects, that are used to store data.
Storage
classloadData
- This method initializes the data file objects that are to be read from, and calls the relevant methods to
load pre-existing data. Subsequently, it makes a call to relevant methods to rewrite the text files such that only valid
data remain in them.loadPatients
, loadVisits
, loadPrescriptions
- each of these methods read data from corresponding text files and
check if they are valid. If so, initialise a relevant Patient
, Visit
, or Prescription
and adds them to the relevant lists.savePatientData
, saveVisitData
, savePrescriptionData
- each of these methods take in the list of Patient
s, Visit
s,
or Prescription
s, processes them one by one and calls the relevant helper method to log its data into the appropriate data
file in a pre-specified format.In particular, we can observe exactly how, for instance, savePatientData
works.
FileWriter
object used to write data.logPatients
, passing in the list of Patient
s and the FileWriter
object created.Patient
s one by one, calling another method called logPatientIntoDataFile
,
passing the Patient
and FileWriter
objects.Patient
attribute by attribute in a pre-specified format.savePatientData
method.UI
classprintWelcomeMessage
- prints logo and welcome message to the user when opening “OneDoc”printObject
- prints object - patient/visit/prescription and their corresponding indexprintMessageAndObject
- prints object - patient/visit/prescription and their corresponding index, given message and object typeprintErrorMessage
- prints error to the userThe Parser
component,
The Parser
class has dependencies on the Pattern
(used to create regular expression patterns) and Matcher
(used to find regular expressions in Strings) classes.
Parser
classmainMenuParser
- This method interprets the initial user input to identify the correct submenu, and return that
state to the UIpatientParser
- Once within the Patient Submenu, this method is called from the UI
class on each user input.
The user input is then parsed into an add
, edit
, retrieve
, or viewall
command. If the input is incorrect, it
concludes as an error with a specific error message. Based on the command, the method will call the relevant method
from the PatientList
class with the parsed parameters. This method also checks for a call to help
, main
, or bye
at the start.visitParser
- Once within the Visit Submenu, this method is called from the UI
class on each user input
The user input is then parsed into an add
, edit
, deleteReason
, viewPatient
, viewVisit
, or viewAll
command.
If the input is incorrect, it concludes as an error with a specific error message. Based on the command, the method will
call the relevant method from the VisitList
class with the parsed parameters. This method also checks for a call to
help
, main
, or bye
at the start.prescriptionParser
- Once within the Prescription Submenu, this method is called from the UI
class on each user
input. The user input is then parsed into an add
, edit
, viewPatientPres
, viewActPatientPres
, activate
,
deactivate
, or viewAll
command. If the input is incorrect, it concludes as an error with a specific error message.
Based on the command, the method will call the relevant method from the PrescriptionList
class with the parsed
parameters. This method also checks for a call to help
, main
, or bye
at the start.In particular, we can observe exactly how, for instance, patientParser
works.
Matcher
objects used to identify if there is a correctly-formatted command
in the user’s input of type add
, edit
, or retrieve
. Since viewAll
is a single word command, there doesn’t need
to be a Matcher for it.viewAll
, and then checks for each Matcher
.Matcher
or viewAll
, it calls the relevant method from PatientList
PatientList
method performs the subsequent actions on Patient
/s, and returns the result.Our target user profile is a doctor in need of quick access to information about his/her patients, visits, and prescriptions. The doctor can quickly see all of the prescriptions that have been given, when a patient has visited, what their reasons were, etc. through this interface. The doctor can also quickly update this before, during, or after each visit and prescription to ensure that it stays up to date and easy-to-use.
Doctors tend to use sticky notes or quick pieces of paper to jot down notes such as prescriptions, reason for visit, etc. This platform allows a doctor to quickly reference basic information about a patient, find their previous prescriptions and visits, and look at the history to make a decision. A doctor can mark a prescription as active or inactive, allowing a consistent history. Moreover, the only part of these records that a doctor can delete is a reason, ensuring continuity of information.
Version | As a … | I want to … | So that I can … |
---|---|---|---|
v1.0 | user | exit the program | leave the program without damage |
v1.0 | doctor/user | add a new patient | have the patient record saved to the list of patients |
v1.0 | doctor/user | see all patients | see all the patients that are saved in the program i.e. are treated by me |
v1.0 | doctor/user | see all the information about a patient | refer to them to see all the patients that are being treated by me |
v1.0 | doctor/user | edit a patients record | change his record to reflect changes in the patient |
v1.0 | doctor/user | add a patient visitation record | refer later on for future care for the patient |
v1.0 | doctor/user | add a reason for visit to the existing record | have on record the reason the patient came for treatment for future use |
v1.0 | doctor/user | edit a patient visitation record | change the visit information in case error was entered |
v1.0 | doctor/user | add new prescription for a patient | add a new prescription for treatment for the patient |
v1.0 | doctor/user | edit a prescription | changes a prescription in case of a change in treatment or error in the current one |
v1.0 | doctor/user | view list of existing prescriptions for a patient | refer to them for future patient treatments |
v2.0 | doctor/user | view information for patient specific visit | refer to the visit in case i want to reflect on the visit |
v2.0 | doctor/user | view all patients visit | see the patient and where treated and are on record |
v2.0 | doctor/user | view list of all existing prescriptions for all of patients | see which prescription the patient was ever prescribed |
v2.0 | doctor/user | view list of all active prescriptions for all of patients | see which prescription the patient is currently taking |
v2.0 | doctor/user | change a prescription status to active | have on record that the patient is currently taking the prescription |
v2.0 | doctor/user | change a prescription status to inactive | have on record that the patient is currently not taking the prescription |
We utilize both ID and index reference in this tP, which may look confusing at first. Indices for visit and prescription are unique when created, and can be found when adding, editing, or viewing a visit or prescription. If you want to find a visit, you can search for a patient’s visits through viewPatient in the visit menu, and then use the given index of the visit you find to edit it. The same workflow applies for prescription.
Given below are instructions to test the app manually.
java -jar tp.jar
into the command line. The app should start running.bye
. The app should end with a greeting.1
. The patient menu should be shown.main
. The main menu should be shown again.2
. The visit menu should be shown.main
. The main menu should be shown again.3
. The prescription menu should be shown.bye
. The app should end with a greeting.To load sample data, please reference the following formats:
patient.txt
: Name | DOB | G | ID
Example: Jane Doe | 09-09-1978 | F | T1
visit.txt
: ID | Reason | Date | Time
Example: T1 | checkup | 08-11-2022 | 08:00
prescription.txt
: ID | Name | Dosage | Time Interval | Active Status (T or F)
Example: T1 | penicillin | 1 tablet | every 3 days | T
Please navigate to patient menu by inputting 1
in the main menu before testing the features below.
Please ensure that a patient with ID T1
doesn’t exist before testing this feature, and there is no patient with ID T2
.
add n/Johnny Depp g/M d/08-09-1965 i/T1
.add n/Elizabeth Swann g/F d/09-11-1975 i/T1
.add n/Will Turner g/M d/11-12-1972 i/T2
.viewall
.patient.txt
file should be listed.patient.txt
file manually if it is not empty.viewall
.retrieve i/T1
.retrieve i/T2
.retrieve T1
.edit i/T2 n/Will Turner
.edit i/T1 d/Will Turner
.help
find
Please follow the same format as Patient & Prescription for add
, edit
, viewall
, etc.
For viewPatient
and viewVisit
please read below.
Please ensure that a patient with ID T1
and T2
exists before testing this feature, and there is no patient with ID
321
. Please add visits for patient T1
and not for T2
.
viewPatient i/T1
T1
should be listed.viewPatient i/T2
viewPatient i/321
Please ensure that a patient with ID T1
exists before testing this feature, and there is no patient with ID
321
. Please add at least two visits for patient T1
, and there are no other visits in the system.
viewPatient i/T1
T1
should be listed.viewVisit x/1
viewVisit x/5
Please navigate to prescription menu by inputting 3
in the main menu before testing the features below.
Please ensure that a patient with ID T1
exists before testing this feature, and there is no patient with ID 321
.
add i/T1 n/Problaxan d/10 mg t/take 15 minutes after every meal
.add i/T1 n/Panadol d/5 mg t/Once a day
.add i/T1 n/Panadol d/5 mg t/Once a day
once again.add i/321 n/Panadol d/5 mg t/Once a day
.add i/T1 n/Panadol d/A pill t/Once a day
.add i/T1 n/Panadol d/5 mg t/Once a day
if the record does not exist. Skip this if it is already there.edit x/<index> n/Problaxan
with the index shown when adding the prescription. (Index is the number next to
Prescription #)Problaxan
without changing all other attributes.edit x/0 d/19 mg
.add i/T1 n/Panadol d/5 mg t/Once a day
if the record does not exist. Skip this if it is already there.add i/T1 n/Panadol d/10 mg t/Once a day
if the record does not exist. Skip this if it is already there.edit x/<index> d/5 mg
with the index shown when adding the prescription with 10 mg
dosage. (Index is the
number next to Prescription #)viewall
.prescription.txt
file should be listed.prescription.txt
file manually if it is not empty.viewall
.Please ensure that a patient with ID T1
and T2
exists before testing this feature, and there is no patient with ID
321
. Please add prescriptions for patient T1
and not for T2
.
viewPatientPres i/T1
T1
should be listed.viewPatientPres i/T2
viewPatientPres i/321
Please ensure that a patient with ID T1
and T2
exists before testing this feature, and there is no patient with ID
321
. Please add prescriptions for patient T1
and not for T2
.
viewActPatientPres i/T1
T1
should be listed.viewActPatientPres i/T2
viewActPatientPres i/321
viewall
and check the index of the last prescription in the system. Please add 1 if there isn’t any.activate x/<index>
, where the index is the one retrieved from Step 1.Active
.deactivate x/0
.help
find