diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fd8c44d086..81e70d052b 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -33,18 +33,3 @@ jobs: - name: Build and check with Gradle run: ./gradlew check - - name: Perform IO redirection test (*NIX) - if: runner.os == 'Linux' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (MacOS) - if: always() && runner.os == 'macOS' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (Windows) - if: always() && runner.os == 'Windows' - working-directory: ${{ github.workspace }}/text-ui-test - shell: cmd - run: runtest.bat \ No newline at end of file diff --git a/.gitignore b/.gitignore index f69985ef1f..6b2265a520 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ bin/ /text-ui-test/ACTUAL.txt text-ui-test/EXPECTED-UNIX.TXT + +#Saved data from the application +data \ No newline at end of file diff --git a/CommandClassUML.png b/CommandClassUML.png new file mode 100644 index 0000000000..5940dc89f1 Binary files /dev/null and b/CommandClassUML.png differ diff --git a/build.gradle b/build.gradle index b0c5528fb5..998565310b 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ repositories { } dependencies { + implementation 'junit:junit:4.13.1' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' } @@ -43,4 +44,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..de885a01b9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,11 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) + +Display | Name | Github Profile | Portfolio +--------|:---------------:|:-----------------------------------------:|:---------: +![sharif](photos/sharif.jpg) | Mohamed Sharif | [Github](https://github.com/shxr3f) | [Portfolio](team/shxr3f.md) +![tanweili](photos/tanweili.jpg) | Wei Li | [Github](https://github.com/tanweili) | [Portfolio](team/tanweili.md) +![tai](photos/taikahkiang.jpeg) | Tai | [Github](https://github.com/kktai1512) | [Portfolio](team/kktai1512.md) +![wraineflores](photos/wraineflores.jpg) | Wraine Flores | [Github](https://github.com/wraineflores) | [Portfolio](team/wraineflores.md) +![anvitharajaram](photos/anvitharajaram.jpg) | Anvitha Rajaram | [Github](https://github.com/Anvitha-r) | [Portfolio](team/Anvitha-r.md) + diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..ff7a396d8a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,38 +1,381 @@ # Developer Guide -## Acknowledgements +-------------------------------------------------------------------------------------------------------------------- +# Contents +* [Acknowledgements](#acknowledgements) +* [Getting Started For Beginners](#getting-started-for-beginners) +* [Design](#design) + * [Architecture](#architecture) + * [UI Component](#ui-component) + * [Manager Component](#manager-component) + * [Helper Classes](#helper-classes) + * [Command Component](#command) + * [Parser Component](#parser) + * [Storage Component](#storage) + * [Validator Component](#validator) + * [Asset Classes](#asset-classes) -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +* [Implementation](#implementation) + * [Design Considerations](#design-considerations) +* [Product Scope](#product-scope) + * [Target User](#target-user-profile) + * [Value Proposition](#value-proposition) + * [User Stories](#user-stories) + * [Use Cases](#use-cases) + * [Non-Functional Requirements](#non-functional-requirements) +* [Glossary](#glossary) +* [Appendix](#appendix) -## Design & implementation +-------------------------------------------------------------------------------------------------------------------- +## **Acknowledgements** -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +* Design and Structure of Developer Guide referenced from the +[AB3-Developer Guide](http://se-education.org/addressbook-level3/DeveloperGuide.html). +-------------------------------------------------------------------------------------------------------------------- +## **Getting Started for Beginners** +Refer to the [_User Guide_](UserGuide.md). + +-------------------------------------------------------------------------------------------------------------------- +## **Design** + +### Architecture + +![Architecture Diagram](diagrams/OverallArch.png) + +The ***Architecture Diagram*** given above explains the high-level design ***HalpMi***. + +Given below is a quick overview of main components and how they interact with each other. + +#### **Main components of the architecture** + +**`Duke`** has single method called `main` which is called upon launch. This initialises a new instance of a `Manager` class, and calls the `runLoop()` +method belonging to the Manager object. + +[**`Assets`**](#asset-classes): Refers to a collection of classes that hold all the necessary data given by the User in +current and past usages. + +The rest of the App consists of these components. + +* [**`Manager`**](#manager-component): The Brain. +* [**`Helper`**](#helper-classes): A collection of core classes that aid with the Logical Operations performed by HalpMi. + * [**`Command`**](#command): Contains the changes or updates to be made. + * [**`UI`**](#ui-component): The UI of the App. + * [**`Parser`**](#parser): Breaks down user input into parameters accepted by the app and creates a Command Object. + * [**`Validator`**](): Checks if the input provided by the User is Valid. + * [**`Storage`**](#storage): Reads data from data files and writes data to data files, also stores in app memory. + +The Sequence Diagram below showcases the general Logic and Flow of the program from Launch till Exit. + +![Sequence Diagram](diagrams/SequenceDiagram.png) + +### UI component + +![UIClassUML](diagrams/UIClassUML.png) + +How the UI class works: +* Based on the architecture sequence diagram, `Manager` class calls readCommand method in `UI` class and returns the UserInput. +* Afterwards, the `Manager` class calls readParameters method in `UI` class and returns another UserInput. +* Finally, the `Manager` class calls print method in `UI` class which in turn calls `Status` enum and returns the constant. + +### Manager component + +![ManagerUML](diagrams/ManagerClass.png) +
+How the Manager class works: +* When `Duke` class instantiates a `Manager` object and calls runLoop method, the program will execute a while loop. +* In the while loop, there is a switch condition. +* Based on the parameter provided to the switch, it will call the respective methods in UI, Parser & Command classes. +* The while loop only halts when isTerminated boolean becomes true. Then, the programme exits. + +### Helper Classes + +#### `Command` + +![CommandUML](diagrams/CommandClassUML.png) + +How the Command class works: +* Based on the architecture sequence diagram, the `Parser` class calls the `Validator` class to check if the inputs are valid. +* If it is valid, the `Command` subclass executes its method. +* The subclass is based on whether the user wants to access either the `Doctor`, `Patient`, `Medicine` or `Appointment` asset list class. +* The input parameters determine which of the `Command` subclass is used. +* These input parameters are actions which can be `Add`, `Delete`, `View`, `Edit`, `Find`, `Check`, `Update` or `Clear` + +#### `Validator` + +![ValidatorClassUML](diagrams/ValidatorClassUML.png) + +The validator has a series of methods to ensure that the parameters entered are correct. It throws a `HalpmiException` if the parameters and/or number of parameters +entered are invalid. +For example, validateAddPatient validates the parameter of `add patient` command, ensuring each parameter is in correct +format. Please refer to the below sequence diagram for a clearer understanding. + +![ValidatorUML](diagrams/ValidatorUML.png) + + +#### `Parser` + +![ParserClassUML](diagrams/ParserClassUML.png) + +The parser parses the description of the command. It calls the validator class to validate the parameters, and then returns a command if the validation is successful. + +![ParserUML](diagrams/ParserUML.png) + + +#### `HalpmiException` +![ExceptionClassUML](diagrams/ExceptionClassUML.png)
+There are three types of HalpmiExceptions, namely, `UserInputErrorException` (usually thrown by Validator), `NotFoundException` (thrown by `find` command) and `DuplicateEntryException` (thrown when trying to add already existing data). + +The exception message will be printed out by the `Ui` class somewhere in the program. + +#### `Storage` + +![StorageClassUML](diagrams/StorageClassUML.png) + +The Storage class holds 4 different Lists found in the Assets collection as seen in the Class Diagram shown above. Any edits made +to these Lists must be made by accessing them from the Storage object. The Storage class also has a genericLoadFunction for all types of Asset, +namely Patient, Doctor, Medicine and Appointment. These methods read in the respective text files to load existing information +into their respective lists. The Storage class has 5 save methods that save the information found in the 4 Lists into text files +in the CSV format. The Directory of these text files is found in the DIR String variable, the PATH for each of the 4 text files +can be found in the PATH_MED, PATH_PAT, PATH_DOC, PATH_APP, PATH_APT_MEDS String variables respectively. + +#### Corrupted files +A preliminary check for corrupted files will be done when HalpMi starts. The validator function will be invoked to ensure the the input lines are correct. Else, the corrupted files will be moved into another separate text file named `[datatype]_corrupted.txt`. +### Asset classes + +#### `Appointment` + +![AppointmentUML](diagrams/AppointmentUML.png) + +The Appointment class holds several attributes that are exposed via getter methods. To instantiate the class, all the +attributes must be given to the constructor method. + +#### `Appointment List` + +![AppointmentListUML](diagrams/AppointmentListUML.png) + +The AppointmentList class contains a private list of Appointments and another list for searching. It has several +public methods that allows the user to get information regarding the list, view the list as well as search for specific +Appointment by selected criteria. + +#### `Medicine` + +![MedicineUML](diagrams/MedicineUML.png) + +The Medicine class holds several attributes that are exposed via getter methods. To instantiate the class, all the +attributes must be given to the constructor method. There is a method to edit the attribute data that can be called +whenever user types in the correct command. + +#### `Medicine List` + +![MedicineListUML](diagrams/MedicineListUML.png) + +The MedicineList class contains private lists of Medicine, expired Medicine and one list for searching. It has several +public methods that allows the user to get information regarding the list, view the list as well as search for specific +Medicine by selected criteria. + +##### `Patient` + +![PatientUML](diagrams/Patient.png) + +The Patient class holds several attributes that are exposed via getter methods. To instantiate the class, all the +attributes must be given to the constructor method. There is a method to edit the attribute data that can be called +whenever user types in the correct command. + +#### `Patient List` + +![PatientListUML](diagrams/PatientList.png) + +The PatientList class contains private lists of Patients and one list for searching. It has several +public methods that allows the user to get information regarding the list, view the list as well as search for specific +Patients by selected criteria. + +#### `Doctor` + +![DoctorUML](diagrams/Doctor.png) + +The Doctor class holds several attributes that are exposed via getter methods. To instantiate the class, all the +attributes must be given to the constructor method. There is a method to edit the attribute data that can be called +whenever user types in the correct command. + +#### `Doctor List` + +![DoctorListUML](diagrams/DoctorList.png) + +The DoctorList class contains private lists of Doctors and one list for searching. It has several +public methods that allows the user to get information regarding the list, view the list as well as search for specific +Doctors by selected criteria. + +-------------------------------------------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------------------------------------------- + +## **Implementation** + +This section describes some noteworthy details on how certain features are implemented. + +### View appointments with selected criteria +This feature is a method within `AppointmentList`. `AppointmentList` contains an arraylist +of `Appointment` as a private element. `AppointmentList` methods invoked interacts with this +list, possibly making changes in the process. + +Some methods included in the `AppointmentList` are: +* `AppointmentList#add` -- Appends a new `Appointment` to the list. +* `AppointmentList#remove` -- Removes an entry from the list by appointment id. +* `AppointmentList#edit` -- Edits a existing entry from the list by. +* `AppointmentList#view` -- Text display of all or selected appointments in the list. +* `AppointmentList#find` -- Find selected appointments using the criteria given. + +The methods are exposed in the `Manager#runLoop` method where user input is parsed. A `ViewAppointmentCommand` will +be returned if the user input passes the validation by `Validator`. Else, a `HalpmiException` will be thrown +indicating missing parameters. + +Below is a simplified sequence diagram showing the key class interactions specifically when the User calls the +`view appointment` command appropriately. + +![ViewAppointmentImplementationUML](diagrams/ViewAppointmentImplementationUML.png) +
+The user first types in the command for view appointment correctly. Then, Manager will call UI methods to +parse and identify the command string and parameters string before parsing within Parser. If parameters are absent, +then a ViewAppointmentCommand is returned. Else, a FindAppointmentCommand with the parameters is returned. The Command +is executed which displays the appointments to the User. The command allows calls to get a Status variable to be +returned to the Manager. + + +### Dispense Medicine to Patient + +This feature allows the user to generate the Batch IDs of the medicine that he/she wishes to dispense to a patient +on his day of appointment. The logic behind this feature is that, in a clinic there will be many batches of +the same medication, each batch differing by the expiry date and the quantity left. This feature allows the user to +simply give the list of Medicine Names and the Quantity of each medicine required. HalpMi will figure out the best way +to dispense each type of medicine such that medicine that expire earlier are dispensed first before dispensing later ones. +HalpMi also generates the list of Medicine that is not available in the inventory if the medicines listed by the user +does not have the necessary quantity. Below is a sequence diagram showcasing how this functionality is achieved. + +This would be the basic flow of application logic when the user gives an input +`dispense medicine /info S1234567A,Paracetamol,10`. Given that both the Patient has an appointment today and the medicine +requested is in stock. + +![DispenseMed](diagrams/DispenseMed.png) + +--------------------------------------------------------------------------------------------------------------- ## Product scope -### Target user profile -{Describe the target user profile} +### Target user profile: + +* administrator in clinic(s) +* prefer desktop apps over other types +* can type fast +* prefers typing to mouse interactions +* is reasonably comfortable using CLI apps + +### Value proposition: + +Manage core clinic related data faster than using mouse or GUI. +Ensure each data type conforms to certain standards with in-built validations. -### Value proposition +### User stories -{Describe the value proposition: what problem does it solve?} +Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -## User Stories +| Version | Priority | As a ... | I want to ... | So that I can ... | +|---------|----------|--------------------------------------------|----------------------------------------------|------------------------------------------------------------------------| +| 1.0 | `***` | new user | view the user guide | to learn how to use the system | +| 1.0 | `***` | user | use the help function | to get help quickly within the application | +| 1.0 | `***` | user | add patient | keep track of the patients | +| 1.0 | `***` | user | add doctor | keep track of the doctors | +| 1.0 | `***` | user | add medicine | keep track of the medicines| +| 1.0 | `***` | user | view patient | see all patients in the clinic | +| 1.0 | `***` | user | view doctor | see all doctors in the clinic | +| 1.0 | `***` | user | view medicine | see all medicines in the clinic | +| 1.0 | `**` | user | delete patient | remove data of patients that are not needed anymore | +| 1.0 | `**` | user | delete doctor | remove data of doctors that are not needed anymore | +| 1.0 | `**` | user | delete medicine | remove data of medicines that are not needed anymore | +| 1.0 | `*` | user | save data of the application | all changes I made in one session is saved | +| 1.0 | `*` | user | exit the app | work on other issues whenever appropriate | +| 2.0 | `***` | user | add appointment | keep track of appointments | +| 2.0 | `***` | user | delete appointment | remove appointments that are not needed anymore | +| 2.0 | `***` | user | view appointment | see all appointment in the clinic | +| 2.0 | `**` | user | edit appointment | update changes to appointments | +| 2.0 | `**` | user | edit patient | update changes of patients | +| 2.0 | `**` | user | edit doctor | update changes of doctors | +| 2.0 | `**` | user | edit medicine | update changes of medicines | +| 2.0 | `**` | user | find patient | filter out patients by specific criteria | +| 2.0 | `**` | user | find doctor | filter out doctors by specific criteria | +| 2.0 | `**` | user | find medicine | filter out medicines by specific criteria | +| 2.0 | `**` | user | find appointment | filter out appointments by specific criteria | +| 2.1 | `*` | user | update medicines in inventory | find medicines that are expired or have ran out | +| 2.1 | `*` | user | clear expired medicines | remove expired/ran out medicines from the inventory | +| 2.1 | `*` | user | generate the batch id of medicines to dispense | dispense medicine that expire earlier first | +| 2.1 | `*` | user | schedule an appointment | schedule an appointment with a doctor that is free | -|Version| As a ... | I want to ... | So that I can ...| -|--------|----------|---------------|------------------| -|v1.0|new user|see usage instructions|refer to them when I forget how to use the application| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +### Use cases -## Non-Functional Requirements +### Non-Functional Requirements +Device Environment: +* Must have Java 11 or higher installed in OS +* 32-bit or 64-bit environment +* Command Line Interface supported -{Give non-functional requirements} + Performance of app: +* Function offline, without the need for internet access +* Quick to launch and use +* No noticeable lag or delay in performance when running +* Intuitive and seamless for new users +* Ability to export the data into a txt file to load on another OS + + Reliability of app: +* Data files should be updated constantly and accurately, with no data loss +* Data records should be retrievable and readable +* Text inputs should produce similar results if utilised multiple times +* Program should run without any forced-close error due to bugs + +-------------------------------------------------------------------------------------------------------------------- ## Glossary -* *glossary item* - Definition +* *FUllNAME* - Standard form for full name of patients and doctors is a String value with no spaces +* *NRIC* - Standard form for nric of patients and doctors is a String value with no spaces +* *AGE* - Standard form for age is an int value more than 0 +* *GENDER* - Standard form for gender of patients and doctors is a char value of "M" or "F" +* *ADDRESS* - Standard form for address is a String value with no spaces +* *DOB* - Standard form for date-of-birth is a String value with no spaces +* *SPECIALIZATION* - Standard form for specialization of doctors is String value with no spaces +* *MEDICINEID* - Standard form for medicine id is a String value with no spaces +* *MEDICINENAME* - Standard form for medicine name is a String value with no spaces +* *DOSAGE* - Standard form for dosage of medicine is an int value, standard unit milligrams +* *EXPIRY* - Standard form for expiry of medicine is a String value with no spaces +* *SIDEEFFECTS* - Standard form for side effects of medicine is a String value with no spaces +* *QUANTITY* - Standard form for quantity of medicine is an int value +* *APPOINTMENTID* - Standard form for appointment id is a String value with no spaces +* *APPOINTMENTDETAILS* - Standard form for appointment details is a String value + + +-------------------------------------------------------------------------------------------------------------------- + +## **Appendix** -## Instructions for manual testing +For manual testing, developers can follow the instructions listed out in the [UserGuide](UserGuide.md) +* Detailed input and output examples are displayed for cross checking. + Alternatively, they can also follow the following steps to test out the respective commands, + upon downloading the jar file, while adhering to the specified restrictions in Glossary: -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} +1. `add doctor /info [nric],[name],[age],[gender],[address],[DOB],[Specialisation]` + * Adds a new doctor with the specified parameters into the system +2. `add patient /info [nric],[name],[age],[gender],[address],[DOB]` + * Adds a new patient with the specified parameters into the system +3. `add medicine /info [name],[dosage],[expiry date],[side effects],[quantity]` + * Adds a new medicine with the specified parameters into the system +4. `view doctor` or `view doctor /info [criteria],[input]` + * View records of all doctors or specific doctors fulfilling the criteria +5. `view patient` or `view patient /info [criteria],[input]` + * View records of all patients or specific patients fulfilling the criteria +6. `view medicine` or `view medicine /info [criteria],[input]` + * View records of all medicines or specific medicines fulfilling the criteria +7. `delete doctor /info [nric]` + * deletes the record of the doctor with the specified nric +8. `delete patient /info [nric]` + * deletes the record of the patient with the specified nric +9. `delete medicine /info [Batch ID]` + * deletes the record of the medicine with the specified id diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..d94f769339 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,10 @@ -# Duke - -{Give product intro here} - -Useful links: +# HALPMI +## Introduction +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors. Users are also able to track stocks of medications. +## Links +You can use the links listed below to view the relevant documentations for this Application and Project. * [User Guide](UserGuide.md) * [Developer Guide](DeveloperGuide.md) * [About Us](AboutUs.md) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..636115007b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,42 +1,540 @@ # User Guide +----------------------------------------------- + +## Contents +* [Introduction](#introduction) + * [Purpose](#purpose) + * [How to read the Guide](#how-to-read-the-guide) +* [Quick Start](#quick-start) + * [Setting up Java](#setting-up-java) + * [Starting up HALPMI](#starting-up-halpmi) +* [Features](#features) + * [Adding](#adding-add) + * [Viewing](#viewing-view) + * [Deleting](#deleting-delete) + * [Editing](#editing-edit) + * [Finding](#finding-find) + * [Medicine Inventory Features](#features-involving-medicine-inventory) + * [Saving](#saving) + * [Saved Data](#saving) + * [Corrupt Files](#corrupt-files) +* [Future Versions](#future-versions) +* [Command Summary](#command-summary) + +----------------------------------------------- + ## Introduction -{Give a product intro} +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors. Users are also able to track stocks of medications. + +### Purpose +The purpose of this User Guide is to get new users of HALPMI to get started with the application and learn the features +that it entails. This User Guide can also be referred to as and when needed when unclear about certain features and commands. + +Persons with greater technical knowledge can refer to the [Developer Guide](DeveloperGuide.md) for in-depth explanations on the +workings behind HALPMI. + +### How to read the Guide? +The User Guide is structured in a way that it is straight-forward and has a logical flow. Hence it should be easy for any User +like you to get started with HALPMI immediately. + +Before reading, it is noteworthy to understand some formats and keywords used in this Guide for better clarity. +* Command - Command refers to the text input that you will be providing on the CLI as and when prompted by HALPMI. +* `Word` - Certain words or sentences in this Guide are often found in this format. These refer to commands that you as a User +can use in the CLI application. +* `[Word]` - Certain words that are found inside brackets refer to compulsory parameters you have to include following the +command. + +----------------------------------------------- ## Quick Start -{Give steps to get started quickly} +### Setting Up Java -1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +Firstly, you need to have Java 11 or above installed in your computer. If you are not sure on how to check if you have +Java 11 installed on your computer, you can refer to [Check Java](https://www.howtogeek.com/717330/how-to-check-your-java-version-on-windows-10/). -## Features +If you do not have Java already installed... +1. You can either download the Java Runtime Environment (JRE) from [Java](https://www.java.com/en/download/manual.jsp). +2. Or you can download the Java Development Kit (JDK) from [Oracle](https://www.oracle.com/java/technologies/downloads/). -{Give detailed description of each feature} +Once you are sure that you have Java installed, you can download the latest version of HALPMI from the releases. -### Adding a todo: `todo` -Adds a new item to the list of todo items. +### Starting up HALPMI +You can launch HALPMI directly from your Command Prompt/Terminal. Change directory to the location where you have saved the +JAR file you have downloaded from our releases. Following which you can type in `java -jar Halpmi.jar` in the command prompt to launch HALPMI. +To learn more about [Command Prompt](https://www.makeuseof.com/tag/a-beginners-guide-to-the-windows-command-line/) +, [Linux Terminal](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) and [Mac Terminal](https://macpaw.com/how-to/use-terminal-on-mac) +please head to the respective help links. -Format: `todo n/TODO_NAME d/DEADLINE` +If you are not ready to handle the intricacies of the Command Prompt, you can use the `.bat` file located in our repository +to launch HALPMI as well. However do note that you will have to change the PATH name included on the bat file to the PATH name +at which Halpmi.jar is located. -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. +![startHalpmi](photos/startHalpmi.jpg) + -Example of usage: +----------------------------------------------- -`todo n/Write the rest of the User Guide d/next week` +## Features +> :warning: Please take note that all the parameters for all the commands will be auto-capitalised. However, if you are confused, please just use it according to the example given below. -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +### Adding: `add` +Adds a new entry into the app. This entry can be either a doctor, patient, medicine or appointment. -## FAQ +#### ADD DOCTOR -**Q**: How do I transfer my data to another computer? +To add a new doctor into your application you can use the `add doctor` command when prompted by HALPMI for your input. +To add a doctor there are some parameters that you would have to provide: +1. NRIC +2. Name +3. Age +4. Gender +5. Address +6. Date Of Birth (DOB) +7. Specialisation -**A**: {your answer here} +You will have to follow the formatting given below when calling the command. -## Command Summary +Format: `add doctor /info [nric], [name], [age], [gender], [address], [DOB], [Specialisation]` + +Example: `add doctor /info S7654321A, John Doe, 22, M, 10 Baker Street, 1999-12-31, Urinology` + +![addDoctor](photos/addDoctor.jpg) + +#### ADD PATIENT + +To add a new patient into your application you can use the `add patient` command when prompted by HALPMI for your input. +To add a patient there are some parameters that you would have to provide: +1. NRIC +2. Name +3. Age +4. Gender +5. Address +6. Date Of Birth (DOB) +7. Date Of Registration (DOR) + +You will have to follow the formatting given below when calling the command. + +Format: `add patient /info [nric], [name], [age], [gender], [address], [DOB], [DOR]` + +Example: `add patient /info S1234567A, John Doe, 22, M, 10 Baker Street, 1999-12-31, 2021-02-15` + +![addPatient](photos/addPatient.jpg) + +#### ADD MEDICINE + +To add a new medicine into your application you can use the `add medicine` command when prompted by HALPMI for your input. +To add a medicine there are some parameters that you would have to provide: +1. Medicine ID +1. Medicine Name +2. Dosage +3. Expiry Date +4. Side Effects (any string) +5. Quantity + +You will have to follow the formatting given below when calling the command. + +Format: `add medicine /info [batch id], [name], [dosage], [expiry date], [side effects], [quantity]` + +Example: `add medicine /info A123, Paracetamol, 500, 2023-06-11, drowsy, 10` + +![addMedicine](photos/addMedicine.jpg) + +#### ADD APPOINTMENT + +To add a new appointment into your application you can use the `add appointment` command when prompted by HALPMI for your input. +To add an appointment there are some parameters that you would have to provide: +1. Patient NRIC +2. Doctor NRIC +3. Appointment Date +4. Appointment Details + +You will have to follow the formatting given below when calling the command. + +Format: `add appointment /info [patient nric], [doctor nric], [appointment date], [appointment details]` + +Example: `add appointment /info S1234567A, S7654321A, 2022-10-15, Regular knee checkup` + +![addAppointment](photos/addAppointment.jpg) + +### Viewing: `view` +Allows user to view existing records of doctors, patients, medicine or appointment. + +#### VIEW DOCTOR + +To view the records of all doctors in the application, you can simply call `view doctor` without any additional +parameters. + +Format: `view doctor` + +Examples: `view doctor` + +![viewDoctor](photos/viewDoctor.jpg) + +#### VIEW PATIENT + +To view the records of all patients in the application, you can simply call `view patient` without any additional +parameters. + +Format: `view patient` + +Example: `view patient` + +![viewPatient](photos/viewPatient.jpg) + +#### VIEW MEDICINE + +To view the records of all medicines in the application, you can simply call `view medicine` without any additional +parameters. + +Format: `view medicine` + +Example: `view medicine` + +![viewMedicine](photos/viewMedicine.jpg) + +#### VIEW APPOINTMENT + +To view the records of all appointments in the application, you can simply call `view appointment` without any +additional parameters. + +Format: `view appointment` + +Example: `view appointment` + +![viewDAppointment](photos/viewAppointment.jpg) + + +### Deleting: `delete` +Allows user to delete existing records of doctors, patients, medicine or appointment. + +> :warning:Do note that all delete commands are irreversible. + +#### DELETE DOCTOR + +To delete an existing doctor in the application, you can use the `delete doctor` command. This command requires an +additional parameter which is the NRIC of the doctor. + +Format: `delete doctor /info [nric]` + +Example: `delete doctor /info S7654321A` +![deleteDoctor](photos/deleteDoctor.jpg) + +#### DELETE PATIENT + +To delete an existing patient in the application, you can use the `delete patient` command. This command requires an +additional parameter which is the NRIC of the patient. + +Format: `delete patient /info [nric]` + +Example: `delete patient /info S1234567A` + +![deletePatient](photos/deletePatient.jpg) + +#### DELETE MEDICINE + +To delete an existing medicine in the application, you can use the `delete medicine` command. This command requires an +additional parameter which is the batch id of the medicine. + +Format: `delete medicine /info [batch id]` + +Example: `delete medicine /info A123` + +![deleteMedicine](photos/deleteMedicine.jpg) + +#### DELETE APPOINTMENT + +To delete an existing appointment in the application, you can use the `delete appointment` command. +This command requires an additional parameter which is the appointment id of the medicine. + +Format: `delete appointment /info [appointment id]` + +Example: `delete appointment /info 12356710156543` + +![deleteAppointment](photos/deleteAppointment.jpg) + +### Editing: `edit` +Allows user to edit existing records of doctors, patients, medicine or appointment. Do note that successful edit +commands will overwrite the previous data recorded. +#### EDIT DOCTOR -{Give a 'cheat sheet' of commands here} +To edit an existing doctor in your application you can use the `edit doctor` command when prompted by HALPMI for your input. +To edit a doctor there are some parameters that you would have to provide: +1. NRIC (Must be already in the list) +2. Name +3. Age +4. Gender +5. Address +6. Date Of Birth (DOB) +7. Specialisation + +You will have to follow the formatting given below when calling the command. + +Format: `edit doctor /info [nric], [name], [age], [gender], [address], [DOB], [Specialisation]` + +Example: `edit doctor /info S7654321A, John Doe, 22, M, 12 Baker Street, 1999-12-31, Urinology` + +![editDoctor](photos/editDoctor.jpg) + +#### EDIT PATIENT + +To edit an existing patient in your application you can use the `edit patient` command when prompted by HALPMI for your input. +To edit a patient there are some parameters that you would have to provide: +1. NRIC (Must be already in the list) +2. Name +3. Age +4. Gender +5. Address +6. Date Of Birth (DOB) +7. Date Of Registration (DOR) + +You will have to follow the formatting given below when calling the command. + +Format: `edit patient /info [nric], [name], [age], [gender], [address], [DOB], [DOR]` + +Example: `edit patient /info S1234567A, Jammie Doe, 22, F, 14 Baker Street, 1999-12-31, 2021-02-15` + +![editPatient](photos/editPatient.jpg) + +#### EDIT MEDICINE + +To edit an existing medicine in your application you can use the `edit medicine` command when prompted by HALPMI for your input. +To edit a medicine there are some parameters that you would have to provide: +1. Batch ID (Must be already on the list) +1. Medicine Name +2. Dosage +3. Expiry Date +4. Side Effects +5. Quantity + +You will have to follow the formatting given below when calling the command. + +Format: `edit medicine /info [batch id], [name], [dosage], [expiry date], [side effects], [quantity]` + +Example: `edit medicine /info A123, Paracetamol, 1000, 2023-06-11, drowsy, 20` + +![editmedicine](photos/editmedicine.jpg) + + +### Finding: `find` +Allows user to find existing records of doctors, patients and medicine. + +#### FIND DOCTOR + +To find an existing doctor in the application, you can use the `find doctor` command. This command requires an +additional parameter which can be any of the parameters of doctor. +To find a doctor you would have to provide one of these parameters: +1. NRIC: `nric` +2. Name: `name` +3. Age: `age` +4. Gender: `gender` +5. Address: `address` +6. Date Of Birth (DOB): `dob` +7. Specialisation: `specialization` + +Format: `find doctor /info [parameter], [keyword to find]` + +Example 1: `find doctor /info name, John`
+Example 2: `find doctor /info nric, S7654321A`
+Example 3: `find doctor /info age, 22`
+Example 4: `find doctor /info gender, M`
+Example 5: `find doctor /info address, 10 BAKER STREET`
+Example 6: `find doctor /info dob, 1999-12-31`
+Example 7: `find doctor /info specialization, Urinology` + +![findDoctor](photos/findDoctor.jpg) + +#### FIND PATIENT + +To find an existing patient in the application, you can use the `find patient` command. This command requires an +additional parameter which can be any of the parameters of patient. +To find a patient you would have to provide one of these parameters using the given keywords: + +1. NRIC: `nric` +2. Name: `name` +3. Age: `age` +4. Gender: `gender` +5. Address: `address` +6. Date Of Birth (DOB): `dob` +7. Registration Date: `registrationdate` + +Format: `find patient /info [parameter], [keyword to find]` + +Example 1: `find patient /info name, John Doe`
+Example 2: `find patient /info nric, S1234567A`
+Example 3: `find patient /info age, 22`
+Example 4: `find patient /info gender, M`
+Example 5: `find patient /info address, 10 BAKER STREET`
+Example 6: `find patient /info dob, 1999-12-31`
+Example 7: `find patient /info registrationdate, 2021-02-15`
+ +![findPatient](photos/findPatient.jpg) + +#### FIND MEDICINE + +To find an existing medicine in the application, you can use the `find medicine` command. This command requires an +additional parameter which can be any of the parameters of medicine. +To find a medicine you would have to provide one of these parameters using the given keywords: + +1. Medicine Name: `name` +2. Dosage: `dosage` +3. Expiry Date: `expiry` +4. Side Effects: `sideeffects` +5. Quantity: `quantity` + +Format: `find medicine /info [parameter], [keyword to find]` + +Example 1: `find medicine /info name, Paracetamol`
+Example 2: `find medicine /info id, A123`
+Example 3: `find medicine /info dosage, 500`
+Example 4: `find medicine /info expiry, 2023-06-11`
+Example 5: `find medicine /info sideeffects, DROWSY`
+Example 6: `find medicine /info quantity, 10` + +![findMedicine](photos/findMedicine.jpg) + +#### FIND APPOINTMENT + +To find an existing appointment in the application, you can use the `find appointment` command. This command requires an +additional parameter which can be any of the parameters of appointment. +To find an appointment you would have to provide one of these parameters using the given keywords: + +1. Appointment Id: `id` +2. Patient nric: `patient nric` +3. Patient name: `patient name` +4. Doctor nric: `doctor nric` +5. Doctor name: `doctor name` +6. Appointment Date: `date` + + +Format: `find appointment /info [parameter], [keyword to find]` + +Example 1: `find appointment /info id, 12356710156543`
+Example 2: `find appointment /info patient nric, S1234567A`
+Example 3: `find appointment /info patient name, Doe`
+Example 4: `find appointment /info doctor nric, S7654321A`
+Example 5: `find appointment /info doctor name, John`
+Example 6: `find appointment /info date, 2022-10-15` + + +![findAppointment](photos/findAppointment.jpg) + +### Features involving Medicine Inventory + +#### Retrieving List of Expired/Run Out Medicine in the inventory + +To retrieve list of expired medicine or depleted medicine in your inventory, you can simply call the `update medicines` command. This command +requires no additional parameter. +> :warning: DO NOTE THAT THIS LIST WILL BE CLEARED AND THE INFORMATION WITHIN WILL BE DESTROYED +UPON EXIT OF THE APP + +Format: `update medicines` + +Example: `update medicines` + +![updateMedicine](photos/updateMedicine.jpg) + +#### Clearing List of Expired Medicine + +If you choose to clear the list of expired medicine manually you can use the `clear old medicines` command. This commmand +requires no additional parameter. + +Format: `clear old medicines` + +Example: `clear old medicines` + +![clearMedicine](photos/clearMedicine.jpg) + +#### Dispensing Medicine to Patients who have appointments on that day + +You can use this feature to generate the Batch IDs of the medicines that are required to be dispensed to the patient on +his appointment day. If certain medicines you wish to dispense are not in stock, HalpMi will show you a list of medicine +you are missing in the inventory. If all the required medicines are present in the inventory, HalpMi will show the list +of Medicines you have to dispense along with the Batch ID so that you can clear batches with earlier expiry dates first. + +You can use this feature using the `dispense medicine` command. This command takes in the NRIC of an existing patient +followed by a list of medicine you would like to dispense. + +Format: `dispense medicine /info [NRIC],[Medicine Name],[Quantity]` + +Example: `dispense medicine /info S1234567A,Paracetamol,10,Aspirin,20` + +You need to give at least 1 medicine to dispense. + +![dispenseMedicine](photos/dispenseMedicine.jpg) + +### Saving + +#### Saved Data + +When you start HalpMi for the first time, the following directory and files would be created: +``` +data/ // Primary resource directory for HalpMi + ├── doctor.txt // Text file containing doctor list + ├── patient.txt // Text file containing patient list + ├── medicine.txt // Text file containing medcine list + ├── appointment.txt // Text file containing appointment list + ├── doctor_date.txt // Text file containing date of appointment for doctors + ├── patient_date.txt // Text file containing date of appointment for patients + └── appointment_meds.txt // Text file containing dispensed medicine list required for appointments + +``` +Do note that the directory (and by extension, the files) will be created in your terminal's +**current working directory**. Thus, it is highly recommended for you to create a new directory +with the HalpMi JAR file inside it, and run the application from the directory. + +When you launch HalpMi in subsequent sessions, please ensure that you run it from the same directory +that you did when starting HalpMi for the first time. + +#### Corrupt Files +If the files are corrupted, you will be prompted by HalpMi and the corrupted lines will be moved into a separate text file, with the following name. +``` +data/ // Corrupted files + ├── doctor_corrupted.txt // Text file containing doctor list + ├── patient_corrupted.txt // Text file containing patient list + ├── medicine_corrupted.txt // Text file containing medicine list + └── appointment_corrupted.txt // Text file containing appointment list +``` + +----------------------------------------------- + +## Future Versions + +#### Storage +**File encryption** -> Files will be encrypted in the future. More checks for corurpted files will also be included. Current corrupted file check is a basic preliminary check. + +#### Appointment +**Assign Appointment** -> Upon adding Patient Nric and Doctor Nric, an Appointment Date would be automatically assigned based on the nearest date when the Doctor is free. Current add appointment features requires manual addition of Appointment date. + +## Command Summary -* Add todo `todo n/TODO_NAME d/DEADLINE` +| Action | Format, Examples | +|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `add doctor` | `add doctor /info [nric],[name],[age],[gender],[address],[DOB],[Specialisation]`
e.g. `add doctor /info S1234567A, John Doe, 22, M, 10 Baker Street, 1999-12-31, Urinology` | +| `add patient` | `add patient /info [nric],[name],[age],[gender],[address],[DOB],[DOR]`
e.g. `add patient /info S1234567A, John Doe, 22, M, 10 Baker Street, 1999-12-31, 2021-02-15` | +| `add medicine` | `add medicine /info [batch id], [name], [dosage], [expiry date], [side effects], [quantity]`
e.g. `add medicine /info A123, Paracetamol, 500, 2023-06-11, drowsy, 10` | +| `add appointment` | `add appointment /info [patient nric], [doctor nric], [appointment date], [appointment details]`
e.g. `add appointment /info S1234567A, S7654321A, 2022-10-15, Regular knee checkup` | +| `view doctor` | `view doctor`
e.g. `view doctor` | +| `view patient` | `view patient`
e.g. `view patient` | +| `view medicine` | `view medicine`
e.g. `view medicine` | +| `view appointment` | `view appointment` or `view appointment /info [parameter], [keyword to find]`
e.g. `view appointment /info id, 12356710156543` | +| `delete doctor` | `delete doctor /info [nric]`
e.g. `delete doctor /info S1234567A` | +| `delete patient` | `delete patient /info [nric]`
e.g. `delete patient /info S1234567A` | +| `delete medicine` | `delete medicine /info [batch id]`
e.g. `delete medicine /info S234` | +| `delete appointment` | `delete appointment /info [appointment id]`
e.g. `delete appointment /info 12356710156543` | +| `find doctor` | `find doctor /info [parameter], [keyword to find]`
e.g.`find doctor /info name, Jimmy`
parameter must be one of the seven (name, nric, age, gender, address, dob or specialization) | +| `find patient` | `find patient /info [parameter], [keyword to find]`
e.g.`find patient /info name, Steven Oz`
parameter must be one of the seven (name, nric, age, gender, address, dob or registrationdate) | +| `find medicine` | `find medicine /info [parameter], [keyword to find]`
e.g.`find medicine /info name, Paracetamol`
e.g.parameter must be one of the six (name, id, dosage, expiry, sideeffects, quantity) | +| `find appointment` | `find appointment /info [parameter], [keyword to find]`
e.g.`find appointment /info id, 12356701017647`
e.g.parameter must be one of the six (appointment id, patient nric, patient name, doctor nric, doctor name, appointment date) | +| `edit doctor` | `edit doctor /info [nric],[name],[age],[gender],[address],[DOB],[Specialisation]`
e.g.`edit doctor /info S1234567A, John Doe, 23, M, 10 Baker Street, 1999-12-31, Urinology` | +| `edit patient` | `edit patient /info [nric],[name],[age],[gender],[address],[DOB],[DOR]`
e.g.`edit patient /info S1234567A, John Doe, 23, M, 10 Baker Street, 1999-12-31, 2021-02-15` | +| `edit medicine` | `edit medicine /info [batch id],[name],[dosage],[expiry date],[side effects],[quantity]`
e.g.`edit medicine /info A123,Paracetamol, 500, 2023-06-11, drowsy, 10` | +| `update medicines` | `update medicines`
e.g `update medicines` | +| `clear old medicines` | `clear old medicines`
e.g `clear old medicines` | +| `dispense medicine` | `dispense medicine /info [NRIC],[Medicine Name],[Quantity]`
e.g `dispense medicine /info S1234567A,Paracetamol,10,Aspirin,20` | +| `help` | view the help function for all the commands required | +| `bye` | exit the programme | diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..c4192631f2 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/docs/diagrams/AppointmentListUML.png b/docs/diagrams/AppointmentListUML.png new file mode 100644 index 0000000000..7ddc92300d Binary files /dev/null and b/docs/diagrams/AppointmentListUML.png differ diff --git a/docs/diagrams/AppointmentListUML.puml b/docs/diagrams/AppointmentListUML.puml new file mode 100644 index 0000000000..2002445359 --- /dev/null +++ b/docs/diagrams/AppointmentListUML.puml @@ -0,0 +1,29 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class AppointmentList { +-appointments : Arraylist = null +-returnedFinderArray : Arraylist = null +-referencePatientList : PatientList = null +-referenceDoctorList : DoctorList = null ++AppointmentList(PatientList, DoctorList) : void ++getAppointment(String) : Appointment ++getList() : Arraylist ++add(String[]) : void ++remove(String) : void ++edit(String[]) : void ++view() : void ++view(String) : void ++findById(String[]) : void ++findByPatientName(String[]) : void ++findByPatientNric(String[]) : void ++findByDoctorName(String[]) : void ++findByDoctorNric(String[]) : void ++findByAppointmentDate(String[]) : void ++createArrayOfFoundAppointments() : void ++hasAppointmentToday(String, String) : boolean ++dispenseMedicine(String, String) : void ++loadMedicine(String[]) : void +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/AppointmentUML.png b/docs/diagrams/AppointmentUML.png new file mode 100644 index 0000000000..17ff9861ed Binary files /dev/null and b/docs/diagrams/AppointmentUML.png differ diff --git a/docs/diagrams/AppointmentUML.puml b/docs/diagrams/AppointmentUML.puml new file mode 100644 index 0000000000..408fe5bc2c --- /dev/null +++ b/docs/diagrams/AppointmentUML.puml @@ -0,0 +1,26 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class Appointment { +#appointmentId : String +#patientNric : String +#patientName : String +#doctorNric : String +#doctorName : String +#appointmentDate : String +#appointmentDetails : String ++Appointment(appointmentId, patientNric, patientName, doctorNric, +doctorName, appointmentDate, appointmentDetails) : void ++toString() : String ++getAppointmentId() : String ++getPatientNric() : String ++getPatientName() : String ++getDoctorNric() : String ++getDoctorName() : String ++getAppointmentDate() : String ++getAppointmentDetails() : String ++saveString() : String ++saveMedicineString() : String +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/CommandClassUML.png b/docs/diagrams/CommandClassUML.png new file mode 100644 index 0000000000..1fb258bfd4 Binary files /dev/null and b/docs/diagrams/CommandClassUML.png differ diff --git a/docs/diagrams/CommandClassUML.puml b/docs/diagrams/CommandClassUML.puml new file mode 100644 index 0000000000..c9ce25dd29 --- /dev/null +++ b/docs/diagrams/CommandClassUML.puml @@ -0,0 +1,41 @@ +@startuml +'https://plantuml.com/class-diagram + +hide circle +skinparam classAttributeIconSize 0 + +abstract class Command { + +parameterArray: String[] + +Command(parameterArray: String[]) + +{abstract} execute(list: List) : Status +} + +Command <|-- AppointmentCommand +class AppointmentCommand { + +parameterArray: String[] + +AppointmentCommand(parameterArray: String[]) + +execute(appointmentList: List) : Status +} + +Command <|--- DoctorCommand +class DoctorCommand { + +parameterArray: String[] + +DoctorCommand(parameterArray: String[]) + +execute(doctorList: List) : Status +} + +Command <|--- PatientCommand +class PatientCommand { + +parameterArray: String[] + +PatientCommand(parameterArray: String[]) + +execute(patientList: List) : Status +} + +Command <|-- MedicineCommand +class MedicineCommand { + +parameterArray: String[] + +MedicineCommand(parameterArray: String[]) + +execute(medicineList: List) : Status +} + +@enduml diff --git a/docs/diagrams/CommandUML.png b/docs/diagrams/CommandUML.png new file mode 100644 index 0000000000..0a44811370 Binary files /dev/null and b/docs/diagrams/CommandUML.png differ diff --git a/docs/diagrams/CommandUML.puml b/docs/diagrams/CommandUML.puml new file mode 100644 index 0000000000..c09e8851ec --- /dev/null +++ b/docs/diagrams/CommandUML.puml @@ -0,0 +1,32 @@ +@startuml +'https://plantuml.com/sequence-diagram + +alt add patient + Manager -> Command: addPatient + Command -> PatientList: add +else delete patient + Manager -> Command: deletePatient + Command -> PatientList: removePatient +else view patient + Manager -> Command: viewPatient + Command -> PatientList: viewPatient +else add doctor + Manager -> Command: addDoctor + Command -> DoctorList: add +else delete doctor + Manager -> Command: deleteDoctor + Command -> DoctorList: removeDoctor +else view doctor + Manager -> Command: viewDoctor + Command -> DoctorList: viewDoctor +else add medicine + Manager -> Command: addMedicine + Command -> MedicineList: add +else delete medicine + Manager -> Command: deleteMedicine + Command -> MedicineList: delete +else view medicine + Manager -> Command: viewMedicine + Command -> MedicineList: viewMedicine +end +@enduml diff --git a/docs/diagrams/DispenseMed.png b/docs/diagrams/DispenseMed.png new file mode 100644 index 0000000000..61a64dd08e Binary files /dev/null and b/docs/diagrams/DispenseMed.png differ diff --git a/docs/diagrams/DispenseMed.puml b/docs/diagrams/DispenseMed.puml new file mode 100644 index 0000000000..2334e875ff --- /dev/null +++ b/docs/diagrams/DispenseMed.puml @@ -0,0 +1,73 @@ +@startuml +actor User as User #blue +activate Manager +Manager -> UI : readCommand() +activate UI +UI -> User : Reads in Command +User --> UI : "dispense medicine" +UI --> Manager : "dispense medicine" +deactivate UI + +Manager -> UI : readParameters() +activate UI +UI -> User : Reads in Command +User --> UI : "S1234567A,Paracetamol,10" +UI --> Manager : "S1234567A,Paracetamol,10" +deactivate UI + +Manager -> Manager : executeCommand("dispense medicine","S1234567A,Paracetamol,10") +activate Manager #blue +Manager -> Manager : executeOtherCommands("dispense medicine","S1234567A,Paracetamol,10") +activate Manager #orange +Manager -> Parser: parseDispenseMedicine("S1234567A,Paracetamol,10") +activate Parser +Parser -> Validator: validateDispenseMedicine({"S1234567A","Paracetamol","10"} +activate Validator +Validator --> Parser +deactivate Validator +Parser -> DispenseMedicineCommand : command({"S1234567A","Paracetamol","10"}) +activate DispenseMedicineCommand +DispenseMedicineCommand --> Parser +deactivate DispenseMedicineCommand +Parser --> Manager : :DispenseMedicineCommand +deactivate Parser +Manager -> Parser : parseCheckForPatientAppointment("S1234567A,Paracetamol,10") +activate Parser +Parser -> CheckIfAppointmentTodayCommand: command({"S1234567A","Paracetamol","10"}) +activate CheckIfAppointmentTodayCommand +CheckIfAppointmentTodayCommand --> Parser +deactivate CheckIfAppointmentTodayCommand +Parser --> Manager : :CheckIfAppointmentTodayCommand +deactivate Parser +Manager -> CheckIfAppointmentTodayCommand : execute(AppointmentList) +activate CheckIfAppointmentTodayCommand +CheckIfAppointmentTodayCommand --> Manager: Status.APPOINTMENT_FOUND_SUCCESS +deactivate CheckIfAppointmentTodayCommand +destroy CheckIfAppointmentTodayCommand +Manager -> Parser: parseCheckMedicineStock("S1234567A,Paracetamol,10") +activate Parser +Parser -> CheckForMedicineStockCommand : command({"S1234567A","Paracetamol","10"}) +activate CheckForMedicineStockCommand +CheckForMedicineStockCommand --> Parser +deactivate CheckForMedicineStockCommand +Parser --> Manager: :CheckForMedicineStockCommand +deactivate Parser +Manager -> CheckForMedicineStockCommand: execute(MedicineList) +activate CheckForMedicineStockCommand +CheckForMedicineStockCommand --> Manager : Status.MEDICINE_STOCK_FOUND_SUCCESS +deactivate CheckForMedicineStockCommand +destroy CheckForMedicineStockCommand +Manager -> DispenseMedicineCommand: execute(MedicineList) +activate DispenseMedicineCommand +DispenseMedicineCommand --> Manager : Status.DISPENSE_SUCCESS +deactivate DispenseMedicineCommand +destroy DispenseMedicineCommand +Manager --> Manager: Status.DISPENSE_SUCCESS +deactivate Manager +Manager --> Manager: Status.DISPENSE_SUCCESS +deactivate Manager + + + + +@enduml \ No newline at end of file diff --git a/docs/diagrams/Doctor.png b/docs/diagrams/Doctor.png new file mode 100644 index 0000000000..dd5914fd29 Binary files /dev/null and b/docs/diagrams/Doctor.png differ diff --git a/docs/diagrams/Doctor.puml b/docs/diagrams/Doctor.puml new file mode 100644 index 0000000000..4c8ea8d4ed --- /dev/null +++ b/docs/diagrams/Doctor.puml @@ -0,0 +1,13 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class Doctor { +-specialization : String ++Doctor(nric, fullName,age, gender, address, dob, specialization) : void ++getSpecialization() : String ++edit(fullName, age, address, gender, dob, specialization) : void ++saveString() : String ++toString() : String +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/DoctorList.png b/docs/diagrams/DoctorList.png new file mode 100644 index 0000000000..f808529819 Binary files /dev/null and b/docs/diagrams/DoctorList.png differ diff --git a/docs/diagrams/DoctorList.puml b/docs/diagrams/DoctorList.puml new file mode 100644 index 0000000000..edc793991d --- /dev/null +++ b/docs/diagrams/DoctorList.puml @@ -0,0 +1,29 @@ +@startuml +'https://plantuml.com/class-diagram +hide circle +skinparam classAttributeIconSize 0 +class DoctorList { +-doctors : Arraylist = null +-returnedFinderArray : Arraylist = null ++getDoctor(String) : Doctor ++search()(String) : Doctor ++add(String[]) : void ++view() : void ++view(String) : void ++edit(String[]) : void ++getSize() : int ++remove(String) : void ++toString() : String ++getList() : Arraylist ++findByNric(String[]) : void ++findByName(String[]) : void ++findByAge(String[]) : void ++findByGender(String[]) : void ++findByAddress(String[]) : void ++findByDob(String[]) : void ++findBySpecialization(String[]) : void ++displayFoundDoctorList() : void ++loadDate(String[]) : void +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/ExceptionClass.png b/docs/diagrams/ExceptionClass.png new file mode 100644 index 0000000000..40b26f29c3 Binary files /dev/null and b/docs/diagrams/ExceptionClass.png differ diff --git a/docs/diagrams/ExceptionClass.puml b/docs/diagrams/ExceptionClass.puml new file mode 100644 index 0000000000..88d9298f0f --- /dev/null +++ b/docs/diagrams/ExceptionClass.puml @@ -0,0 +1,29 @@ +@startuml +'https://plantuml.com/class-diagram +hide circle + +skinparam classAttributeIconSize 0 +class UserInputErrorException { + +UserInputErrorException(String) + +toString() : String +} +class DuplicateEntryException { + +DuplicateEntryException(String) + +toString() : String + } + +class NotFoundException { + +DuplicateEntryException(String) + +toString() : String +} + +class HalpmiException{ + +HalpmiException(String) + +toString() : String +} +DuplicateEntryException --|> HalpmiException +UserInputErrorException --|> HalpmiException +NotFoundException --|> HalpmiException + +HalpmiException --|> Exception +@enduml \ No newline at end of file diff --git a/docs/diagrams/ExceptionClassUML.png b/docs/diagrams/ExceptionClassUML.png new file mode 100644 index 0000000000..837734e47c Binary files /dev/null and b/docs/diagrams/ExceptionClassUML.png differ diff --git a/docs/diagrams/ManagerClass.png b/docs/diagrams/ManagerClass.png new file mode 100644 index 0000000000..af3dfaa155 Binary files /dev/null and b/docs/diagrams/ManagerClass.png differ diff --git a/docs/diagrams/ManagerClass.puml b/docs/diagrams/ManagerClass.puml new file mode 100644 index 0000000000..84884f3ff1 --- /dev/null +++ b/docs/diagrams/ManagerClass.puml @@ -0,0 +1,20 @@ +@startuml +'https://plantuml.com/class-diagram +hide circle +skinparam classAttributeIconSize 0 +class Manager { ++ ui: UI = new UI +- isTerminated: boolean = false +- storage: Storage = new Storage ++ runLoop() : void +- executeCommand(commandWord: String, parameters: String) : Status ++ executeAddCommand(commandWord: String, parameters: String) : Status ++ executeDeleteCommand(commandWord: String, parameters: String) : Status ++ executeViewCommand(commandWord: String, parameters: String) : Status ++ executeEditCommand(commandWord: String, parameters: String) : Status ++ executeFindCommand(commandWord: String, parameters: String) : Status ++ executeOtherCommand(commandWord: String, parameters: String) : Status +} + + +@enduml diff --git a/docs/diagrams/ManagerUML.puml b/docs/diagrams/ManagerUML.puml new file mode 100644 index 0000000000..c566cd2727 --- /dev/null +++ b/docs/diagrams/ManagerUML.puml @@ -0,0 +1,32 @@ +@startuml +'https://plantuml.com/sequence-diagram + +Duke -> Manager: runLoop +loop Not isTerminated + alt add patient + Manager -> Command: addPatient + else delete patient + Manager -> Command: deletePatient + else view patient + Manager -> Command: viewPatient + else add doctor + Manager -> Command: addDoctor + else delete doctor + Manager -> Command: deleteDoctor + else view doctor + Manager -> Command: viewDoctor + else add medicine + Manager -> Command: addMedicine + else delete medicine + Manager -> Command: deleteMedicine + else view medicine + Manager -> Command: viewMedicine + else help + Manager -> UI: printHelp + else bye + Manager -> UI: printBye + else DEFAULT + Manager -> UI: readCommand + end +end +@enduml diff --git a/docs/diagrams/MedicineListUML.png b/docs/diagrams/MedicineListUML.png new file mode 100644 index 0000000000..048757cc1a Binary files /dev/null and b/docs/diagrams/MedicineListUML.png differ diff --git a/docs/diagrams/MedicineListUML.puml b/docs/diagrams/MedicineListUML.puml new file mode 100644 index 0000000000..011cfe2a6d --- /dev/null +++ b/docs/diagrams/MedicineListUML.puml @@ -0,0 +1,30 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class MedicineList { +-medicines : Arraylist = null +-expiredMedicines : Arraylist = null +-returnedFinderArray : Arraylist = null ++getSize() : int ++getMedicine(String) : Medicine ++search(String) : Medicine ++add(String[]) : void ++find(String[]) : void ++getMedicineInfo(Medicine) : String ++view(String) : void ++view() : void ++remove(String) : void ++edit(String[]) : void ++viewExpired() : void ++updateStock() : void ++clearStock() : void ++findById(String[]) : void ++findByDosage(String[]) : void ++findByExpiry(String[]) : void ++findBySideEffects(String[]) : void ++findByQuantity(String[]) : void ++findByName(String[]) : void ++createArrayOfFoundMedicines() : void +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/MedicineUML.png b/docs/diagrams/MedicineUML.png new file mode 100644 index 0000000000..ea97a93590 Binary files /dev/null and b/docs/diagrams/MedicineUML.png differ diff --git a/docs/diagrams/MedicineUML.puml b/docs/diagrams/MedicineUML.puml new file mode 100644 index 0000000000..4007d04b6e --- /dev/null +++ b/docs/diagrams/MedicineUML.puml @@ -0,0 +1,22 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class Medicine { +-medicineId : String +-medicineName : String +-dosage : int +-expiry : String +-sideEffects : String +-quantity : int ++Medicine(medicineId, medicineName, dosage, expiry,sideEffects, quantity) : void ++edit(medicineName, dosage, expiry, sideEffects, quantity) : void ++saveString() : String ++getMedicineId() : String ++getMedicineName() : String ++getDosage() : String ++getExpiry() : String ++getSideEffects() : String ++getQuantiy() : int +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/OverallArch.png b/docs/diagrams/OverallArch.png new file mode 100644 index 0000000000..ec482285e8 Binary files /dev/null and b/docs/diagrams/OverallArch.png differ diff --git a/docs/diagrams/ParserClassUML.png b/docs/diagrams/ParserClassUML.png new file mode 100644 index 0000000000..eb0e11e971 Binary files /dev/null and b/docs/diagrams/ParserClassUML.png differ diff --git a/docs/diagrams/ParserClassUML.puml b/docs/diagrams/ParserClassUML.puml new file mode 100644 index 0000000000..40770587ee --- /dev/null +++ b/docs/diagrams/ParserClassUML.puml @@ -0,0 +1,37 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 + +class Parser { ++checkifDoctorExists (String): Command ++checkifPatientExists(String): Command ++commandParser (String): String( ++parseAddAppointment (String): Command ++parseAddDoctor(String): Command ++parseAddMedicine(String): Command ++parseAddPatient(String): Command ++parseCheckForPatientAppointment(String): Command ++parseCheckMedicineStock(String): Command ++parseClearExpiredMedicine(String): Command ++parseDeleteAppointment (String): Command ++parseDeleteDoctor(String): Command ++parseDeleteMedicine(String): Command ++parseDeletePatient(String): Command ++parseDispenseMedicine(String): Command ++parseEditAppointment(String): Command ++parseEditDoctor(String): Command ++parseEditMedicine(String): Command ++parseEditPatient (String): Command ++parseFindAppointment (String): Command ++parseFindDoctor (String): Command ++parseFindMedicine(String): Command ++parseFindPatient(String): Command ++parseUpdateMedicineStock(String): Command ++parseViewAppointment(String): Command ++parseViewDoctor(String): Command ++parseViewMedicine(String): Command ++parseViewPatient (String): Command +-isNull(String): boolean +-stringSplitter (String): String (] +} +@enduml \ No newline at end of file diff --git a/docs/diagrams/ParserUML.png b/docs/diagrams/ParserUML.png new file mode 100644 index 0000000000..5ae5299243 Binary files /dev/null and b/docs/diagrams/ParserUML.png differ diff --git a/docs/diagrams/ParserUML.puml b/docs/diagrams/ParserUML.puml new file mode 100644 index 0000000000..4822d5c30d --- /dev/null +++ b/docs/diagrams/ParserUML.puml @@ -0,0 +1,22 @@ +@startuml +'https://plantuml.com/sequence-diagram +!include style.puml + + +box LOGIC_COLOR_T1 +participant ":Parser" as Parser LOGIC_COLOR_T2 +participant ":Validator" as Validator LOGIC_COLOR_T2 + + + +Parser -> Validator: validateMedicine +alt LOGIC_COLOR_T2 +Validator -> Parser +else LOGIC_COLOR_T2 +Validator -> Parser : UserInputErrorException +end +<--Parser : AddMedicineCommand +end box + + +@enduml \ No newline at end of file diff --git a/docs/diagrams/Patient.png b/docs/diagrams/Patient.png new file mode 100644 index 0000000000..5818528d49 Binary files /dev/null and b/docs/diagrams/Patient.png differ diff --git a/docs/diagrams/Patient.puml b/docs/diagrams/Patient.puml new file mode 100644 index 0000000000..ecb5721915 --- /dev/null +++ b/docs/diagrams/Patient.puml @@ -0,0 +1,20 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class Patient { +-dateAdmission : String ++Patient(nric, fullName, age, gender, address, dob, dateAdmission) : void ++getDateAdmission() : String ++edit(fullName, age, address, gender, dob, dateAdmission) : void ++getPatientNric() : String ++getPatientName() : String ++getPatientAge() : String ++getPatientGender() : String ++getPatientAddress() : String ++getPatientDob() : String ++getDateOfAdmission() : String ++saveString() : String ++appointmentDate() : ArrayList +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/PatientList.png b/docs/diagrams/PatientList.png new file mode 100644 index 0000000000..cc2d417c3e Binary files /dev/null and b/docs/diagrams/PatientList.png differ diff --git a/docs/diagrams/PatientList.puml b/docs/diagrams/PatientList.puml new file mode 100644 index 0000000000..7f971e878d --- /dev/null +++ b/docs/diagrams/PatientList.puml @@ -0,0 +1,29 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class PatientList { +-patients : Arraylist = null +-returnedFinderArray : Arraylist = null ++getPatient(String) : Patient ++search()(String) : Patient ++add(String[]) : void ++getPatientInfo(Patient) : String ++getSize() : int ++view() : void ++view(String) : void ++edit(String[]) : void ++remove(String) : void ++getList() : Arraylist ++toString() : String ++findByNric(String[]) : void ++findByName(String[]) : void ++findByAge(String[]) : void ++findByGender(String[]) : void ++findByAddress(String[]) : void ++findByDob(String[]) : void ++findByDateAdmission(String[]) : void ++displayFoundPatientList() : void ++loadDate(String[]) : void +} + +@enduml \ No newline at end of file diff --git a/docs/diagrams/SequenceDiagram.png b/docs/diagrams/SequenceDiagram.png new file mode 100644 index 0000000000..0f41ca3778 Binary files /dev/null and b/docs/diagrams/SequenceDiagram.png differ diff --git a/docs/diagrams/SequenceDiagram.puml b/docs/diagrams/SequenceDiagram.puml new file mode 100644 index 0000000000..d368bd5d79 --- /dev/null +++ b/docs/diagrams/SequenceDiagram.puml @@ -0,0 +1,113 @@ +@startuml +actor User as User #blue + + +User -> Duke : Launches App +activate Duke #white + +Duke -> Manager : Manager() +activate Manager #yellow + +Manager -> UI: UI() +activate UI #green +UI --> Manager +deactivate UI + +Manager -> Storage : Storage() +activate Storage #green +collections Assets as Assets +Storage -> Assets: Initialise Asset Objects +activate Assets #grey +Assets --> Storage +deactivate Assets + + +Storage -> Storage : loadData() +activate Storage #green +Storage -> Assets: add() +activate Assets #grey +Assets --> Storage +deactivate Assets +Storage --> Storage: +deactivate Storage +Storage --> Manager: +deactivate Storage + +deactivate Manager + +Duke -> Manager: runLoop() +activate Manager #yellow +loop until bye command + Manager -> UI: readCommand() + activate UI #green + UI -> User: Reads User Input + User --> UI: command + UI --> Manager: UserInput + deactivate UI + Manager -> UI: readParameters() + activate UI #green + UI -> User: Reads User Input + User --> UI: parameters + UI --> Manager: UserInput + deactivate UI + Manager -> Parser: parseCommand() + activate Parser #green + Parser -> Validator: validateParameters() + activate Validator #green + Validator --> Parser + deactivate Validator + opt Parameters are Valid + Parser -> Command: command() + activate Command #green + Command --> Parser + deactivate Command + Parser --> Manager: :Command + end + deactivate Parser + Manager -> Command: execute() + activate Command #green + Command -> Storage: Access Assets + activate Storage #green + Storage -> Assets : edit Assets + activate Assets #grey + Assets --> Storage + deactivate Assets + Storage --> Command + deactivate Storage + Command -> Status: Status() + activate Status + Status --> Command + deactivate Status + Command --> Manager: :Status + deactivate Command + Manager -> UI: print(:Status) + activate UI #green + UI -> Status : Get the Status + activate Status + Status --> UI + deactivate Status + UI --> Manager + deactivate UI + destroy Status + destroy Command + Manager -> Storage: saveData() + activate Storage #green + Storage -> Assets: Retrieve Data from Asset Objects + activate Assets #grey + Assets --> Storage: Data in CSV format + deactivate Assets + Storage --> Manager + deactivate Storage +end +Manager --> Duke +deactivate Manager +destroy Assets +destroy Storage +destroy UI +destroy Parser +destroy Validator +destroy Manager +deactivate Duke +destroy Duke + +@enduml \ No newline at end of file diff --git a/docs/diagrams/StorageClassUML.png b/docs/diagrams/StorageClassUML.png new file mode 100644 index 0000000000..ff32f8d686 Binary files /dev/null and b/docs/diagrams/StorageClassUML.png differ diff --git a/docs/diagrams/StorageClassUML.puml b/docs/diagrams/StorageClassUML.puml new file mode 100644 index 0000000000..3dfbc10764 --- /dev/null +++ b/docs/diagrams/StorageClassUML.puml @@ -0,0 +1,38 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +abstract List +class PatientList +class DoctorList +class MedicineList +class AppointmentList + +List <|-- PatientList +List <|-- DoctorList +List <|-- MedicineList +List <|-- AppointmentList + +class Storage { + String DIR + String PATH_DOC + String PATH_PAT + String PATH_MED + String PATH_APP + String PATH_APT_MEDS + + Storage() + + saveData() + + loadData() + - loadGenericData(filePath: String, listType : List) + - saveCorruptedData(filePath: String, stringArray : ArrayList) + - saveMedicineData() + - savePatientData() + - saveDoctorData() + - saveAppointmentData() +} + +Storage --> "1" PatientList +Storage --> "1" AppointmentList +Storage --> "1" DoctorList +Storage --> "1" MedicineList + +@enduml \ No newline at end of file diff --git a/docs/diagrams/Style.puml b/docs/diagrams/Style.puml new file mode 100644 index 0000000000..a08bc22c02 --- /dev/null +++ b/docs/diagrams/Style.puml @@ -0,0 +1,5 @@ +!define LOGIC_COLOR #3333C4 +!define LOGIC_COLOR_T1 #7777DB +!define LOGIC_COLOR_T2 #5252CE +!define LOGIC_COLOR_T3 #1616B0 +!define LOGIC_COLOR_T4 #101086 diff --git a/docs/diagrams/UIClass.puml b/docs/diagrams/UIClass.puml new file mode 100644 index 0000000000..eb00dc6fcc --- /dev/null +++ b/docs/diagrams/UIClass.puml @@ -0,0 +1,15 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class UI { +-userInput: String +-patients: ArrayList = new ArrayList<> +-reader: Scanner = new Scanner +-parser: Parser = new Parser +-readInput() : void ++readCommand() : String ++readParameters() : String ++printStatus(status: Status) : void +} + +@enduml diff --git a/docs/diagrams/UIClassUML.png b/docs/diagrams/UIClassUML.png new file mode 100644 index 0000000000..be96d82cab Binary files /dev/null and b/docs/diagrams/UIClassUML.png differ diff --git a/docs/diagrams/ValidatorClassUML.png b/docs/diagrams/ValidatorClassUML.png new file mode 100644 index 0000000000..34b4f5fd30 Binary files /dev/null and b/docs/diagrams/ValidatorClassUML.png differ diff --git a/docs/diagrams/ValidatorClassUML.puml b/docs/diagrams/ValidatorClassUML.puml new file mode 100644 index 0000000000..0b3a9e8895 --- /dev/null +++ b/docs/diagrams/ValidatorClassUML.puml @@ -0,0 +1,35 @@ +@startuml +hide circle +skinparam classAttributeIconSize 0 +class Validator { ++minParameterCheck(String U, int): void ++validateAddAppointment(String(]): void ++validateDispenseMedicine(String(]): void ++validateEditAppointment(String(]): void ++validateFindAppointment(String]): void ++validateFindDoctor(String (]): void ++validateFindMedicine(String()]): void ++validateFindPatient (String I)]): void ++validateMedicine (String I]): void ++validateNric(String): void ++validateAddDoctor(String(): void ++validateAddPatient (String I]): void +-validateAddPerson (String I]): void +-validateAddress (String): void +-validateAdmissionDate(String): void +-validateAdmissionDob(String, String): void +-validateAge(String): void +-validateAppointmentDetails(String): void +-validateDate(String): boolean +-validateDate(String, String): void +-validateDob(String): void +-validateDobAge(String, String): void +-validateDosage(String): boolean +-validateExpiry(String): boolean +-validateFullName(String): void +-validateGender(String): void +-validateMedicineName(String): boolean +-validateQuantity(String): boolean +-validateSpecialization(String): void +} +@enduml \ No newline at end of file diff --git a/docs/diagrams/ValidatorUML.png b/docs/diagrams/ValidatorUML.png new file mode 100644 index 0000000000..bb14133d87 Binary files /dev/null and b/docs/diagrams/ValidatorUML.png differ diff --git a/docs/diagrams/ValidatorUML.puml b/docs/diagrams/ValidatorUML.puml new file mode 100644 index 0000000000..206cd3cd69 --- /dev/null +++ b/docs/diagrams/ValidatorUML.puml @@ -0,0 +1,35 @@ +@startuml +!include style.puml + +box LOGIC_COLOR_T1 +participant ":Validator" as Validator LOGIC_COLOR_T2 + + +[-> Validator : validateMedicine(parameters) +activate Validator +Validator -> Validator : minParameterCheck(parameters, 6) +activate Validator +deactivate Validator +Validator -> Validator : validateMedicineName(parameters[1]) +activate Validator +deactivate Validator +Validator -> Validator : validateDosage(parameters[2]) +activate Validator +deactivate Validator +Validator -> Validator : validateExpiry(parameters[3]) +activate Validator +deactivate Validator +Validator -> Validator : validateQuantity(parameters[5]) +activate Validator +deactivate Validator + +alt LOGIC_COLOR_T2 +<-- Validator: +else LOGIC_COLOR_T2 +<-- Validator: UserInputErrorException +end + + + +@enduml + diff --git a/docs/diagrams/ViewAppointmentImplementation.puml b/docs/diagrams/ViewAppointmentImplementation.puml new file mode 100644 index 0000000000..ddcdbd64bd --- /dev/null +++ b/docs/diagrams/ViewAppointmentImplementation.puml @@ -0,0 +1,43 @@ +@startuml +actor User +User -> Manager : Type in command +activate Manager + +Manager -> UI : readCommand() +activate UI +UI --> Manager +deactivate UI + +Manager -> UI : readParameters() +activate UI +UI --> Manager +deactivate UI + +Manager -> Parser : parseViewAppointment(parameters) +activate Parser +alt parameters is null + Parser --> Manager : ViewAppointmentCommand(null) +else "else" + Parser --> Manager : FindAppointmentCommand(parameters) +end +deactivate Parser +Manager -> Command : execute(storage.appointments) +activate Command +alt ViewAppointmentCommand + Command -> Appointment : viewAllAppointments() + activate Appointment + Appointment --> Command + deactivate Appointment +else FindAppointmentCommand + Command -> Appointment : viewAppointmentsByCriteria(parameters) + activate Appointment + Appointment --> Command + deactivate Appointment +end +Command -> Status : Status() +activate Status +Status --> Command +deactivate Status +Command -> Manager : Status +deactivate Command +@enduml \ No newline at end of file diff --git a/docs/diagrams/ViewAppointmentImplementationUML.png b/docs/diagrams/ViewAppointmentImplementationUML.png new file mode 100644 index 0000000000..ba253e972e Binary files /dev/null and b/docs/diagrams/ViewAppointmentImplementationUML.png differ diff --git a/docs/photos/addAppointment.jpg b/docs/photos/addAppointment.jpg new file mode 100644 index 0000000000..a01ada00aa Binary files /dev/null and b/docs/photos/addAppointment.jpg differ diff --git a/docs/photos/addDoctor.jpg b/docs/photos/addDoctor.jpg new file mode 100644 index 0000000000..2011cef139 Binary files /dev/null and b/docs/photos/addDoctor.jpg differ diff --git a/docs/photos/addMedicine.jpg b/docs/photos/addMedicine.jpg new file mode 100644 index 0000000000..9e80c7f39a Binary files /dev/null and b/docs/photos/addMedicine.jpg differ diff --git a/docs/photos/addPatient.jpg b/docs/photos/addPatient.jpg new file mode 100644 index 0000000000..846e3cd305 Binary files /dev/null and b/docs/photos/addPatient.jpg differ diff --git a/docs/photos/anvitharajaram.jpg b/docs/photos/anvitharajaram.jpg new file mode 100644 index 0000000000..07079e634d Binary files /dev/null and b/docs/photos/anvitharajaram.jpg differ diff --git a/docs/photos/clearMedicine.jpg b/docs/photos/clearMedicine.jpg new file mode 100644 index 0000000000..bba019b72e Binary files /dev/null and b/docs/photos/clearMedicine.jpg differ diff --git a/docs/photos/deleteAppointment.jpg b/docs/photos/deleteAppointment.jpg new file mode 100644 index 0000000000..fffe541ba5 Binary files /dev/null and b/docs/photos/deleteAppointment.jpg differ diff --git a/docs/photos/deleteDoctor.jpg b/docs/photos/deleteDoctor.jpg new file mode 100644 index 0000000000..4a29c32853 Binary files /dev/null and b/docs/photos/deleteDoctor.jpg differ diff --git a/docs/photos/deleteMedicine.jpg b/docs/photos/deleteMedicine.jpg new file mode 100644 index 0000000000..225c36bd48 Binary files /dev/null and b/docs/photos/deleteMedicine.jpg differ diff --git a/docs/photos/deletePatient.jpg b/docs/photos/deletePatient.jpg new file mode 100644 index 0000000000..577b36f675 Binary files /dev/null and b/docs/photos/deletePatient.jpg differ diff --git a/docs/photos/dispenseMedicine.jpg b/docs/photos/dispenseMedicine.jpg new file mode 100644 index 0000000000..cd8825cace Binary files /dev/null and b/docs/photos/dispenseMedicine.jpg differ diff --git a/docs/photos/editDoctor.jpg b/docs/photos/editDoctor.jpg new file mode 100644 index 0000000000..21a587f4fb Binary files /dev/null and b/docs/photos/editDoctor.jpg differ diff --git a/docs/photos/editPatient.jpg b/docs/photos/editPatient.jpg new file mode 100644 index 0000000000..74dd7a6f3b Binary files /dev/null and b/docs/photos/editPatient.jpg differ diff --git a/docs/photos/editmedicine.jpg b/docs/photos/editmedicine.jpg new file mode 100644 index 0000000000..2f58cac4a5 Binary files /dev/null and b/docs/photos/editmedicine.jpg differ diff --git a/docs/photos/findAppointment.jpg b/docs/photos/findAppointment.jpg new file mode 100644 index 0000000000..ff9150140c Binary files /dev/null and b/docs/photos/findAppointment.jpg differ diff --git a/docs/photos/findDoctor.jpg b/docs/photos/findDoctor.jpg new file mode 100644 index 0000000000..ed920be654 Binary files /dev/null and b/docs/photos/findDoctor.jpg differ diff --git a/docs/photos/findMedicine.jpg b/docs/photos/findMedicine.jpg new file mode 100644 index 0000000000..aa9dfeb9c1 Binary files /dev/null and b/docs/photos/findMedicine.jpg differ diff --git a/docs/photos/findPatient.jpg b/docs/photos/findPatient.jpg new file mode 100644 index 0000000000..99b0798612 Binary files /dev/null and b/docs/photos/findPatient.jpg differ diff --git a/docs/photos/sharif.jpg b/docs/photos/sharif.jpg new file mode 100644 index 0000000000..1622412607 Binary files /dev/null and b/docs/photos/sharif.jpg differ diff --git a/docs/photos/startHalpmi.jpg b/docs/photos/startHalpmi.jpg new file mode 100644 index 0000000000..a264ca7abd Binary files /dev/null and b/docs/photos/startHalpmi.jpg differ diff --git a/docs/photos/taikahkiang.jpeg b/docs/photos/taikahkiang.jpeg new file mode 100644 index 0000000000..4f5d22ab1c Binary files /dev/null and b/docs/photos/taikahkiang.jpeg differ diff --git a/docs/photos/tanweili.jpg b/docs/photos/tanweili.jpg new file mode 100644 index 0000000000..48be35299b Binary files /dev/null and b/docs/photos/tanweili.jpg differ diff --git a/docs/photos/updateMedicine.jpg b/docs/photos/updateMedicine.jpg new file mode 100644 index 0000000000..1e266ed04e Binary files /dev/null and b/docs/photos/updateMedicine.jpg differ diff --git a/docs/photos/viewAppointment.jpg b/docs/photos/viewAppointment.jpg new file mode 100644 index 0000000000..0805e1dd44 Binary files /dev/null and b/docs/photos/viewAppointment.jpg differ diff --git a/docs/photos/viewDoctor.jpg b/docs/photos/viewDoctor.jpg new file mode 100644 index 0000000000..0d6de573b9 Binary files /dev/null and b/docs/photos/viewDoctor.jpg differ diff --git a/docs/photos/viewMedicine.jpg b/docs/photos/viewMedicine.jpg new file mode 100644 index 0000000000..cd4b1955d3 Binary files /dev/null and b/docs/photos/viewMedicine.jpg differ diff --git a/docs/photos/viewPatient.jpg b/docs/photos/viewPatient.jpg new file mode 100644 index 0000000000..41da2207e4 Binary files /dev/null and b/docs/photos/viewPatient.jpg differ diff --git a/docs/photos/wraineflores.jpg b/docs/photos/wraineflores.jpg new file mode 100644 index 0000000000..e27252f69d Binary files /dev/null and b/docs/photos/wraineflores.jpg differ diff --git a/docs/team/Anvitha-r.md b/docs/team/Anvitha-r.md new file mode 100644 index 0000000000..42835bf36d --- /dev/null +++ b/docs/team/Anvitha-r.md @@ -0,0 +1,50 @@ +# Anvitha Rajaram - Project Portfolio Page + +## Overview +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors and keep track of medication stocks. +## Summary of Contributions + +**Code contributed:** [RepoSense link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=anvitha-r&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18) +
+ + +| Contribution, Enhancement | Description | +|---------------------------|---------------------------------------------------------------------------------------------| +| Delete doctor | Implemented the delete fuction to delete a dcotor based on the | +| View Doctor | Implemented view fucntion for doctor | +| View Table Format | Implemted a tableview format to arrange view fucntion clearly | +| Edit Patient record | Implemented the edit function for patient | +| Edit Doctor record | Implemented the edit function for doctor | +| Edit Find function | Edited the find function to display accordingly | +| Appointment function | Edited the appointment function to check for whether patient or doctor contains appointment | +| Fix bugs | Fixed some bugs from the pe2 dry run and made the respective changes | + + +## **UG contributions:** + +* Edited contents in the UG for continuity purposes +* Fixed the bugs in the UG according to the feedback from pe2 dry run +* Add images and screenshots to ease the readability +* Updated help commands +* Updated required sections whenever necessary + +## **DG contributions:** + +* Helped explain the Doctor class and Doctor List +* Helped explain the Patient class and Patient List +* Structured the user stories intially + +## **Team-based tasks contributions:** + +* Necessary general code enhancements is by everyone + +* Setting up tools e.g., GitHub, Gradle is by everyone + +* Maintaining the issue tracker is by everyone + +* Release management is done by consensus by the majority + +* Updating user/developer docs that are not specific to a feature is by everyone when we see a change fits + diff --git a/docs/team/anvitha-r.md b/docs/team/anvitha-r.md new file mode 100644 index 0000000000..42835bf36d --- /dev/null +++ b/docs/team/anvitha-r.md @@ -0,0 +1,50 @@ +# Anvitha Rajaram - Project Portfolio Page + +## Overview +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors and keep track of medication stocks. +## Summary of Contributions + +**Code contributed:** [RepoSense link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=anvitha-r&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18) +
+ + +| Contribution, Enhancement | Description | +|---------------------------|---------------------------------------------------------------------------------------------| +| Delete doctor | Implemented the delete fuction to delete a dcotor based on the | +| View Doctor | Implemented view fucntion for doctor | +| View Table Format | Implemted a tableview format to arrange view fucntion clearly | +| Edit Patient record | Implemented the edit function for patient | +| Edit Doctor record | Implemented the edit function for doctor | +| Edit Find function | Edited the find function to display accordingly | +| Appointment function | Edited the appointment function to check for whether patient or doctor contains appointment | +| Fix bugs | Fixed some bugs from the pe2 dry run and made the respective changes | + + +## **UG contributions:** + +* Edited contents in the UG for continuity purposes +* Fixed the bugs in the UG according to the feedback from pe2 dry run +* Add images and screenshots to ease the readability +* Updated help commands +* Updated required sections whenever necessary + +## **DG contributions:** + +* Helped explain the Doctor class and Doctor List +* Helped explain the Patient class and Patient List +* Structured the user stories intially + +## **Team-based tasks contributions:** + +* Necessary general code enhancements is by everyone + +* Setting up tools e.g., GitHub, Gradle is by everyone + +* Maintaining the issue tracker is by everyone + +* Release management is done by consensus by the majority + +* Updating user/developer docs that are not specific to a feature is by everyone when we see a change fits + diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md deleted file mode 100644 index ab75b391b8..0000000000 --- a/docs/team/johndoe.md +++ /dev/null @@ -1,6 +0,0 @@ -# John Doe - Project Portfolio Page - -## Overview - - -### Summary of Contributions diff --git a/docs/team/kktai1512.md b/docs/team/kktai1512.md new file mode 100644 index 0000000000..5d0b7256e3 --- /dev/null +++ b/docs/team/kktai1512.md @@ -0,0 +1,48 @@ +# Tai Kah Kiang - Project Portfolio Page (PPP) + +## Overview +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors and keep track of medication stocks. +## Summary of Contributions + +**Code contributed:** [RepoSense link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=kktai1512&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18) +
+**Enhancement implemented:** + +| Enhancement | Description | +|-------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| View patient | Implemented the view patient logic, to either view a particular patient, or all patients | +| Add patient | Implemented the add patient function | +| Add doctor | Added add doctor into Manager | +| Refactor validator | Refactored all the validation out from parser into a separate class, clean up Validator code and remove repetitions to make code cleaner. Reformatted code such that there's a higher cohesion between methods | +| Exceptions | Implemented exceptions such that methods now return exceptions instead of printing error message straight from the method itself | +| Exception abstraction | Created a parent exception `HalpmiException` and now `UserInputErrorException`, `DuplicateEntryException` and `NotFoundException` inherits it | +| Bug fixes | Fix bugs that are reported by other teams | +| Storage - corrupted files handling & refactoring of methods | Implemented a function such that the program does a preliminary check for the input files using Validator, such that the data makes sense, prompts the user for any corrupted lines, and moves those into a separate file. Since the data is all connected, if one part is deleted, another part should be corrupted too, hence this check ios essenial. Orignally researched on file encryption, and tried to implement it but found out that it makes more sense now to not put encryption such that the admin can easily sees the data outside of the application. Maybe a different encryption method could be used. | + + +**UG contributions:** +* Basic add, view, delete command summary table for V1.0 submission. +* Storage - corrupted files explanation +* Warnings and additional info +
+ +**DG contributions:** +* Parser class diagram and explanation +* Validator class diagram and explanation +* Parser-validator class logic explanation with sequence diagram +* Exception class explanation +
+ +**Team-based tasks contributions:** +* Gave recommendations and opinions on features discussed to be implemented +* Gave suggestions on the logic on how certain features are implemented +* Helped fixed bugs by testing out the application +* Set up Zoom meeting for every team meeting +* Reviewed PRs and gave suggestions +* Updated user/developer docs for typos +* Set up Trello for project management +* General code clean up + +Overall, I'm thankful for a great team, as everyone helps each other out. \ No newline at end of file diff --git a/docs/team/shxr3f.md b/docs/team/shxr3f.md new file mode 100644 index 0000000000..5b75c03ddc --- /dev/null +++ b/docs/team/shxr3f.md @@ -0,0 +1,43 @@ +# Project Portfolio Page - Mohamed Sharif +____________________________________________________________ + +## Code Contributions + +| Contribution | Description | +|-----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Add Medicine | Feature that allows user to add medicines into the application. | +| View Medicine | Feature that allows user to view all medicines in the list. | +| Edit Medicine | Feature that allows user to edit existing medicines | +| Update Medicine | Feature that allows user to update medicine inventory to check for expired medicines as well as medicine that have run out. | +| Assign Medicine | Feature that allows user to assign medications to patients who have appointments on that day. The user can request for certain medicines to be dispensed to the patient. HalpMi will show the list of medicines to dispense with the batch id and quantity. | +| Storage Class | Implemented storage class that holds all data (Patient, Doctor, Medicines, Appointments). Holds methods that load data from and save data to CSV files. | +| Refactoring Command Class | Initially our command class had static methods and was not showing good implementation of OOP principles. Hence I refactored the code to include abstract command class and various children classes for different commands available. | +| Other code corrections and improvements | Along the way there were various bugs and issues found with code that I have helped to correct as well. | +| JUnit Code | Contributed significantly to JUnit code for many methods that I was involved in creating. | + +For detailed look at code contribution: [TP Code Dashboard](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18&tabOpen=true&tabType=authorship&tabAuthor=shxr3f&tabRepo=AY2122S2-CS2113T-T09-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false) +____________________________________________________________ +## Other Contributions + +### **User Guide** + +Contributed to User Guide by setting up clear formatting in the initial iteration of drafting the UG. In the following +iterations, contributed by adding in the details of the various features implemented in HalpMi. + +### **Developer Guide** + +Contributed to Dev Guide by setting up the format in the early iterations of the Developer Guide. +Created the overall Sequence Diagram to show overall flow of logic. Also created a high-level design model of HalpMi. +Explained the usage and logic of the Storage Class and its methods with reference to Class Diagrams and Sequence Diagrams. +Explained on the implementation of features such as "Update Medicine" and "Assign Medicine" in the guide as well. + +____________________________________________________________ +## Learning Outcomes + +Through this project I was better able to appreciate the various tools such as IDEs, Gradle and Git that are available to +Software Engineers. The module gave insights on how these tools can help makes one's life easier especially when working on +a single product as a team. The project has also allowed me to learn key OOP principles and how good usage of OOP can lead +to a cohesive and less coupled app. This would make the code a joy to read for other developers and oneself alike. + +In conclusion, this module has been an eye-opener into the world of software engineering and through this project and my +contributions I was able to gain much knowledge that would really come handy in the workforce! \ No newline at end of file diff --git a/docs/team/tanweili.md b/docs/team/tanweili.md new file mode 100644 index 0000000000..63e53bf71b --- /dev/null +++ b/docs/team/tanweili.md @@ -0,0 +1,44 @@ +# Tan Wei Li - Project Portfolio Page + +## Overview +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors and keep track of medication stocks. +## Summary of Contributions + +**Code contributed:** [RepoSense link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=tanweili&sort=groupTitle&sortWithin=title&since=2022-02-18&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false) +
+
+**Enhancements implemented:** +
+I helped to implement the initial code logic and exceptions for adding and deleting patients using the Patient and +PatientList classes. I implemented most of the initial Appointment and AppointmentList classes, and integrated them +with the codebase to add, delete, find and view. Next, I implemented the feature that checks that the given patient +and doctor exists before adding them into the AppointmentList. + +This feature is pivotal for the product because it prevents the user from adding in non-existent patients and/or +doctors into the appointments and improves the functionality of the product as a whole. +
+
+**UG contributions:** +I helped to keep our UG updated as much as possible as our code evolved, by updating the command format and examples as +needed. +
+
+**DG contributions:** +I implemented the class diagrams for Appointment,AppointmentList,Medicine, and MedicineList and added in descriptions +for them in the DG. I also helped to make small changes to our DG as our code evolved, such as changing the required +command inputs in the appendix. I also helped to update the class diagrams by removing the default class and +method/variable icons, to adhere to the UML diagram standards given. I did the design implementation section regarding +the view appointment command. +
+
+**Team-based tasks contributions:** +I helped to set up the milestones and labels on Github issues. I also helped to release V2.0 and kept it updated as +much as possible prior to its deadline. I used the issue tracker as much as possible, by tagging the appropriate +labels and milestones. I closed a significant portion of the bugs from PE dry run by updating the code to address the +bugs where needed. +
+
+**Review contributions:** +I helped to review some of my teammates PRs, giving comments and suggestions where I thought was appropriate. \ No newline at end of file diff --git a/docs/team/wraineflores.md b/docs/team/wraineflores.md new file mode 100644 index 0000000000..269c4ba7ba --- /dev/null +++ b/docs/team/wraineflores.md @@ -0,0 +1,44 @@ +# Wraine Flores - Project Portfolio Page (PPP) + +## Overview +HALPMI is a Command Line Interface (CLI) Application that allows administrators in clinics to manage the clinic's day-to-day +administrative tasks. More specifically, using HALPMI the user is able to insert new information regarding Doctors, Patients +and Medication. Users can also schedule appointment for Patients with Doctors and keep track of medication stocks. +## Summary of Contributions + +## **Code contributed & Enhancement implemented:** [RepoSense link](https://nus-cs2113-ay2122s2.github.io/tp-dashboard/?search=wraineflores&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2022-02-18) +
+ +| Contributions & Enhancements | Description | +|------------------------------------------|---------------------------------------------------------------| +| Created Person | This class is is used to base Doctor & Person Classes | +| Find Doctor | Feature finds a doctor based on a specific parameter | +| Find Patient | Feature finds a patient based on a specific parameter | +| Find Medicine | Feature finds a medicine based on a specific parameter | +| Help Function | Compiled all help messages to be printed out | + +## **UG contributions:** + +* Edited contents in the UG for continuity purposes to see an overall picture + +* Tests examples in the UG to ensure its validity + +* Checked every section in UG to know that everything is in order + +## **DG contributions:** + +* Helped explain the Manager class and made its diagram + +* Helped explain the Command classes and made its diagram + +## **Team-based tasks contributions:** + +* Helped to set up the milestones and labels on Github issues when necessary + +* Helped maintain issue trackers for our Github + +* Updating user/developer docs that are not specific to a feature and see a change fits it + +* Regularly code reviews teammates' codes for merging into our master + +* Before the final release for v2.1, I have checked that all functions work as indicated in our guides diff --git a/hello b/hello new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..2e532db15c 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,21 +1,14 @@ package seedu.duke; -import java.util.Scanner; - public class Duke { + /** - * Main entry-point for the java.duke.Duke application. + * Main entry-point for the java.Duke.Duke application. */ public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); - - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); + assert true : "dummy assertion set to pass"; + Manager manager = new Manager(); + manager.runLoop(); } } + diff --git a/src/main/java/seedu/duke/Manager.java b/src/main/java/seedu/duke/Manager.java new file mode 100644 index 0000000000..6d70600a5c --- /dev/null +++ b/src/main/java/seedu/duke/Manager.java @@ -0,0 +1,265 @@ +package seedu.duke; + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.HalpmiException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.Parser; +import seedu.duke.helper.Storage; +import seedu.duke.helper.UI; +import seedu.duke.helper.command.Command; +import seedu.duke.status.Status; + +/** + * Manager class contains the main loop that runs until application is terminated. + */ +public class Manager { + UI ui = new UI(); + private boolean isTerminated = false; + private final Storage storage = new Storage(); + + /** + * Main application loop that holds switch case statement. + */ + public void runLoop() { + ui.printLogo(); + ui.printGreeting(); + + while (!isTerminated) { + UI.printPrompt(); + String commandWord = ui.readCommand(); + String parameters = ui.readParameters(); + Status status = null; + try { + status = executeCommand(commandWord, parameters); + ui.print(status); + } catch (HalpmiException e) { + UI.printParagraph(e.toString()); + } + storage.saveData(); + } + } + + private Status executeAddCommand(String commandWord, String parameters) throws HalpmiException, NotFoundException, + DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "add patient": + command = Parser.parseAddPatient(parameters); + status = command.execute(storage.patients); + break; + case "add doctor": + command = Parser.parseAddDoctor(parameters); + status = command.execute(storage.doctors); + break; + case "add medicine": + command = Parser.parseAddMedicine(parameters); + status = command.execute(storage.medicines); + break; + case "add appointment": + Command checkIfPatientExists = Parser.checkIfPatientExists(parameters); + checkIfPatientExists.execute(storage.patients); + + Command checkIfDoctorExists = Parser.checkIfDoctorExists(parameters); + checkIfDoctorExists.execute(storage.doctors); + + command = Parser.parseAddAppointment(parameters); + command.execute(storage.appointments); + + command.execute(storage.patients); + status = command.execute(storage.doctors); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + + return status; + } + + private Status executeDeleteCommand(String commandWord, String parameters) throws HalpmiException, + NotFoundException, DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "delete patient": + command = Parser.parseDeletePatient(parameters); + status = command.execute(storage.patients); + break; + case "delete doctor": + command = Parser.parseDeleteDoctor(parameters); + status = command.execute(storage.doctors); + break; + case "delete medicine": + command = Parser.parseDeleteMedicine(parameters); + status = command.execute(storage.medicines); + break; + case "delete appointment": + command = Parser.parseDeleteAppointment(parameters); + command.execute(storage.appointments); + command.execute(storage.patients); + status = command.execute(storage.doctors); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + return status; + } + + private Status executeViewCommand(String commandWord, String parameters) throws HalpmiException, NotFoundException, + DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "view patient": + command = Parser.parseViewPatient(parameters); + status = command.execute(storage.patients); + break; + case "view doctor": + command = Parser.parseViewDoctor(parameters); + status = command.execute(storage.doctors); + break; + case "view medicine": + command = Parser.parseViewMedicine(parameters); + status = command.execute(storage.medicines); + break; + case "view appointment": + command = Parser.parseViewAppointment(parameters); + status = command.execute(storage.appointments); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + return status; + } + + private Status executeEditCommand(String commandWord, String parameters) throws HalpmiException, NotFoundException, + DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "edit patient": + command = Parser.parseEditPatient(parameters); + status = command.execute(storage.patients); + break; + case "edit doctor": + command = Parser.parseEditDoctor(parameters); + status = command.execute(storage.doctors); + break; + case "edit medicine": + command = Parser.parseEditMedicine(parameters); + status = command.execute(storage.medicines); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + return status; + } + + private Status executeFindCommand(String commandWord, String parameters) throws HalpmiException, NotFoundException, + DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "find doctor": + command = Parser.parseFindDoctor(parameters); + status = command.execute(storage.doctors); + break; + case "find patient": + command = Parser.parseFindPatient(parameters); + status = command.execute(storage.patients); + break; + case "find medicine": + command = Parser.parseFindMedicine(parameters); + status = command.execute(storage.medicines); + break; + case "find appointment": + command = Parser.parseFindAppointment(parameters); + status = command.execute(storage.appointments); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + return status; + } + + private Status executeOtherCommands(String commandWord, String parameters) throws HalpmiException, + NotFoundException, DuplicateEntryException { + + Command command; + Status status = null; + switch (commandWord) { + case "update medicines": + command = Parser.parseUpdateMedicineStock(parameters); + status = command.execute(storage.medicines); + break; + case "clear old medicines": + command = Parser.parseClearExpiredMedicine(parameters); + status = command.execute(storage.medicines); + break; + case "dispense medicine": + command = Parser.parseDispenseMedicine(parameters); + + Command helperCommand = Parser.parseCheckForPatientAppointment(parameters); + helperCommand.execute(storage.appointments); + helperCommand = Parser.parseCheckMedicineStock(parameters); + helperCommand.execute(storage.medicines); + + command.execute(storage.appointments); + status = command.execute(storage.medicines); + break; + default: + throw new UserInputErrorException("Invalid Command given!"); + } + return status; + } + + /* + * Method that initialises the relevant Command object and executes the execute method. + * Upon execution, returns either a success message or throws exception. + * @ param commandWord a String that holds the initial command given by User + * @ param parameters a String that holds all the additional parameters given following the Command + * @ return Status object - enum that holds various success messages + * @ throws HalpmiException when the commandWord or parameters is not following correct formatting + * @ throws DuplicateEntryException when duplicate entries are being added through the Command + * @ throws NotFoundException when certain data was not found + */ + private Status executeCommand(String commandWord, String parameters) throws HalpmiException, NotFoundException, + DuplicateEntryException { + String firstCommand = commandWord.split(" ")[0].trim(); + Status status = null; + switch (firstCommand) { + case "add": + status = executeAddCommand(commandWord,parameters); + break; + case "delete": + status = executeDeleteCommand(commandWord,parameters); + break; + case "view": + status = executeViewCommand(commandWord,parameters); + break; + case "edit": + status = executeEditCommand(commandWord,parameters); + break; + case "find": + status = executeFindCommand(commandWord,parameters); + break; + case "help": + status = Status.PRINT_HELP; + break; + case "bye": + status = Status.END_APP; + System.out.println("Terminated"); + isTerminated = true; + break; + default: + status = executeOtherCommands(commandWord,parameters); + } + return status; + } +} diff --git a/src/main/java/seedu/duke/assets/Appointment.java b/src/main/java/seedu/duke/assets/Appointment.java new file mode 100644 index 0000000000..1ec6e763f9 --- /dev/null +++ b/src/main/java/seedu/duke/assets/Appointment.java @@ -0,0 +1,82 @@ +package seedu.duke.assets; + +import java.util.ArrayList; + +public class Appointment { + protected String appointmentId; + protected String patientNric; + protected String patientName; + protected String doctorNric; + protected String doctorName; + protected String appointmentDate; + protected String appointmentDetails; + protected ArrayList dispensedMedicines = new ArrayList<>(); + + public Appointment(String appointmentId, String patientNric, String patientName, String doctorNric, + String doctorName, String appointmentDate, String appointmentDetails) { + this.appointmentId = appointmentId; + this.patientName = patientName; + this.patientNric = patientNric; + this.doctorName = doctorName; + this.doctorNric = doctorNric; + this.appointmentDate = appointmentDate; + this.appointmentDetails = appointmentDetails; + } + + public void addMedicine(String medicineName, String quantity) { + dispensedMedicines.add(medicineName + "," + quantity); + } + + @Override + public String toString() { + return "Patient: " + patientName + " (" + patientNric + ")\n" + + "Doctor: " + doctorName + " (" + doctorNric + ")\n" + + "Appointment date: " + appointmentDate + "\n" + + "Appointment details: " + appointmentDetails + "\n"; + } + + public String getAppointmentId() { + return appointmentId; + } + + public String getPatientNric() { + return patientNric; + } + + public String getPatientName() { + return patientName; + } + + public String getDoctorNric() { + return doctorNric; + } + + public String getDoctorName() { + return doctorName; + } + + public String getAppointmentDate() { + return appointmentDate; + } + + public String getAppointmentDetails() { + return appointmentDetails; + } + + public String saveString() { + return patientNric + "," + doctorNric + "," + appointmentDate + "," + appointmentDetails; + } + + public String saveMedicineString() { + String returnString = ""; + for (int i = 0; i < dispensedMedicines.size(); i++) { + if (i != 0) { + returnString += "," + dispensedMedicines.get(i); + } else { + returnString += appointmentId + "," + dispensedMedicines.get(i); + } + } + return returnString; + } + +} diff --git a/src/main/java/seedu/duke/assets/AppointmentList.java b/src/main/java/seedu/duke/assets/AppointmentList.java new file mode 100644 index 0000000000..0f3fab0f45 --- /dev/null +++ b/src/main/java/seedu/duke/assets/AppointmentList.java @@ -0,0 +1,318 @@ +package seedu.duke.assets; + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.helper.CommandLineTable; +import seedu.duke.helper.IdGenerator; +import seedu.duke.helper.Storage; +import seedu.duke.helper.UI; +import seedu.duke.helper.finder.AppointmentFinder; +import seedu.duke.helper.finder.DoctorFinder; +import seedu.duke.helper.finder.PatientFinder; + + + +import java.time.LocalDate; +import java.util.ArrayList; + +public class AppointmentList extends List { + protected static ArrayList appointments = new ArrayList<>(); + private ArrayList returnedFinderArray = new ArrayList<>(); + + private PatientList referencePatientList; + private DoctorList referenceDoctorList; + private final String title = "Table of appointments"; + + + + public AppointmentList(PatientList patientList, DoctorList doctorList) { + this.referencePatientList = patientList; + this.referenceDoctorList = doctorList; + } + + public Appointment getAppointment(String appointmentId) { + for (Appointment appointment : appointments) { + if (appointment.getAppointmentId().equals(appointmentId)) { + return appointment; + } + } + return null; + } + + + public ArrayList getList() { + + + return appointments; + } + + + + @Override + public void add(String[] addAppointmentParameters) throws DuplicateEntryException { + final int numberOfAppointmentsBefore = appointments.size(); + String patientNric = addAppointmentParameters[0]; + PatientFinder patientFinder = new PatientFinder(); + ArrayList foundPatient = patientFinder.findPatientByNric(referencePatientList.getList(), patientNric); + + if (foundPatient == null) { + throw new DuplicateEntryException("Patient NRIC corrupted"); + } + + if (foundPatient == null) { + throw new DuplicateEntryException("Patient Nric corrupted"); + } + + + String doctorNric = addAppointmentParameters[1]; + DoctorFinder doctorFinder = new DoctorFinder(); + ArrayList foundDoctor = doctorFinder.findDoctorByNric(referenceDoctorList.getList(), doctorNric); + + if (foundDoctor == null) { + throw new DuplicateEntryException("Doctor NRIC corrupted"); + } + + String appointmentDate = addAppointmentParameters[2]; + String id = IdGenerator.createAppointmentId(patientNric, doctorNric, appointmentDate); + + for (Appointment appointment : appointments) { + if (appointment.getAppointmentId().equals(id)) { + throw new DuplicateEntryException("There is already an appointment between this doctor and patient " + + "on the given date!"); + } + } + + + if (referencePatientList.hasPatientDate(patientNric, appointmentDate)) { + throw new DuplicateEntryException("Patient already has an appointment on this date," + + " choose another appointment date "); + } + if (referenceDoctorList.hasDoctorDate(doctorNric, appointmentDate)) { + throw new DuplicateEntryException("Doctor already has an appointment on this date," + + " choose another appointment date "); + } + + String patientName = foundPatient.get(0).getPatientName(); + String doctorName = foundDoctor.get(0).getFullName(); + String appointmentDetails = addAppointmentParameters[3]; + Appointment newAppointment = new Appointment(id, patientNric, patientName, doctorNric, doctorName, + appointmentDate, appointmentDetails); + appointments.add(newAppointment); + assert appointments.size() == numberOfAppointmentsBefore + 1; + + } + + public String appointmentInformation(String appointmentId) throws NotFoundException { + for (int i = 0; i < appointments.size(); i++) { + if (appointments.get(i).getAppointmentId().equals(appointmentId)) { + String appointmentInfo = appointments.get(i).doctorNric + "," + appointments.get(i).patientNric + "," + + appointments.get(i).appointmentDate; + return appointmentInfo; + } + } + throw new NotFoundException("There is no appointment with the given appointment id.\n" + + "Please search by patient's nric or doctor's nric to find out the correct id if needed."); + } + + + + @Override + public void remove(String appointmentId) throws NotFoundException { + int numberOfAppointmentsBefore = appointments.size(); + for (int i = 0; i < appointments.size(); i++) { + if (appointments.get(i).getAppointmentId().equals(appointmentId)) { + appointments.remove(i); + assert appointments.size() == numberOfAppointmentsBefore - 1; + return; + } + } + throw new NotFoundException("There is no appointment with the given appointment id.\n" + + "Please search by patient's nric or doctor's nric to find out the correct id if needed."); + } + + @Override + public void edit(String[] parameters) throws NotFoundException { + for (int i = 0; i < appointments.size(); i++) { + if (appointments.get(i).getAppointmentId().equals(parameters[0])) { + appointments.remove(i); + Appointment editAppointment = new Appointment(parameters[0], parameters[1], + parameters[2], parameters[3], parameters[4], + parameters[5], parameters[6]); + appointments.add(editAppointment); + return; + } + } + throw new NotFoundException("There is no appointment with the given appointment id.\n" + + "Please search by patient's nric or doctor's nric to find out the correct id if needed."); + } + + @Override + public void view() throws UserInputErrorException { + + + CommandLineTable appointmentTable = new CommandLineTable(title); + + appointmentTable.setShowVerticalLines(true); + appointmentTable.setHeaders("Appointment Id", "Patient Name", "Patient NRIC", "Doctor Name", "Doctor NRIC", + "Appointment Date", "Appointment Details"); + if (appointments.size() == 0) { + throw new UserInputErrorException("Appointment list is empty, please add appointment"); + } + + + for (Appointment appointment : appointments) { + appointmentTable.addRow(appointment.getAppointmentId(), appointment.getPatientName(), + appointment.getPatientNric(), appointment.getDoctorName(), appointment.getDoctorNric(), + appointment.getAppointmentDate(), appointment.getAppointmentDetails()); + } + appointmentTable.print(); + } + + @Override + public void view(String appointmentId) throws UserInputErrorException { + Appointment foundAppointment = getAppointment(appointmentId); + if (foundAppointment == null) { + throw new UserInputErrorException("Appointment doesn't exist please try again!"); + } + CommandLineTable appointmentTable = new CommandLineTable(title); + appointmentTable.setShowVerticalLines(true); + appointmentTable.setHeaders("Appointment Id", "Patient Name", "Patient NRIC", "Doctor Name", "Doctor NRIC", + "Appointment Date", "Appointment Details"); + appointmentTable.addRow(foundAppointment.getAppointmentId(), foundAppointment.getPatientName(), + foundAppointment.getPatientNric(), foundAppointment.getDoctorName(), foundAppointment.getDoctorNric(), + foundAppointment.getAppointmentDate(), foundAppointment.getAppointmentDetails()); + appointmentTable.print(); + } + + public void findById(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentById(appointments, parameters[1]); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given ID doesn't exist. Please try again!"); + } + } + + public void findByPatientName(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentByPatientName(appointments, parameters[1]); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given patient name doesn't exist. Please try again!"); + } + } + + public void findByPatientNric(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentByPatientNric(appointments, (parameters[1])); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given patient nric doesn't exist. Please try again!"); + } + } + + public void findByDoctorName(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentByDoctorName(appointments, parameters[1]); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given doctor name doesn't exist. Please try again!"); + } + } + + public void findByDoctorNric(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentByDoctorNric(appointments, parameters[1]); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given doctor nric doesn't exist. Please try again!"); + } + } + + public void findByAppointmentDate(String[] parameters) { + try { + this.returnedFinderArray = AppointmentFinder.findAppointmentByDate(appointments, parameters[1]); + createArrayOfFoundAppointments(); + } catch (NullPointerException e) { + UI.printParagraph("Appointment with given date doesn't exist. Please try again!"); + } + } + + private void createArrayOfFoundAppointments() { + if (returnedFinderArray.isEmpty()) { + UI.printParagraph("Appointment doesn't exist please try again!"); + } else { + CommandLineTable findAppointmentTable = new CommandLineTable(title); + findAppointmentTable.setShowVerticalLines(true); + findAppointmentTable.setHeaders("Appointment Id", "Patient Nric", "Patient Name", "Doctor Nric", + "Doctor Name", "Appointment Date", "Appointment Details"); + for (int i = 0; i < returnedFinderArray.size(); i++) { + findAppointmentTable.addRow(returnedFinderArray.get(i).getAppointmentId(), + returnedFinderArray.get(i).getPatientNric(), + returnedFinderArray.get(i).getPatientName(), + returnedFinderArray.get(i).getDoctorNric(), + returnedFinderArray.get(i).getDoctorName(), + returnedFinderArray.get(i).getAppointmentDate(), + returnedFinderArray.get(i).getAppointmentDetails()); + } + findAppointmentTable.print(); + } + } + + + public boolean hasAppointmentToday(String type, String nric) throws NotFoundException, UserInputErrorException { + ArrayList foundAppointments; + switch (type) { + case "P": + foundAppointments = AppointmentFinder.findAppointmentByPatientNric(appointments, nric); + if (foundAppointments == null) { + throw new NotFoundException("Patient does not have an appointment today!"); + } + for (Appointment a : foundAppointments) { + LocalDate appointmentDate = LocalDate.parse(a.appointmentDate); + if (appointmentDate.equals(LocalDate.now())) { + return true; + } + } + throw new NotFoundException("Patient does not have an appointment today!"); + case "D": + foundAppointments = AppointmentFinder.findAppointmentByDoctorNric(appointments, nric); + for (Appointment a : foundAppointments) { + LocalDate appointmentDate = LocalDate.parse(a.appointmentDate); + if (appointmentDate.equals(LocalDate.now())) { + return true; + } + } + throw new NotFoundException("Doctor does not have an appointment today!"); + default: + assert false; + throw new UserInputErrorException("Error with code, approach developer!"); + } + } + + public void dispenseMedicine(String patientNric, String[] medicines) { + for (Appointment a : appointments) { + LocalDate appointmentDate = LocalDate.parse(a.appointmentDate); + if (appointmentDate.equals(LocalDate.now()) && a.patientNric.equals(patientNric)) { + for (int i = 0; i < medicines.length; i += 2) { + a.addMedicine(medicines[i], medicines[i + 1]); + } + break; + } + } + } + + public void loadMedicine(String[] parameters) { + String appointmentId = parameters[0]; + for (Appointment a : appointments) { + if (a.appointmentId.equals(appointmentId)) { + for (int i = 1; i < parameters.length; i += 2) { + a.addMedicine(parameters[i], parameters[i + 1]); + } + } + } + } +} + + diff --git a/src/main/java/seedu/duke/assets/Doctor.java b/src/main/java/seedu/duke/assets/Doctor.java new file mode 100644 index 0000000000..54103181ff --- /dev/null +++ b/src/main/java/seedu/duke/assets/Doctor.java @@ -0,0 +1,77 @@ +package seedu.duke.assets; + +import java.util.ArrayList; + +public class Doctor extends Person { + private String specialization; + public ArrayList appointmentDate = new ArrayList<>(); + + public Doctor(String nric, String fullName, int age, char gender, String address, + String dob, String specialization) { + super(nric, fullName, age, gender, address, dob); + this.specialization = specialization; + } + + public String getSpecialization() { + return specialization; + } + + + // @override toString() + + public void edit(String fullName, int age, char gender, String address, String dob, + String specialization) { + this.fullName = fullName; + this.age = age; + this.gender = gender; + this.address = address; + this.dob = dob; + this.specialization = specialization; + } + + public String saveString() { + return nric + "," + fullName + "," + age + "," + gender + "," + address + + "," + dob + "," + specialization; + } + + + public void addAppointmentDate(String date) { + appointmentDate.add(date); + } + + @Override + public String toString() { + return "Nric='" + getNric() + '\'' + + ", Full Name='" + getFullName() + '\'' + + ", Age=" + getAge() + + ", Address='" + getAddress() + + ", Gender=" + getGender() + + '\'' + ", DOB='" + getDob() + '\'' + + ", Specialization='" + getSpecialization() + '\''; + } + + public ArrayList appointmentDateDoctor() { + return appointmentDate; + } + + public String saveDateString() { + String returnString = ""; + for (int i = 0; i < appointmentDate.size(); i++) { + if (i != 0) { + returnString += "," + appointmentDate.get(i); + } else { + returnString += nric + "," + appointmentDate.get(i); + } + } + return returnString; + } + + public void removeAppointmentDate(String date) { + for (int i = 0; i < appointmentDate.size(); i++) { + if (appointmentDate.get(i).equals(date)) { + appointmentDate.remove(i); + break; + } + } + } +} diff --git a/src/main/java/seedu/duke/assets/DoctorList.java b/src/main/java/seedu/duke/assets/DoctorList.java new file mode 100644 index 0000000000..bd31062a6a --- /dev/null +++ b/src/main/java/seedu/duke/assets/DoctorList.java @@ -0,0 +1,270 @@ +package seedu.duke.assets; + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.CommandLineTable; +import seedu.duke.helper.UI; +import seedu.duke.helper.finder.DoctorFinder; + +import java.util.ArrayList; + + +public class DoctorList extends List { + + private ArrayList doctors = new ArrayList<>(); + private ArrayList returnedFinderArray = new ArrayList<>(); + private final String title = "Table of doctors"; + + + public Doctor getDoctor(String nric) { + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(nric)) { + return doctor; + } + } + return null; + } + + + public Doctor search(String nric) { + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(nric)) { + return doctor; + } + } + return null; + } + + public void find(String[] command) { + } + + public void add(String[] addDoctorParameters) throws DuplicateEntryException { + if (getDoctor(addDoctorParameters[0]) != null) { + throw new DuplicateEntryException("Doctor with given NRIC already exists!"); + } + Doctor newDoctor = new Doctor(addDoctorParameters[0], addDoctorParameters[1], + Integer.parseInt(addDoctorParameters[2]), + addDoctorParameters[3].charAt(0), addDoctorParameters[4], addDoctorParameters[5], + addDoctorParameters[6]); + doctors.add(newDoctor); + } + + //view all doctor + public void view() throws UserInputErrorException { + CommandLineTable doctorTable = new CommandLineTable(title); + doctorTable.setShowVerticalLines(true); + doctorTable.setHeaders("Nric", "FullName", "Age", "Address", "Gender", "Dob", + "Specialization"); + if (doctors.size() == 0) { + throw new UserInputErrorException("Doctor list is empty, please add doctor"); + } + for (Doctor doctor : doctors) { + doctorTable.addRow(doctor.getNric(), doctor.getFullName(), String.valueOf(doctor.getAge()), + doctor.getAddress(), String.valueOf(doctor.getGender()), doctor.getDob(), + doctor.getSpecialization()); + } + doctorTable.print(); + } + + //view particular doctor + public void view(String nric) throws UserInputErrorException { + Doctor doctor = getDoctor(nric); + if (doctor == null) { + throw new UserInputErrorException("Doctor doesn't exist please try again!"); + } + CommandLineTable doctorTable = new CommandLineTable(title); + doctorTable.setShowVerticalLines(true); + doctorTable.setHeaders("Nric", "FullName", "Age", "Address", "Gender", "Dob", + "Specialization"); + doctorTable.addRow(doctor.getNric(), doctor.getFullName(), String.valueOf(doctor.getAge()), + doctor.getAddress(), String.valueOf(doctor.getGender()), doctor.getDob(), + doctor.getSpecialization()); + doctorTable.print(); + } + + public void addAppointmentDate(String nric, String date) { + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(nric)) { + doctor.addAppointmentDate(date); + break; + } + } + } + + public void removeAppointmentDate(String nric, String date) { + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(nric)) { + doctor.removeAppointmentDate(date); + break; + } + } + } + + + public boolean hasDoctorDate(String nric, String date) throws DuplicateEntryException { + ArrayList doctorDateList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(nric)) { + doctorDateList = doctor.appointmentDateDoctor(); + for (String dateDoctor : doctorDateList) { + if (dateDoctor.equals(date)) { + return true; + } + return false; + } + return false; + } + } + throw new DuplicateEntryException("Doctor not found"); + } + + + + + public void edit(String[] parameterArray) throws NotFoundException { + if (search(parameterArray[0]) != null) { + Doctor doctor = search(parameterArray[0]); + doctor.edit(parameterArray[1], Integer.parseInt(parameterArray[2]), parameterArray[3].charAt(0), + (parameterArray[4]), parameterArray[5], parameterArray[6]); + return; + } + throw new NotFoundException("There are no doctors with given NRIC!"); + } + + + //get the number of doctors + public int getSize() { + return doctors.size(); + } + + //remove the specific doctor + public void remove(String nric) throws NotFoundException { + for (int i = 0; i < getSize(); i++) { + if (doctors.get(i).getNric().equals(nric)) { + doctors.remove(i); + return; + } + } + throw new NotFoundException("There are no doctors with given NRIC!"); + } + + @Override + public String toString() { + if (getSize() == 0) { + return "There are no doctors."; + } + String doctorName = ""; + int index = 1; + for (Doctor doctor : this.doctors) { + doctorName += String.format("%d. %s", index, doctor.toString()); + if (index != this.getSize()) { + doctorName += "\n"; + } + index++; + } + return doctorName; + } + + public ArrayList getList() { + return doctors; + } + + public void findByNric(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByNric(doctors, parameterArray[1]); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given NRIC doesn't exist. Please try again!"); + } + } + + public void findByName(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByName(doctors, parameterArray[1]); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given name doesn't exist. Please try again!"); + } + } + + public void findByAge(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByAge(doctors, Integer.parseInt(parameterArray[1])); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given age doesn't exist. Please try again!"); + } + } + + public void findByGender(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByGender(doctors, parameterArray[1].charAt(0)); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given gender doesn't exist. Please try again!"); + } + } + + public void findByAddress(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByAddress(doctors, parameterArray[1]); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given address doesn't exist. Please try again!"); + } + } + + public void findByDob(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorByDob(doctors, parameterArray[1]); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor doesn't exist please try again!"); + } + } + + public void findBySpecialization(String[] parameterArray) { + try { + this.returnedFinderArray = DoctorFinder.findDoctorBySpecialization(doctors, parameterArray[1]); + displayFoundDoctorList(); + } catch (NullPointerException e) { + UI.printParagraph("Doctor with given specialization doesn't exist. Please try again!"); + } + } + + private void displayFoundDoctorList() { + if (returnedFinderArray.isEmpty()) { + UI.printParagraph("Doctor doesn't exist please try again!"); + } else { + CommandLineTable findPatientTable = new CommandLineTable(title); + for (int i = 0; i < returnedFinderArray.size(); i++) { + + findPatientTable.setShowVerticalLines(true); + findPatientTable.setHeaders("Nric", "Full Name", "Age", "Address", "Gender", "Dob", + "Specialization"); + findPatientTable.addRow(returnedFinderArray.get(i).getNric(), + returnedFinderArray.get(i).getFullName(), + String.valueOf(returnedFinderArray.get(i).getAge()), + returnedFinderArray.get(i).getAddress(), + String.valueOf(returnedFinderArray.get(i).getGender()), + returnedFinderArray.get(i).getDob(), + returnedFinderArray.get(i).getSpecialization()); + } + findPatientTable.print(); + } + } + + public void loadDate(String[] parameters) { + String doctorNric = parameters[0]; + for (Doctor a : doctors) { + if (a.getNric().equals(doctorNric)) { + for (int i = 1; i < parameters.length; i++) { + a.addAppointmentDate(parameters[i]); + } + } + } + } + +} + diff --git a/src/main/java/seedu/duke/assets/ExpiryComparator.java b/src/main/java/seedu/duke/assets/ExpiryComparator.java new file mode 100644 index 0000000000..5aaf69b03a --- /dev/null +++ b/src/main/java/seedu/duke/assets/ExpiryComparator.java @@ -0,0 +1,12 @@ +package seedu.duke.assets; + +import java.util.Comparator; + +class ExpiryComparator implements Comparator { + + // override the compare() method + public int compare(Medicine m1, Medicine m2) { + return m1.getExpiry().compareTo(m2.getExpiry()); + } +} + diff --git a/src/main/java/seedu/duke/assets/List.java b/src/main/java/seedu/duke/assets/List.java new file mode 100644 index 0000000000..3f778f66da --- /dev/null +++ b/src/main/java/seedu/duke/assets/List.java @@ -0,0 +1,19 @@ +package seedu.duke.assets; + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.exception.UserInputErrorException; + +public abstract class List { + + public abstract void add(String[] parameters) throws DuplicateEntryException; + + public abstract void remove(String parameters) throws NotFoundException; + + public abstract void view() throws UserInputErrorException; + + public abstract void view(String parameter) throws UserInputErrorException; + + public abstract void edit(String[] parameters) throws NotFoundException; + +} diff --git a/src/main/java/seedu/duke/assets/Medicine.java b/src/main/java/seedu/duke/assets/Medicine.java new file mode 100644 index 0000000000..2f60c910e1 --- /dev/null +++ b/src/main/java/seedu/duke/assets/Medicine.java @@ -0,0 +1,58 @@ +package seedu.duke.assets; + +public class Medicine { + private String medicineId; + private String medicineName; + private int dosage; //in milligrams + private String expiry; + private String sideEffects; + protected int quantity; + + public Medicine(String medicineId, String medicineName, int dosage, String expiry, + String sideEffects, int quantity) { + this.medicineId = medicineId; + this.medicineName = medicineName; + this.dosage = dosage; + this.expiry = expiry; + this.sideEffects = sideEffects; + this.quantity = quantity; + } + + public void edit(String medicineName, int dosage, String expiry, + String sideEffects, int quantity) { + this.medicineName = medicineName; + this.dosage = dosage; + this.expiry = expiry; + this.sideEffects = sideEffects; + this.quantity = quantity; + } + + public String saveString() { + return medicineId + "," + medicineName + "," + dosage + "," + expiry + + "," + sideEffects + "," + quantity; + } + + public String getMedicineId() { + return medicineId; + } + + public String getMedicineName() { + return medicineName; + } + + public int getDosage() { + return dosage; + } + + public String getExpiry() { + return expiry; + } + + public String getSideEffects() { + return sideEffects; + } + + public int getQuantity() { + return quantity; + } +} diff --git a/src/main/java/seedu/duke/assets/MedicineList.java b/src/main/java/seedu/duke/assets/MedicineList.java new file mode 100644 index 0000000000..3c4630937d --- /dev/null +++ b/src/main/java/seedu/duke/assets/MedicineList.java @@ -0,0 +1,304 @@ +package seedu.duke.assets; + + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.UI; +import seedu.duke.helper.CommandLineTable; +import seedu.duke.helper.finder.MedicineFinder; + +import java.time.LocalDate; +import java.util.ArrayList; + +public class MedicineList extends List { + + private ArrayList medicines = new ArrayList<>(); + private ArrayList expiredMedicines = new ArrayList<>(); + private ArrayList returnedFinderArray = new ArrayList<>(); + private final String title = "Table of medicines"; + + public int getSize() { + return medicines.size(); + } + + public Medicine getMedicine(String medicineId) { + for (Medicine medicine : medicines) { + if (medicine.getMedicineId().equals(medicineId)) { + return medicine; + } + } + return null; + } + + public Medicine search(String medicineId) { + for (Medicine medicine : medicines) { + if (medicine.getMedicineId().equals(medicineId)) { + return medicine; + } + } + return null; + } + + public void add(String[] parameterArray) throws DuplicateEntryException { + if (search(parameterArray[0]) != null) { + throw new DuplicateEntryException("Medicine with given Batch ID already exists!"); + } + Medicine newMedicine = new Medicine(parameterArray[0], parameterArray[1], + Integer.parseInt(parameterArray[2]), parameterArray[3], parameterArray[4], + Integer.parseInt(parameterArray[5])); + medicines.add(newMedicine); + } + + public void find(String[] command) { + } + + public String getMedicineInfo(Medicine medicine) { + return (medicine.getMedicineId() + ": " + + medicine.getMedicineName() + ", " + + Integer.toString(medicine.getDosage()) + ", " + medicine.getExpiry() + ", " + + medicine.getSideEffects() + ", " + Integer.toString(medicine.getQuantity())); + } + + + //view particular medicine + public void view(String medicineId) throws UserInputErrorException { + Medicine medicine = getMedicine(medicineId); + if (medicine == null) { + throw new UserInputErrorException("Medicine doesn't exist please try again!"); + } + CommandLineTable medicineTable = new CommandLineTable(title); + medicineTable.setShowVerticalLines(true); + medicineTable.setHeaders("MedicineId", "MedicineName", "Dosage", "Expiry", "SideEffects", "Quantity"); + medicineTable.addRow(medicine.getMedicineId(), medicine.getMedicineName(), + String.valueOf(medicine.getDosage()), + medicine.getExpiry(), medicine.getSideEffects(), String.valueOf(medicine.getQuantity())); + medicineTable.print(); + } + + public void view() throws UserInputErrorException { + CommandLineTable medicineTable = new CommandLineTable(title); + medicineTable.setShowVerticalLines(true); + medicineTable.setHeaders("MedicineId", "MedicineName", "Dosage", "Expiry", "SideEffects", "Quantity"); + + if (medicines.size() == 0) { + throw new UserInputErrorException("Medicine list is empty, please add medicine"); + } + for (Medicine medicine : medicines) { + medicineTable.addRow(medicine.getMedicineId(), medicine.getMedicineName(), + String.valueOf(medicine.getDosage()), + medicine.getExpiry(), medicine.getSideEffects(), + String.valueOf(medicine.getQuantity())); + } + medicineTable.print(); + } + + + public void remove(String medicineId) throws NotFoundException { + for (int i = 0; i < getSize(); i++) { + if (medicines.get(i).getMedicineId().equals(medicineId)) { + medicines.remove(i); + return; + } + } + throw new NotFoundException("There are no medicines with given Batch ID!"); + } + + public void edit(String[] parameterArray) throws NotFoundException { + if (search(parameterArray[0]) != null) { + Medicine medicine = search(parameterArray[0]); + medicine.edit(parameterArray[1], Integer.parseInt(parameterArray[2]), parameterArray[3], parameterArray[4], + Integer.parseInt(parameterArray[5])); + return; + } + throw new NotFoundException("There are no medicines with given Batch ID!"); + } + + public void viewExpired() throws UserInputErrorException { + CommandLineTable medicineTable = new CommandLineTable("Table of expired medicine"); + medicineTable.setShowVerticalLines(true); + medicineTable.setHeaders("MedicineId", "MedicineName", "Dosage", "Expiry", "SideEffects", "Quantity"); + if (expiredMedicines.size() == 0) { + throw new UserInputErrorException("There are no expired medicines."); + } + for (Medicine medicine : expiredMedicines) { + medicineTable.addRow(medicine.getMedicineId(), medicine.getMedicineName(), + String.valueOf(medicine.getDosage()), + medicine.getExpiry(), medicine.getSideEffects(), + String.valueOf(medicine.getQuantity())); + } + medicineTable.print(); + } + + public void updateStock() throws UserInputErrorException { + for (int i = 0; i < medicines.size(); i++) { + LocalDate date = LocalDate.parse(medicines.get(i).getExpiry()); + int quantity = medicines.get(i).getQuantity(); + LocalDate today = LocalDate.now(); + if (date.isBefore(today) || quantity == 0) { + expiredMedicines.add(medicines.get(i)); + medicines.remove(i); + } + } + viewExpired(); + } + + public void updateStockBackend() { + for (int i = 0; i < medicines.size(); i++) { + LocalDate date = LocalDate.parse(medicines.get(i).getExpiry()); + int quantity = medicines.get(i).getQuantity(); + LocalDate today = LocalDate.now(); + if (date.isBefore(today) || quantity == 0) { + expiredMedicines.add(medicines.get(i)); + medicines.remove(i); + } + } + } + + public void clearStock() { + if (expiredMedicines.size() == 0) { + UI.printParagraph("There are no expired medicines in the expired list!"); + return; + } + expiredMedicines.clear(); + UI.printParagraph("Expired medicines in the expired list has been cleared!"); + } + + public void checkStock(String [] medicines) throws UserInputErrorException { + updateStockBackend(); + CommandLineTable medicineTable = new CommandLineTable("Table of missing medicines"); + medicineTable.setShowVerticalLines(true); + medicineTable.setHeaders("MedicineName", "Quantity"); + + boolean hasShortage = false; + + for (int i = 0; i < medicines.length; i += 2) { + String medicineName = medicines[i]; + int quantity = Integer.parseInt(medicines[i + 1]); + for (Medicine a : this.medicines) { + if (a.getMedicineName().equals(medicineName)) { + quantity -= a.getQuantity(); + if (quantity <= 0) { + break; + } + } + } + if (quantity > 0) { + medicineTable.addRow(medicineName,medicines[i + 1]); + hasShortage = true; + } + } + + if (hasShortage) { + medicineTable.print(); + throw new UserInputErrorException("The medicines mentioned on the table" + + " above do not have enough stock to dispense!"); + } + } + + public ArrayList getList() { + return medicines; + } + + public void findById(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineById(medicines, parameters[1]); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given id doesn't exist. Please try again!"); + } + } + + public void findByDosage(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineByDosage(medicines, Integer.parseInt(parameters[1])); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given dosage doesn't exist. Please try again!"); + } + } + + public void findByExpiry(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineByExpiry(medicines, parameters[1]); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given expiry doesn't exist. Please try again!"); + } + } + + public void findBySideEffects(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineBySideEffects(medicines, parameters[1]); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given side effects doesn't exist. Please try again!"); + } + } + + public void findByQuantity(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineByQuantity(medicines, + Integer.parseInt(parameters[1])); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given quantity doesn't exist. Please try again!"); + } + } + + public void findByName(String[] parameters) { + try { + this.returnedFinderArray = MedicineFinder.findMedicineByName(medicines, parameters[1]); + createArrayOfFoundMedicines(); + } catch (NullPointerException e) { + UI.printParagraph("Medicine with given name doesn't exist. Please try again!"); + } + } + + + private void createArrayOfFoundMedicines() { + if (returnedFinderArray.isEmpty()) { + UI.printParagraph("Medicine doesn't exist please try again!"); + } else { + CommandLineTable findMedicineTable = new CommandLineTable(title); + for (int i = 0; i < returnedFinderArray.size(); i++) { + findMedicineTable.setShowVerticalLines(true); + findMedicineTable.setHeaders("MedicineId", "MedicineName", "Dosage", "Expiry", + "SideEffects", "Quantity"); + findMedicineTable.addRow(returnedFinderArray.get(i).getMedicineId(), + returnedFinderArray.get(i).getMedicineName(), + String.valueOf(returnedFinderArray.get(i).getDosage()), + returnedFinderArray.get(i).getExpiry(), returnedFinderArray.get(i).getSideEffects(), + String.valueOf(returnedFinderArray.get(i).getQuantity())); + + } + findMedicineTable.print(); + } + } + + public void dispenseMedicine(String[] medicineArray) { + CommandLineTable medicineTable = new CommandLineTable("Table of medicines to dispense"); + medicineTable.setShowVerticalLines(true); + medicineTable.setHeaders("MedicineId", "MedicineName", "Expiry", "Quantity"); + medicines.sort(new ExpiryComparator()); + for (int i = 0; i < medicineArray.length; i += 2) { + String medicineName = medicineArray[i]; + int quantity = Integer.parseInt(medicineArray[i + 1]); + for (Medicine a : this.medicines) { + if (a.getMedicineName().equals(medicineName)) { + int quantityTaken = (quantity > a.getQuantity()) ? a.getQuantity() : quantity; + quantity = (quantity > quantityTaken) ? quantity - quantityTaken : 0; + a.quantity = (a.getQuantity() > quantityTaken) ? a.getQuantity() - quantityTaken : 0; + + medicineTable.addRow(a.getMedicineId(), a.getMedicineName(), a.getExpiry(), + String.valueOf(quantityTaken)); + } + if (quantity == 0) { + break; + } + } + } + medicineTable.print(); + } +} + diff --git a/src/main/java/seedu/duke/assets/Patient.java b/src/main/java/seedu/duke/assets/Patient.java new file mode 100644 index 0000000000..26056f2948 --- /dev/null +++ b/src/main/java/seedu/duke/assets/Patient.java @@ -0,0 +1,92 @@ +package seedu.duke.assets; + +import java.util.ArrayList; + +public class Patient extends Person { + String dateAdmission; + protected ArrayList appointmentDate = new ArrayList<>(); + + public Patient(String nric, String fullName, int age, char gender, String address, String dob, + String dateAdmission) { + super(nric, fullName, age, gender, address, dob); + this.dateAdmission = dateAdmission; + } + + public String getDateAdmission() { + return dateAdmission; + } + + public void edit(String fullName, int age, char gender, String address, String dob, + String dateAdmission) { + this.fullName = fullName; + this.age = age; + this.gender = gender; + this.address = address; + this.dob = dob; + this.dateAdmission = dateAdmission; + } + + public String getPatientNric() { + return nric; + } + + public String getPatientName() { + return fullName; + } + + public int getPatientAge() { + return age; + } + + public char getPatientGender() { + return gender; + } + + public String getPatientAddress() { + return address; + } + + public String getPatientDob() { + return dob; + } + + public String getDateOfAdmission() { + return dateAdmission; + } + + + + public void addAppointmentDate(String date) { + appointmentDate.add(date); + } + + public String saveString() { + return nric + "," + fullName + "," + age + "," + gender + "," + address + + "," + dob + "," + dateAdmission; + } + + public ArrayList appointmentDate() { + return appointmentDate; + } + + public String saveDateString() { + String returnString = ""; + for (int i = 0; i < appointmentDate.size(); i++) { + if (i != 0) { + returnString += "," + appointmentDate.get(i); + } else { + returnString += nric + "," + appointmentDate.get(i); + } + } + return returnString; + } + + public void removeAppointmentDate(String date) { + for (int i = 0; i < appointmentDate.size(); i++) { + if (appointmentDate.get(i).equals(date)) { + appointmentDate.remove(i); + break; + } + } + } +} diff --git a/src/main/java/seedu/duke/assets/PatientList.java b/src/main/java/seedu/duke/assets/PatientList.java new file mode 100644 index 0000000000..9437fec9eb --- /dev/null +++ b/src/main/java/seedu/duke/assets/PatientList.java @@ -0,0 +1,281 @@ +package seedu.duke.assets; + +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.CommandLineTable; +import seedu.duke.helper.UI; +import seedu.duke.helper.finder.PatientFinder; + +import java.util.ArrayList; + + +public class PatientList extends List { + + private ArrayList patients = new ArrayList<>(); + private ArrayList returnedFinderArray = new ArrayList<>(); + ArrayList patientDateList = new ArrayList<>(); + private final String title = "Table of patients"; + + + public Patient getPatient(String nric) { + for (Patient patient : patients) { + if (patient.getNric().equals(nric)) { + return patient; + } + } + return null; + } + + + public Patient search(String nric) { + for (Patient patient : patients) { + if (patient.getPatientNric().equals(nric)) { + return patient; + } + } + return null; + } + + public void add(String[] addPatientParameters) throws DuplicateEntryException { + final int numberOfPatientsBefore = patients.size(); + if (getPatient(addPatientParameters[0]) != null) { + throw new DuplicateEntryException("Patient with given NRIC already exists!"); + } + Patient newPatient = new Patient(addPatientParameters[0], addPatientParameters[1], + Integer.parseInt(addPatientParameters[2]), + addPatientParameters[3].charAt(0), addPatientParameters[4], addPatientParameters[5], + addPatientParameters[6]); + patients.add(newPatient); + assert patients.size() == numberOfPatientsBefore + 1; + } + + public String getPatientInfo(Patient patient) { + return (patient.getPatientNric() + ": " + + patient.getPatientName() + ", " + + Integer.toString(patient.getPatientAge()) + ", " + patient.getPatientAddress() + + ", " + patient.getPatientGender() + ", " + patient.getPatientDob() + + ", " + patient.getDateOfAdmission()); + } + + public int getSize() { + return patients.size(); + } + + //view particular patient + public void view(String nric) throws UserInputErrorException { + Patient patient = getPatient(nric); + if (patient == null) { + throw new UserInputErrorException("Patient doesn't exist please try again!"); + } + + CommandLineTable patientTable = new CommandLineTable(title); + patientTable.setShowVerticalLines(true);//if false (default) then no vertical lines are shown + patientTable.setHeaders("Nric", "Full Name", "Age", "Address", "Gender", "Dob", + "Registration Date"); + + patientTable.addRow(patient.getPatientNric(), patient.getPatientName(), + String.valueOf(patient.getPatientAge()), + patient.getPatientAddress(), String.valueOf(patient.getPatientGender()), + patient.getPatientDob(), + patient.getDateOfAdmission()); + patientTable.print(); + } + + + //view all patients + public void view() throws UserInputErrorException { + + CommandLineTable patientTable = new CommandLineTable(title); + patientTable.setShowVerticalLines(true);//if false (default) then no vertical lines are shown + patientTable.setHeaders("Nric", "Full Name", "Age", "Address", "Gender", "Dob", + "Registration Date"); + + if (patients.size() == 0) { + throw new UserInputErrorException("Patient list is empty, please add patient"); + } + for (Patient patient : patients) { + patientTable.addRow(patient.getPatientNric(), patient.getPatientName(), + String.valueOf(patient.getPatientAge()), + patient.getPatientAddress(), String.valueOf(patient.getPatientGender()), + patient.getPatientDob(), + patient.getDateOfAdmission()); + } + patientTable.print(); + } + + public void addAppointmentDate(String nric, String date) { + for (Patient patient : patients) { + if (patient.getPatientNric().equals(nric)) { + patient.addAppointmentDate(date); + break; + } + } + } + + public void removeAppointmentDate(String nric, String date) { + for (Patient patient : patients) { + if (patient.getPatientNric().equals(nric)) { + patient.removeAppointmentDate(date); + break; + } + } + } + + public boolean hasPatientDate(String nric, String date) throws DuplicateEntryException { + for (Patient patient : patients) { + if (patient.getNric().equals(nric)) { + patientDateList = patient.appointmentDate(); + for (String datePatient : patientDateList) { + if (datePatient.equals(date)) { + return true; + } + return false; + } + return false; + } + } + throw new DuplicateEntryException("Patient not found"); + } + + public void remove(String nric) throws NotFoundException { + int numberOfPatientsBefore = patients.size(); + for (int i = 0; i < getSize(); i++) { + if (patients.get(i).getNric().equals(nric)) { + patients.remove(i); + assert patients.size() == numberOfPatientsBefore - 1; + return; + } + } + throw new NotFoundException("There are no patients with given NRIC!"); + } + + public void edit(String[] parameterArray) throws NotFoundException { + if (search(parameterArray[0]) != null) { + Patient patient = search(parameterArray[0]); + patient.edit(parameterArray[1], Integer.parseInt(parameterArray[2]), parameterArray[3].charAt(0), + parameterArray[4], parameterArray[5], parameterArray[6]); + return; + } + throw new NotFoundException("There are no patients with given NRIC!"); + } + + public ArrayList getList() { + return patients; + } + + @Override + public String toString() { + if (getSize() == 0) { + return "There are no patients currently."; + } + String output = ""; + int number = 1; + for (Patient patient : this.patients) { + output += String.format("%d. %s", number, patient.toString()); + if (number != this.getSize()) { + output += "\n"; + } + number++; + } + assert !output.isEmpty(); + return output; + } + + public void findByNric(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByNric(patients, parameters[1]); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given NRIC doesn't exist. Please try again!"); + } + } + + public void findByName(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByName(patients, parameters[1]); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given name doesn't exist. Please try again!"); + } + } + + public void findByAge(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByAge(patients, Integer.parseInt(parameters[1])); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given age doesn't exist. Please try again!"); + } + } + + public void findByGender(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByGender(patients, parameters[1].charAt(0)); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given gender doesn't exist. Please try again!"); + } + } + + public void findByAddress(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByAddress(patients, parameters[1]); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given address doesn't exist. Please try again!"); + } + } + + public void findByDob(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByDob(patients, parameters[1]); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given DOB doesn't exist. Please try again!"); + } + } + + public void findByDateAdmission(String[] parameters) { + try { + this.returnedFinderArray = PatientFinder.findPatientByDateAdmission(patients, parameters[1]); + displayFoundPatientList(); + } catch (NullPointerException e) { + UI.printParagraph("Patient with given registration date doesn't exist. Please try again!"); + } + } + + private void displayFoundPatientList() { + if (returnedFinderArray.isEmpty()) { + UI.printParagraph("Patient doesn't exist please try again!"); + } else { + CommandLineTable findPatientTable = new CommandLineTable(title); + for (int i = 0; i < returnedFinderArray.size(); i++) { + + findPatientTable.setShowVerticalLines(true); + findPatientTable.setHeaders("Nric", "Full Name", "Age", "Address", "Gender", "Dob", + "Registration Date"); + findPatientTable.addRow(returnedFinderArray.get(i).getNric(), + returnedFinderArray.get(i).getFullName(), + String.valueOf(returnedFinderArray.get(i).getAge()), + returnedFinderArray.get(i).getAddress(), + String.valueOf(returnedFinderArray.get(i).getGender()), + returnedFinderArray.get(i).getDob(), + returnedFinderArray.get(i).getDateAdmission()); + } + findPatientTable.print(); + } + } + + public void loadDate(String[] parameters) { + String patientNric = parameters[0]; + for (Patient a : patients) { + if (a.getNric().equals(patientNric)) { + for (int i = 1; i < parameters.length; i++) { + a.addAppointmentDate(parameters[i]); + } + } + } + } +} + diff --git a/src/main/java/seedu/duke/assets/Person.java b/src/main/java/seedu/duke/assets/Person.java new file mode 100644 index 0000000000..d5f3459ad8 --- /dev/null +++ b/src/main/java/seedu/duke/assets/Person.java @@ -0,0 +1,43 @@ +package seedu.duke.assets; + +public abstract class Person { + protected String nric; + protected String fullName; + protected int age; + protected String address; + protected char gender; + protected String dob; + + public Person(String nric, String fullName, int age, char gender, String address, String dob) { + this.nric = nric; + this.fullName = fullName; + this.age = age; + this.address = address; + this.gender = gender; + this.dob = dob; + } + + public String getNric() { + return nric; + } + + public String getFullName() { + return fullName; + } + + public int getAge() { + return age; + } + + public char getGender() { + return gender; + } + + public String getAddress() { + return address; + } + + public String getDob() { + return dob; + } +} diff --git a/src/main/java/seedu/duke/exception/DuplicateEntryException.java b/src/main/java/seedu/duke/exception/DuplicateEntryException.java new file mode 100644 index 0000000000..92a09fa8b5 --- /dev/null +++ b/src/main/java/seedu/duke/exception/DuplicateEntryException.java @@ -0,0 +1,9 @@ +package seedu.duke.exception; + +public class DuplicateEntryException extends HalpmiException { + + public DuplicateEntryException(String message) { + super(message); + } + +} diff --git a/src/main/java/seedu/duke/exception/HalpmiException.java b/src/main/java/seedu/duke/exception/HalpmiException.java new file mode 100644 index 0000000000..a3e1237fc3 --- /dev/null +++ b/src/main/java/seedu/duke/exception/HalpmiException.java @@ -0,0 +1,13 @@ +package seedu.duke.exception; + +public class HalpmiException extends Exception { + public HalpmiException(String message) { + super(message); + } + + @Override + public String toString() { + return getMessage(); + } +} + diff --git a/src/main/java/seedu/duke/exception/NotFoundException.java b/src/main/java/seedu/duke/exception/NotFoundException.java new file mode 100644 index 0000000000..87e3608b8e --- /dev/null +++ b/src/main/java/seedu/duke/exception/NotFoundException.java @@ -0,0 +1,10 @@ +package seedu.duke.exception; + +public class NotFoundException extends HalpmiException { + + public NotFoundException(String message) { + super(message); + } + + +} diff --git a/src/main/java/seedu/duke/exception/UserInputErrorException.java b/src/main/java/seedu/duke/exception/UserInputErrorException.java new file mode 100644 index 0000000000..84088691f7 --- /dev/null +++ b/src/main/java/seedu/duke/exception/UserInputErrorException.java @@ -0,0 +1,8 @@ +package seedu.duke.exception; + +public class UserInputErrorException extends HalpmiException { + public UserInputErrorException(String message) { + super(message); + } + +} diff --git a/src/main/java/seedu/duke/helper/CommandLineTable.java b/src/main/java/seedu/duke/helper/CommandLineTable.java new file mode 100644 index 0000000000..e6e47f567b --- /dev/null +++ b/src/main/java/seedu/duke/helper/CommandLineTable.java @@ -0,0 +1,89 @@ +package seedu.duke.helper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class CommandLineTable { + private static final String HORIZONTAL_SEP = "-"; + private String verticalSep; + private String joinSep; + private String[] headers; + private List rows = new ArrayList<>(); + private boolean rightAlign; + private String title; + + public CommandLineTable(String title) { + this.title = title; + setShowVerticalLines(false); + } + + public void setRightAlign(boolean rightAlign) { + this.rightAlign = rightAlign; + } + + public void setShowVerticalLines(boolean showVerticalLines) { + verticalSep = showVerticalLines ? "|" : ""; + joinSep = showVerticalLines ? "+" : " "; + } + + public void setHeaders(String... headers) { + this.headers = headers; + } + + public void addRow(String... cells) { + rows.add(cells); + } + + public void print() { + int[] maxWidths = headers != null + ? Arrays.stream(headers).mapToInt(String::length).toArray() : null; + + for (String[] cells : rows) { + if (maxWidths == null) { + maxWidths = new int[cells.length]; + } + if (cells.length != maxWidths.length) { + throw new IllegalArgumentException("Number of row-cells and headers should be consistent"); + } + for (int i = 0; i < cells.length; i++) { + maxWidths[i] = Math.max(maxWidths[i], cells[i].length()); + } + } + System.out.println(title); + if (headers != null) { + printLine(maxWidths); + printRow(headers, maxWidths); + printLine(maxWidths); + } + for (String[] cells : rows) { + printRow(cells, maxWidths); + } + if (headers != null) { + printLine(maxWidths); + } + } + + private void printLine(int[] columnWidths) { + for (int i = 0; i < columnWidths.length; i++) { + String line = String.join("", Collections.nCopies(columnWidths[i] + + verticalSep.length() + 1, HORIZONTAL_SEP)); + System.out.print(joinSep + line + (i == columnWidths.length - 1 ? joinSep : "")); + } + System.out.println(); + } + + private void printRow(String[] cells, int[] maxWidths) { + for (int i = 0; i < cells.length; i++) { + String s = cells[i]; + String verStrTemp = i == cells.length - 1 ? verticalSep : ""; + if (rightAlign) { + System.out.printf("%s %" + maxWidths[i] + "s %s", verticalSep, s, verStrTemp); + } else { + System.out.printf("%s %-" + maxWidths[i] + "s %s", verticalSep, s, verStrTemp); + } + } + System.out.println(); + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/helper/IdGenerator.java b/src/main/java/seedu/duke/helper/IdGenerator.java new file mode 100644 index 0000000000..aee6fad563 --- /dev/null +++ b/src/main/java/seedu/duke/helper/IdGenerator.java @@ -0,0 +1,10 @@ +package seedu.duke.helper; + +public class IdGenerator { + public static String createAppointmentId(String patientNric, String doctorNric, String appointmentDate) { + String patientNricCode = patientNric.substring(1,4) + patientNric.substring(5,8); + String doctorNricCode = doctorNric.substring(2,6); + String appointmentDateCode = appointmentDate.replace("-","").substring(4,8); + return patientNricCode + appointmentDateCode + doctorNricCode; + } +} diff --git a/src/main/java/seedu/duke/helper/Parser.java b/src/main/java/seedu/duke/helper/Parser.java new file mode 100644 index 0000000000..7ccacf34dd --- /dev/null +++ b/src/main/java/seedu/duke/helper/Parser.java @@ -0,0 +1,223 @@ +package seedu.duke.helper; + +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.helper.command.AddAppointmentCommand; +import seedu.duke.helper.command.AddDoctorCommand; +import seedu.duke.helper.command.AddMedicineCommand; +import seedu.duke.helper.command.AddPatientCommand; +import seedu.duke.helper.command.CheckIfAppointmentTodayCommand; +import seedu.duke.helper.command.CheckIfDoctorExistsCommand; +import seedu.duke.helper.command.CheckIfPatientExistsCommand; +import seedu.duke.helper.command.ClearExpiredMedicineCommand; +import seedu.duke.helper.command.Command; +import seedu.duke.helper.command.DeleteAppointmentCommand; +import seedu.duke.helper.command.DeleteDoctorCommand; +import seedu.duke.helper.command.DeleteMedicineCommand; +import seedu.duke.helper.command.DeletePatientCommand; +import seedu.duke.helper.command.DispenseMedicineCommand; +import seedu.duke.helper.command.EditAppointmentCommand; +import seedu.duke.helper.command.EditDoctorCommand; +import seedu.duke.helper.command.EditMedicineCommand; +import seedu.duke.helper.command.EditPatientCommand; +import seedu.duke.helper.command.FindAppointmentCommand; +import seedu.duke.helper.command.FindDoctorCommand; +import seedu.duke.helper.command.FindMedicineCommand; +import seedu.duke.helper.command.FindPatientCommand; +import seedu.duke.helper.command.CheckForMedicineStockCommand; +import seedu.duke.helper.command.UpdateMedicineInventoryCommand; +import seedu.duke.helper.command.ViewAppointmentCommand; +import seedu.duke.helper.command.ViewDoctorCommand; +import seedu.duke.helper.command.ViewMedicineCommand; +import seedu.duke.helper.command.ViewPatientCommand; + + +public class Parser { + public static String[] commandParser(String userInput) { + return userInput.trim().split("/info"); + } + + private static String[] stringSplitter(String parameters) throws UserInputErrorException { + try { + String[] parametersArray = parameters.split(","); + for (int i = 0; i < parametersArray.length; i++) { + parametersArray[i] = parametersArray[i].trim(); + } + return parametersArray; + } catch (Exception e) { + throw new UserInputErrorException("There is one or more parameters missing"); + } + } + + private static boolean isNull(String string) { + return string == null; + } + + public static Command parseAddPatient(String parameters) throws UserInputErrorException { + String[] addPatientParameters = stringSplitter(parameters); + Validator.validateAddPatient(addPatientParameters); + return new AddPatientCommand(addPatientParameters); + } + + public static Command parseDeletePatient(String parameters) throws UserInputErrorException { + String[] deletePatientParameters = stringSplitter(parameters); + Validator.validateNric(parameters); + return new DeletePatientCommand(deletePatientParameters); + } + + public static Command parseViewPatient(String parameters) throws UserInputErrorException { + if (isNull(parameters)) { + return new ViewPatientCommand(null); + } + return parseFindPatient(parameters); + } + + public static Command parseEditPatient(String parameters) throws UserInputErrorException { + String[] patientParameters = stringSplitter(parameters); + Validator.validateAddPatient(patientParameters); + return new EditPatientCommand(patientParameters); + } + + public static Command parseAddDoctor(String parameters) throws UserInputErrorException { + String[] addDoctorParameters = stringSplitter(parameters); + Validator.validateAddDoctor(addDoctorParameters); + return new AddDoctorCommand(addDoctorParameters); + } + + public static Command parseDeleteDoctor(String parameters) throws UserInputErrorException { + String[] deleteDoctorParameters = stringSplitter(parameters); + Validator.validateNric(parameters); + return new DeleteDoctorCommand(deleteDoctorParameters); + } + + public static Command parseViewDoctor(String parameters) throws UserInputErrorException { + if (isNull(parameters)) { + return new ViewDoctorCommand(null); + } + return parseFindDoctor(parameters); + } + + public static Command parseEditDoctor(String parameters) throws UserInputErrorException { + String[] doctorParameters = stringSplitter(parameters); + Validator.validateAddDoctor(doctorParameters); + return new EditDoctorCommand(doctorParameters); + } + + + public static Command parseAddMedicine(String parameters) throws UserInputErrorException { + String[] medicineParameters = stringSplitter(parameters); + Validator.validateMedicine(medicineParameters); + return new AddMedicineCommand(medicineParameters); + } + + public static Command parseDeleteMedicine(String parameters) throws UserInputErrorException { + String[] deleteMedicineParameters = stringSplitter(parameters); + if (deleteMedicineParameters.length != 1) { + throw new UserInputErrorException("Delete medicine only takes in one parameter"); + } + return new DeleteMedicineCommand(deleteMedicineParameters); + } + + public static Command parseViewMedicine(String parameters) throws UserInputErrorException { + if (isNull(parameters)) { + return new ViewMedicineCommand(null); + } + return parseFindMedicine(parameters); + } + + public static Command parseEditMedicine(String parameters) throws UserInputErrorException { + String[] medicineParameters = stringSplitter(parameters); + Validator.validateMedicine(medicineParameters); + return new EditMedicineCommand(medicineParameters); + } + + public static Command parseUpdateMedicineStock(String parameters) throws UserInputErrorException { + if (!isNull(parameters)) { + throw new UserInputErrorException("The update medicines command does not take in any parameters!"); + } + return new UpdateMedicineInventoryCommand(); + } + + public static Command parseClearExpiredMedicine(String parameters) throws UserInputErrorException { + if (!isNull(parameters)) { + throw new UserInputErrorException("The clear old medicines command does not take in any parameters!"); + } + return new ClearExpiredMedicineCommand(); + } + + public static Command parseDispenseMedicine(String parameters) throws UserInputErrorException { + String[] dispenseMedicineParameters = stringSplitter(parameters); + Validator.validateDispenseMedicine(dispenseMedicineParameters); + return new DispenseMedicineCommand(dispenseMedicineParameters); + } + + public static Command parseCheckMedicineStock(String parameters) throws UserInputErrorException { + String[] retrieveMedicineParameters = stringSplitter(parameters); + return new CheckForMedicineStockCommand(retrieveMedicineParameters); + } + + public static Command parseCheckForPatientAppointment(String parameters) throws UserInputErrorException { + String[] checkForPatientAppointmentParameters = stringSplitter(parameters); + return new CheckIfAppointmentTodayCommand(checkForPatientAppointmentParameters); + } + + public static Command parseAddAppointment(String parameters) throws UserInputErrorException { + String[] addAppointmentParameters = stringSplitter(parameters); + Validator.validateAddAppointment(addAppointmentParameters); + return new AddAppointmentCommand(addAppointmentParameters); + } + + public static Command checkIfPatientExists(String parameters) throws UserInputErrorException { + String[] checkIfPatientExistsParameters = stringSplitter(parameters); + Validator.validateAddAppointment(checkIfPatientExistsParameters); + return new CheckIfPatientExistsCommand(checkIfPatientExistsParameters); + } + + public static Command checkIfDoctorExists(String parameters) throws UserInputErrorException { + String[] checkIfDoctorExistsParameters = stringSplitter(parameters); + Validator.validateAddAppointment(checkIfDoctorExistsParameters); + return new CheckIfDoctorExistsCommand(checkIfDoctorExistsParameters); + } + + + public static Command parseViewAppointment(String parameters) throws UserInputErrorException { + if (isNull(parameters)) { + return new ViewAppointmentCommand(null); + } + return parseFindAppointment(parameters); + } + + public static Command parseFindAppointment(String parameters) throws UserInputErrorException { + String[] findAppointmentParameters = stringSplitter(parameters); + Validator.validateFindAppointment(findAppointmentParameters); + return new FindAppointmentCommand(findAppointmentParameters); + } + + public static Command parseEditAppointment(String parameters) throws UserInputErrorException { + String[] editAppointmentParameters = stringSplitter(parameters); + Validator.validateEditAppointment(editAppointmentParameters); + return new EditAppointmentCommand(editAppointmentParameters); + } + + public static Command parseFindDoctor(String parameters) throws UserInputErrorException { + String[] findDoctorParameters = stringSplitter(parameters); + Validator.validateFindDoctor(findDoctorParameters); + return new FindDoctorCommand(findDoctorParameters); + } + + public static Command parseFindPatient(String parameters) throws UserInputErrorException { + String[] findPatientParameters = stringSplitter(parameters); + Validator.validateFindPatient(findPatientParameters); + return new FindPatientCommand(findPatientParameters); + } + + public static Command parseFindMedicine(String parameters) throws UserInputErrorException { + String[] findMedicineParameters = stringSplitter(parameters); + Validator.validateFindMedicine(findMedicineParameters); + return new FindMedicineCommand(findMedicineParameters); + } + + public static Command parseDeleteAppointment(String parameters) throws UserInputErrorException { + String[] deleteAppointmentParameters = stringSplitter(parameters); + return new DeleteAppointmentCommand(deleteAppointmentParameters); + } +} diff --git a/src/main/java/seedu/duke/helper/Storage.java b/src/main/java/seedu/duke/helper/Storage.java new file mode 100644 index 0000000000..0aaaa53ffa --- /dev/null +++ b/src/main/java/seedu/duke/helper/Storage.java @@ -0,0 +1,309 @@ +package seedu.duke.helper; + +import seedu.duke.assets.Appointment; +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.Doctor; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.List; +import seedu.duke.assets.Medicine; +import seedu.duke.assets.MedicineList; +import seedu.duke.assets.Patient; +import seedu.duke.assets.PatientList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; + + + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Scanner; + +public class Storage { + static final String DIR = "data"; + static final String PATH_DOC = "data/doctor.txt"; + static final String PATH_PAT = "data/patient.txt"; + static final String PATH_MED = "data/medicine.txt"; + static final String PATH_APT = "data/appointment.txt"; + static final String PATH_APT_MEDS = "data/appointment_meds.txt"; + static final String PATH_DOC_DATE = "data/doctor_date.txt"; + static final String PATH_PAT_DATE = "data/patient_date.txt"; + public DoctorList doctors = new DoctorList(); + public PatientList patients = new PatientList(); + public MedicineList medicines = new MedicineList(); + public AppointmentList appointments = new AppointmentList(patients, doctors); + + public Storage() { + loadData(); + } + + ArrayList corruptedLines = new ArrayList<>(); + + private void loadGenericData(String filePath, List listType) throws FileNotFoundException { + File data = new File(filePath); + Scanner reader = new Scanner(data); + String outputFilePathCorrupted = "nope"; + while (reader.hasNext()) { + String line = reader.nextLine(); + String[] parameters = line.split(","); + try { + if (filePath.equals(PATH_APT_MEDS)) { + outputFilePathCorrupted = "data/appointment_meds_corrupted.txt"; + appointments.loadMedicine(parameters); + } else if (filePath.equals(PATH_DOC_DATE)) { + doctors.loadDate(parameters); + } else if (filePath.equals(PATH_PAT_DATE)) { + patients.loadDate(parameters); + } else { + if (filePath.equals(PATH_DOC)) { + outputFilePathCorrupted = "data/doctor_corrupted.txt"; + Validator.validateAddDoctor(parameters); + } + if (filePath.equals(PATH_PAT)) { + outputFilePathCorrupted = "data/patient_corrupted.txt"; + Validator.validateAddPatient(parameters); + } + if (filePath.equals(PATH_MED)) { + outputFilePathCorrupted = "data/medicine_corrupted.txt"; + Validator.validateMedicineStorage(parameters); + } + if (filePath.equals(PATH_APT)) { + outputFilePathCorrupted = "data/appointment_corrupted.txt"; + Validator.validateAddAppointmentStorage(parameters); + } + + listType.add(parameters); + } + + + } catch (UserInputErrorException | DuplicateEntryException e) { + corruptedLines.add(e + "\nLine: " + line); + } + } + if (corruptedLines.size() != 0 && !outputFilePathCorrupted.equals("nope")) { + saveCorruptedData(outputFilePathCorrupted, corruptedLines); + UI.printParagraph("There are some corrupted lines in your input files. " + + "It has been moved to another file named " + + outputFilePathCorrupted); + } + } + + private void saveCorruptedData(String filePath, ArrayList stringArray) { + File file = new File(filePath); + if (!file.exists()) { + try { + file.createNewFile(); + UI.printParagraph("file has been created"); + } catch (IOException ioException) { + UI.printParagraph("file cannot be created" + filePath); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(filePath,true); + dataWrite.write("Session: " + LocalDateTime.now().toString() + "\n"); + for (String s : stringArray) { + dataWrite.write(s + "\n"); + } + dataWrite.write("----------------------------------------------------------\n"); + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + + public void loadData() { + try { + loadGenericData(PATH_DOC, doctors); + loadGenericData(PATH_PAT, patients); + loadGenericData(PATH_MED, medicines); + loadGenericData(PATH_APT, appointments); + loadGenericData(PATH_APT_MEDS, appointments); + loadGenericData(PATH_PAT_DATE, patients); + loadGenericData(PATH_DOC_DATE, doctors); + } catch (FileNotFoundException f) { + UI.printParagraph("No saved data found!"); + } + + } + + private void saveMedicineData() { + File medicineFile = new File(PATH_MED); + if (!medicineFile.exists()) { + try { + medicineFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("medicine.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_MED,false); + for (Medicine m : medicines.getList()) { + dataWrite.write(m.saveString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + private void savePatientData() { + File patientFile = new File(PATH_PAT); + if (!patientFile.exists()) { + try { + patientFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("patient.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_PAT,false); + for (Patient p : patients.getList()) { + dataWrite.write(p.saveString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + private void saveDoctorData() { + File patientFile = new File(PATH_DOC); + if (!patientFile.exists()) { + try { + patientFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("doctor.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_DOC,false); + for (Doctor d : doctors.getList()) { + dataWrite.write(d.saveString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + private void saveAppointmentData() { + File appointmentFile = new File(PATH_APT); + if (!appointmentFile.exists()) { + try { + appointmentFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("appointment.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_APT,false); + for (Appointment appointment : appointments.getList()) { + dataWrite.write(appointment.saveString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + + private void saveAppointmentMedData() { + File appointmentMedFile = new File(PATH_APT_MEDS); + if (!appointmentMedFile.exists()) { + try { + appointmentMedFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("appointment_meds.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_APT_MEDS,false); + for (Appointment appointment : appointments.getList()) { + String saveString = appointment.saveMedicineString(); + if (saveString.equals("")) { + continue; + } + dataWrite.write(appointment.saveMedicineString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + private void saveDoctorDateData() { + File doctorFile = new File(PATH_DOC_DATE); + if (!doctorFile.exists()) { + try { + doctorFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("doctorDate.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_DOC_DATE,false); + for (Doctor d : doctors.getList()) { + String saveString = d.saveDateString(); + if (saveString.equals("")) { + continue; + } + dataWrite.write(d.saveDateString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + private void savePatientDateData() { + File appointmentMedFile = new File(PATH_PAT_DATE); + if (!appointmentMedFile.exists()) { + try { + appointmentMedFile.createNewFile(); + } catch (IOException ioException) { + UI.printParagraph("PatientDate.txt cannot be created"); + return; + } + } + try { + FileWriter dataWrite = new FileWriter(PATH_PAT_DATE,false); + for (Patient p : patients.getList()) { + String saveString = p.saveDateString(); + if (saveString.equals("")) { + continue; + } + dataWrite.write(p.saveDateString() + "\n"); + } + dataWrite.close(); + } catch (IOException e) { + UI.printParagraph("Unable to save data..."); + } + } + + public void saveData() { + File dir = new File(DIR); + try { + dir.mkdir(); + } catch (SecurityException s) { + UI.printParagraph("Cannot Create Dir"); + } + saveDoctorData(); + savePatientData(); + saveMedicineData(); + saveAppointmentData(); + saveAppointmentMedData(); + savePatientDateData(); + saveDoctorDateData(); + } +} diff --git a/src/main/java/seedu/duke/helper/UI.java b/src/main/java/seedu/duke/helper/UI.java new file mode 100644 index 0000000000..d0726eabf4 --- /dev/null +++ b/src/main/java/seedu/duke/helper/UI.java @@ -0,0 +1,436 @@ +package seedu.duke.helper; + +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.MedicineList; +import seedu.duke.assets.Patient; +import seedu.duke.assets.PatientList; +import seedu.duke.status.Status; + +import java.util.ArrayList; +import java.util.Scanner; + +public class UI { + private String userInput; + private ArrayList patients = new ArrayList<>(); + private Scanner reader = new Scanner(System.in); + private Parser parser = new Parser(); + + private void readInput() { + this.userInput = reader.nextLine(); + } + + public String readCommand() { + readInput(); + return parser.commandParser(userInput)[0].trim(); + } + + + public String readParameters() { + String[] userInputArray = parser.commandParser(userInput); + if (userInputArray.length == 1) { + return null; + } + return parser.commandParser(userInput)[1].trim().toUpperCase(); + } + + public static void printNewLineSeparator() { + System.out.println("--------------------------------------------------------"); + } + + public void printGreeting() { + printNewLineSeparator(); + printParagraph("Welcome! This is the Hospital Management System.\n" + + "Please type in your input"); + } + + public void printLogo() { + String logo = "--------------------------------------------------------\n" + + "HALPMI"; + + System.out.println(logo); + } + + public static void printHelp() { + printAddDoctorMessage(); + printAddPatientMessage(); + printAddMedicineMessage(); + printAddAppointmentMessage(); + printViewDoctorMessage(); + printViewPatientMessage(); + printViewMedicineMessage(); + printViewAppointmentMessage(); + printDeleteDoctorMessage(); + printDeletePatientMessage(); + printDeleteMedicineMessage(); + printDeleteAppointmentMessage(); + printEditDoctorMessage(); + printEditPatientMessage(); + printEditMedicineMessage(); + printFindDoctorMessage(); + printFindPatientMessage(); + printFindMedicineMessage(); + printUpdateMedicineMessage(); + printClearMedicineMessage(); + printDispenseMedicineMessage(); + printByeMessage(); + printNewLineSeparator(); + } + + public static void printAddDoctorMessage() { + printNewLineSeparator(); + System.out.println("Feature: ADD DOCTOR"); + System.out.print("Format: add doctor /info [nric],[name],[age],[gender], "); + System.out.println("[address],[DOB],[Specialisation]"); + System.out.print("Example: add doctor /info S1234567A, John Doe, "); + System.out.println("22, M, 10 Baker Street, 1999-12-31, Urinology"); + } + + public static void printAddPatientMessage() { + printNewLineSeparator(); + System.out.println("Feature: ADD PATIENT"); + System.out.print("Format: add patient /info [nric], [name], [age], [gender], "); + System.out.println("[address], [DOB], [Date of Admission]"); + System.out.print("Example: add patient /info S1234567A, John Doe, 22, "); + System.out.println("M, 10 Baker Street, 1999-12-31, 2021-02-15"); + } + + public static void printAddMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: ADD MEDICINE"); + System.out.print("Format: add medicine /info [batch id], [name], [dosage], "); + System.out.println("[expiry date],[side effects],[quantity]"); + System.out.print("Example: add medicine /info A123, Paracetamol, "); + System.out.println("500, 2023-06-11, Drowsy, 10"); + } + + public static void printAddAppointmentMessage() { + printNewLineSeparator(); + System.out.println("Feature: ADD APPOINTMENT"); + System.out.print("Format: add appointment /info [patient nric], [doctor nric], "); + System.out.println("[appointment date], [appointment details]"); + System.out.print("Example: add appointment /info S1234567A, S7654321A, "); + System.out.println("2022-10-15, Regular knee checkup"); + } + + public static void printViewDoctorMessage() { + printNewLineSeparator(); + System.out.println("Feature: VIEW DOCTOR"); + System.out.println("Format: view doctor"); + System.out.println("Example: view doctor"); + } + + public static void printViewPatientMessage() { + printNewLineSeparator(); + System.out.println("Feature: VIEW PATIENT"); + System.out.println("Format: view patient"); + System.out.println("Example: view patient"); + } + + public static void printViewMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: VIEW MEDICINE"); + System.out.println("Format: view medicine"); + System.out.println("Example: view medicine"); + } + + public static void printViewAppointmentMessage() { + printNewLineSeparator(); + System.out.println("Feature: VIEW APPOINTMENT"); + System.out.println("Format: view appointment or view appointment /info [criteria],[input value]"); + System.out.print("Accepted Criteria: appointment id, patient nric, "); + System.out.println("patient name, doctor name, doctor nric, date"); + System.out.println("Example 1: view appointment /info appointment id, 12356710156543"); + System.out.println("Example 2: view appointment /info patient nric, S1234567A"); + System.out.println("Example 3: view appointment /info doctor name, John"); + System.out.println("Example 4: view appointment /info patient date, 2023-01-01"); + } + + public static void printDeleteDoctorMessage() { + printNewLineSeparator(); + System.out.println("Feature: DELETE DOCTOR"); + System.out.println("Format: delete doctor /info [nric]"); + System.out.println("Example: delete doctor /info S7654321A"); + } + + public static void printDeletePatientMessage() { + printNewLineSeparator(); + System.out.println("Feature: DELETE PATIENT"); + System.out.println("Format: delete patient /info [nric]"); + System.out.println("Example: delete patient /info S1234567A"); + } + + public static void printDeleteMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: DELETE MEDICINE"); + System.out.println("Format: delete medicine /info [batch id]"); + System.out.println("Example: delete medicine /info S123"); + } + + public static void printDeleteAppointmentMessage() { + printNewLineSeparator(); + System.out.println("Feature: DELETE APPOINTMENT"); + System.out.println("Format: delete appointment /info [appointment id]"); + System.out.println("Example: delete appointment /info 12356710156543"); + } + + public static void printEditDoctorMessage() { + printNewLineSeparator(); + System.out.println("Feature: EDIT DOCTOR"); + System.out.print("Format: edit doctor /info [nric],[name],[age],[gender], "); + System.out.println("[address],[DOB],[Specialisation]"); + System.out.print("Example: edit doctor /info S7654321, John Doe, "); + System.out.println("22, M, 10 Baker Street, 1999-12-31, Urinology"); + } + + public static void printEditPatientMessage() { + printNewLineSeparator(); + System.out.println("Feature: Edit PATIENT"); + System.out.print("Format: edit patient /info [nric], [name], [age], [gender], "); + System.out.println("[address], [DOB], [Date of Admission]"); + System.out.print("Example: edit patient /info S1234567A, John Doe, 22, "); + System.out.println("M, 10 Baker Street, 1999-12-31, 2021-02-15"); + } + + public static void printEditMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: EDIT MEDICINE"); + System.out.print("Format: edit medicine /info [batch id], [name], [dosage], "); + System.out.println("[expiry date],[side effects],[quantity]"); + System.out.print("Example: edit medicine /info A123, Paracetamol, "); + System.out.println("500, 2023-06-11, Drowsy, 10"); + } + + public static void printEditAppointmentMessage() { + printNewLineSeparator(); + System.out.println("Feature: EDIT APPOINTMENT"); + System.out.print("Format: edit appointment /info [appointment id],[patient nric],"); + System.out.println("[patient name],[doctor nric],[doctor name],[appointment date],[appointment details]"); + System.out.print("Example: edit appointment /info A123,S1234567A,Doe,"); + System.out.println("S7654321A,John,2022-10-15,Regular knee checkup"); + } + + public static void printFindDoctorMessage() { + printNewLineSeparator(); + System.out.println("Feature: FIND DOCTOR"); + System.out.println("Format: find doctor /info [parameter], [keyword to find]"); + System.out.println("Example 1: find doctor /info name, Bruce Lee"); + System.out.println("Example 2: find doctor /info nric, S1234567X"); + System.out.println("Example 3: find doctor /info age, 23"); + System.out.println("Example 4: find doctor /info gender, M"); + System.out.println("Example 5: find doctor /info address, 15 King's Avenue"); + System.out.println("Example 6: find doctor /info dob, 1999-12-31"); + System.out.println("Example 7: find doctor /info specialization, Dermatology"); + } + + public static void printFindPatientMessage() { + printNewLineSeparator(); + System.out.println("Feature: FIND PATIENT"); + System.out.println("Format: find patient /info [parameter], [keyword to find]"); + System.out.println("Example 1: find patient /info name, Bruce Lee"); + System.out.println("Example 2: find patient /info nric, S1234567X"); + System.out.println("Example 3: find patient /info age, 22"); + System.out.println("Example 4: find patient /info gender, M"); + System.out.println("Example 5: find patient /info address, 15 King's Avenue"); + System.out.println("Example 6: find patient /info dob, 1999-12-31"); + System.out.println("Example 7: find patient /info registrationdate, 2021-02-15"); + } + + public static void printFindMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: FIND MEDICINE"); + System.out.println("Format: find medicine /info [parameter], [keyword to find]"); + System.out.println("Example 1: find medicine /info id, 12356710156543"); + System.out.println("Example 2: find medicine /info name, Paracetamol"); + System.out.println("Example 3: find medicine /info dosage, 500"); + System.out.println("Example 4: find medicine /info expiry, 2023-06-11"); + System.out.println("Example 5: find medicine /info sideeffects, DROWSY"); + System.out.println("Example 6: find medicine /info quantity, 10"); + } + + public static void printUpdateMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: UPDATE MEDICINE"); + System.out.println("Format: update medicines"); + System.out.println("Example: update medicines"); + } + + public static void printClearMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: CLEAR MEDICINE"); + System.out.println("Format: clear medicines"); + System.out.println("Example: clear medicines"); + } + + public static void printDispenseMedicineMessage() { + printNewLineSeparator(); + System.out.println("Feature: DISPENSE MEDICINE"); + System.out.println("Format: dispense medicine /info [Patient NRIC],[Medicine Name],[Quantity]"); + System.out.println("You can list multiple medicines as long as each medicine is in the form" + + "[Medicine Name],[Quantity]"); + System.out.println("Example: dispense medicine /info S1234567A,Paracetamol,10,Aspirin,20"); + } + + public static void printByeMessage() { + printNewLineSeparator(); + System.out.println("Feature: BYE (to exit & save the programme)"); + System.out.println("Format: bye"); + System.out.println("Example: bye"); + } + + public int getSize() { + return patients.size(); + } + + public void printWrongInput() { + printNewLineSeparator(); + printParagraph("Sorry. Input was invalid."); + printHelp(); + } + + public void printBye() { + printNewLineSeparator(); + printParagraph("Goodbye! Exiting the programme."); + } + + public void printAddPatientExampleMessage() { + printParagraph("Please note the error(s) mentioned above and try again!\n" + + "Here are two examples. Please follow the input order:\n" + + "add patient /info S1234567A, John Doe, 23, M, 10 Baker Street, 1999-12-31, 2021-02-15\n" + + "add patient /info T4867591Z, Mary Douglas Owen, 25, F, 15 King's Avenue, 1997-08-26, 2020-03-30"); + } + + public void printAddDoctorExampleMessage() { + printParagraph("Please note the error(s) mentioned above and try again!\n" + + "Here are two examples. Please follow the input order:\n" + + "add doctor /info S1234567A, John Doe, 23, M, 10 Baker Street, 1999-12-31, Urinology\n" + + "add doctor /info T4867591Z, Mary Douglas Owen, 25, F, 15 King's Avenue, 1997-08-26, Optometry"); + } + + public void printDeletePatientExampleMessage(PatientList patientList) { + printParagraph("Please input a positive number up to " + patientList.getSize() + " only.\n" + + "Here is an example:\ndelete patient /info 1"); + } + + public void printDeleteDoctorErrorMessage(DoctorList doctorList) { + printParagraph("Please input a positive number up to " + doctorList.getSize() + " only.\n" + + "Here is an example:\ndelete doctor /info 1"); + } + + public void printAddAppointmentExampleMessage() { + printParagraph("Please note the error(s) mentioned above and try again!\n" + + "Here is an example. Please follow the input order:\n" + + "add appointment /info S1234567A, Thomas, S1234567A, Ben, 2023-01-01, Knee checkup"); + } + + public void printNullParametersMessage() { + UI.printParagraph("Parameters missing or not detected. Please use /info for parameters."); + } + + public void printAddMedicineExampleMessage() { + printParagraph("Invalid format. Please follow the below example and try again.\n" + + "add medicine /info s231, Paracetamol,500,2023-12-12,Headaches,10"); + } + + public void printEditMedicineExampleMessage() { + printParagraph("Invalid format. Please follow the below example and try again.\n" + + "edit medicine /info s231, Paracetamol,500,2023-12-12,Headaches,10"); + } + + public void printFindDoctorExampleMessage() { + printParagraph("find doctor /info name, Bruce Lee\n" + + "find doctor /info nric, S1234567X\n" + + "find doctor /info age, 23\n" + + "find doctor /info gender, M\n" + + "find doctor /info address, 15 King's Avenue\n" + + "find doctor /info dob, 1999-12-31\n" + + "find doctor /info specialization, Dermatology\n"); + } + + public void printFindPatientExampleMessage() { + printParagraph("find patient /info name, Bruce Lee\n" + + "find patient /info nric, S1234567X\n" + + "find patient /info age, 23\n" + + "find patient /info gender, M\n" + + "find patient /info address, 15 King's Avenue\n" + + "find patient /info dob, 1999-12-31\n" + + "find patient /info admissiondate, 2021-02-15\n"); + } + + public void printFindMedicinetExampleMessage() { + printParagraph("find medicine /info id, S123\n" + + "find medicine /info name, Paracetamol\n" + + "find medicine /info dosage, 500\n" + + "find medicine /info expiry, 2023-06-11\n" + + "find medicine /info sideeffects, headache\n" + + "find medicine /info quantity, 10\n"); + } + + public static void printPrompt() { + System.out.print("\nYou: "); + } + + public static void printParagraph(String paragraph) { + String[] arrayOfSentences = paragraph.split("\n"); + System.out.println("Duke: " + arrayOfSentences[0]); + for (int i = 1; i < arrayOfSentences.length; i++) { + System.out.print(" "); + System.out.println(arrayOfSentences[i]); + } + } + + public static void printCont(String sentence) { + System.out.print(" "); + System.out.println(sentence); + } + + public void printDeleteMedicineExampleMessage(MedicineList medicineList) { + printParagraph("Please input a positive number up to " + medicineList.getSize() + " only.\n" + + "Here is an example:\ndelete patient /info 1"); + } + + public void print(Status status) { + switch (status) { + case ADD_PATIENT_SUCCESS: + printParagraph("Patient has been added successfully!"); + break; + case ADD_DOCTOR_SUCCESS: + printParagraph("Doctor has been added successfully!"); + break; + case ADD_MEDICINE_SUCCESS: + printParagraph("Medicine has been added successfully!"); + break; + case ADD_APPOINTMENT_SUCCESS: + printParagraph("Appointment has been added successfully!"); + break; + case DELETE_PATIENT_SUCCESS: + printParagraph("Patient has been deleted successfully!"); + break; + case DELETE_DOCTOR_SUCCESS: + printParagraph("Doctor has been deleted successfully!"); + break; + case DELETE_MEDICINE_SUCCESS: + printParagraph("Medicine has been deleted successfully!"); + break; + case DELETE_APPOINTMENT_SUCCESS: + printParagraph("Appointment has been deleted successfully!"); + break; + case EDIT_DOCTOR_SUCCESS: + printParagraph("Doctor has been edited successfully!"); + break; + case EDIT_PATIENT_SUCCESS: + printParagraph("Patient has been edited successfully!"); + break; + case EDIT_MEDICINE_SUCCESS: + printParagraph("Medicine has been edited successfully!"); + break; + case EDIT_APPOINTMENT_SUCCESS: + printParagraph("Appointment has been edited successfully!"); + break; + case PRINT_HELP: + UI.printHelp(); + break; + default: + break; + } + } +} diff --git a/src/main/java/seedu/duke/helper/Validator.java b/src/main/java/seedu/duke/helper/Validator.java new file mode 100644 index 0000000000..7882bcf15b --- /dev/null +++ b/src/main/java/seedu/duke/helper/Validator.java @@ -0,0 +1,400 @@ +package seedu.duke.helper; + +import seedu.duke.exception.UserInputErrorException; + +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeParseException; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Validator { + + /* Validating person attributes */ + public static void minParameterCheck(String[] parametersArray, int length) throws UserInputErrorException { + if (parametersArray.length != length) { + throw new UserInputErrorException("There is one or more parameters missing"); + } + } + + public static void validateNric(String nric) throws UserInputErrorException { + Pattern nricPattern = Pattern.compile("[A-Z][0-9]{7}[A-Z]"); + Matcher nricMatcher = nricPattern.matcher(nric); + if (!nricMatcher.matches()) { + throw new UserInputErrorException("NRIC must start with a capital letter, " + + "followed by 7 digits and end with a capital letter."); + } + } + + private static void validateFullName(String fullName) throws UserInputErrorException { + Pattern fullNamePattern = Pattern.compile("[a-zA-Z ]*"); + Matcher fullNameMatcher = fullNamePattern.matcher(fullName); + if (!fullNameMatcher.matches()) { + throw new UserInputErrorException("Full name must contain only alphabets, " + + "no special characters or numbers."); + } + } + + private static void validateAge(String ageString) throws UserInputErrorException { + int age; + try { + age = Integer.parseInt(ageString); + } catch (NumberFormatException numberFormatException) { + throw new UserInputErrorException("Age must be a positive number!"); + } + //age must be within 1 and 120 + if (!(1 <= age && age <= 120)) { + throw new UserInputErrorException("Age must be between 1 and 120 inclusive."); + } + } + + private static void validateGender(String gender) throws UserInputErrorException { + Pattern genderPattern = Pattern.compile("M|F"); + Matcher genderMatcher = genderPattern.matcher(gender); + if (!genderMatcher.matches()) { + throw new UserInputErrorException("Gender must be a single character: M or F."); + } + } + + private static void validateAddress(String address) throws UserInputErrorException { + Pattern addressPattern = Pattern.compile("[\\w\\-\\s'()#]*"); + Matcher addressMatcher = addressPattern.matcher(address); + if (!addressMatcher.matches()) { + throw new UserInputErrorException("Address must be alphanumeric. " + + "Only these specific special characters are allowed: ' ( ) #"); + } + } + + private static void validateDob(String dobString) throws UserInputErrorException { + LocalDate dob; + try { + dob = LocalDate.parse(dobString); + } catch (DateTimeParseException dateTimeParseException) { + throw new UserInputErrorException("Date of birth must be in YYYY-MM-DD format. " + + "It cannot be before 1900-01-01 or be today and after."); + } + LocalDate today = LocalDate.now(); + LocalDate dobLimit = LocalDate.parse("1900-01-01"); + // dob is within the range of 1900 - today + if (!(dob.isAfter(dobLimit) && dob.isBefore(today))) { + throw new UserInputErrorException("Date of birth must be in YYYY-MM-DD format. " + + "It cannot be before 1900-01-01 or be today and after."); + } + } + + private static void validateAdmissionDate(String admissionDateString) throws UserInputErrorException { + LocalDate admissionDate; + try { + admissionDate = LocalDate.parse(admissionDateString); + } catch (DateTimeParseException dateTimeParseException) { + throw new UserInputErrorException("Registration date must be in YYYY-MM-DD format. " + + "It cannot be before 1900-01-01 or be today and after."); + } + LocalDate today = LocalDate.now(); + LocalDate admissionDateLimit = LocalDate.parse("1980-01-01"); + + + // admission date is after 1980 and before today + if (!(admissionDate.isAfter(admissionDateLimit) && admissionDate.isBefore(today))) { + throw new UserInputErrorException("Registration date must be in YYYY-MM-DD format. " + + "It cannot be before 1900-01-01 or be today and after."); + } + } + + private static void validateAdmissionDob(String admissionDateString, String dob) throws UserInputErrorException { + LocalDate admissionDate = LocalDate.parse(admissionDateString); + LocalDate dateOfBirth = LocalDate.parse(dob); + if (!(admissionDate.isAfter(dateOfBirth))) { + throw new UserInputErrorException("Registration date must be after date of birth!"); + } + } + + private static void validateDobAge(String age, String dob) throws UserInputErrorException { + validateDob(dob); + LocalDate today = LocalDate.now(); + LocalDate birthday = LocalDate.parse(dob); + Period period = Period.between(birthday, today); + int calculatedAge = period.getYears(); + int parsedAge = Integer.parseInt(age); + if (!(parsedAge == calculatedAge)) { + throw new UserInputErrorException("Please ensure that the date of birth matches the age provided"); + } + + } + + /* Validating person */ + private static void validateAddPerson(String[] parameters) throws UserInputErrorException { + validateNric(parameters[0]); + validateFullName(parameters[1]); + validateAge(parameters[2]); + validateGender(parameters[3]); + validateAddress(parameters[4]); + validateDob(parameters[5]); + validateDobAge(parameters[2], parameters[5]); + } + + private static void validateSpecialization(String specialization) throws UserInputErrorException { + Pattern fullNamePattern = Pattern.compile("[a-zA-Z ]*"); + Matcher fullNameMatcher = fullNamePattern.matcher(specialization); + if (!fullNameMatcher.matches()) { + throw new UserInputErrorException("Specialization must contain only alphabets and no special characters."); + } + } + + + public static void validateAddDoctor(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 7); + validateAddPerson(Arrays.copyOfRange(parameters, 0, 6)); + validateSpecialization(parameters[6]); + } + + public static void validateAddPatient(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 7); + validateAddPerson(Arrays.copyOfRange(parameters, 0, 6)); + validateAdmissionDate(parameters[6]); + validateAdmissionDob(parameters[6], parameters[5]); + } + + + /* Validate medicine attributes */ + private static boolean validateMedicineName(String medicineName) throws UserInputErrorException { + boolean isValid = medicineName.matches("[a-zA-z ]+"); + if (!isValid) { + throw new UserInputErrorException("Invalid Medicine name"); + } + return true; + } + + private static boolean validateDosage(String dosage) throws UserInputErrorException { + try { + int dosageInt = Integer.parseInt(dosage); + if (dosageInt <= 0) { + throw new UserInputErrorException("Invalid medicine dosage"); + } + return dosageInt > 0; + } catch (NumberFormatException numberFormatException) { + throw new UserInputErrorException("Invalid Medicine dosage"); + } + } + + private static boolean validateExpiry(String expiry) throws UserInputErrorException { + try { + LocalDate expiryDate = LocalDate.parse(expiry); + LocalDate minimumDate = LocalDate.now(); + if (expiryDate.isBefore(minimumDate)) { + throw new UserInputErrorException("Medicine expiry date is before today"); + } + return true; + } catch (DateTimeParseException dateTimeParseException) { + throw new UserInputErrorException("Invalid Medicine Expiry"); + } + } + + private static boolean validateQuantity(String quantity) throws UserInputErrorException { + try { + int quantityInt = Integer.parseInt(quantity); + if (quantityInt <= 0) { + throw new UserInputErrorException("Invalid medicine quantity"); + } + return quantityInt > 0; + } catch (NumberFormatException numberFormatException) { + throw new UserInputErrorException("Invalid Medicine Quantity"); + } + } + + // Validate medicine + + public static void validateMedicine(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 6); + assert parameters.length == 6 : "Validate failed to check parameter length"; + validateMedicineName(parameters[1]); + validateDosage(parameters[2]); + validateExpiry(parameters[3]); + validateQuantity(parameters[5]); + } + + public static void validateMedicineStorage(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 6); + assert parameters.length == 6 : "Validate failed to check parameter length"; + validateMedicineName(parameters[1]); + validateDosage(parameters[2]); + validateDate(parameters[3],"none"); + validateQuantity(parameters[5]); + } + + // Validate appointment + + private static void validateAppointmentDetails(String appointmentDetails) throws UserInputErrorException { + if (appointmentDetails.isBlank() || appointmentDetails.isEmpty()) { + throw new UserInputErrorException("Appointment details cannot be empty. Please indicate some details."); + } + } + + private static void validateDate(String inputDate, String type) throws UserInputErrorException { + LocalDate newDate; + try { + newDate = LocalDate.parse(inputDate); + } catch (DateTimeParseException dateTimeParseException) { + throw new UserInputErrorException("Date must be in YYYY-MM-DD format. "); + } + LocalDate today = LocalDate.now(); + LocalDate admissionDateLimit = LocalDate.parse("1980-01-01"); + if (type.equals("appointment") && newDate.isBefore(today)) { + throw new UserInputErrorException("Date must be in YYYY-MM-DD format. " + + "New appointment dates must be today and after."); + } else if (type.equals("patient") && newDate.isAfter(admissionDateLimit) + && newDate.isBefore(today)) { + throw new UserInputErrorException("Date must be in YYYY-MM-DD format. " + + "Patient registration date must be after 1980-01-01 and today or before."); + } + } + + private static boolean validateDate(String expiry) throws UserInputErrorException { + try { + LocalDate expiryDate = LocalDate.parse(expiry); + return true; + } catch (DateTimeParseException dateTimeParseException) { + throw new UserInputErrorException("Invalid Medicine Expiry"); + } + } + + public static void validateAddAppointment(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 4); + validateNric(parameters[0]); + validateNric(parameters[1]); + validateDate(parameters[2], "appointment"); + } + + public static void validateAddAppointmentStorage(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 4); + validateNric(parameters[0]); + validateNric(parameters[1]); + validateDate(parameters[2], "none"); + } + + public static void validateEditAppointment(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 7); + validateNric(parameters[1]); + validateFullName(parameters[2]); + validateNric(parameters[3]); + validateFullName(parameters[4]); + validateDate(parameters[5], "appointment"); + validateAppointmentDetails(parameters[6]); + } + + public static void validateFindDoctor(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 2); + switch (parameters[0].toLowerCase()) { + case "nric": + validateNric(parameters[1]); + break; + case "name": + validateFullName(parameters[1]); + break; + case "age": + validateAge(parameters[1]); + break; + case "gender": + validateGender(parameters[1]); + break; + case "address": + validateAddress(parameters[1]); + break; + case "dob": + validateDob(parameters[1]); + break; + case "specialization": + validateSpecialization(parameters[1]); + break; + default: + throw new UserInputErrorException("Input must be an attribute of Doctor"); + } + } + + public static void validateFindAppointment(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 2); + switch (parameters[0].toLowerCase()) { + case "id": + break; + case "patient name": + case "doctor name": + validateFullName(parameters[1]); + break; + case "patient nric": + case "doctor nric": + validateNric(parameters[1]); + break; + case "date": + validateDate(parameters[1], "find appointment"); + break; + default: + throw new UserInputErrorException("Input must be an attribute of Appointment"); + } + } + + public static void validateFindMedicine(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 2); + boolean check = true; + switch (parameters[0].toLowerCase()) { + case "name": + check = validateMedicineName(parameters[1]); + break; + case "dosage": + check = check && validateDosage(parameters[1]); + break; + case "expiry": + check = check && validateDate(parameters[1]); + break; + case "quantity": + check = check && validateQuantity(parameters[1]); + break; + case "id": + case "side effects": + default: + break; + } + } + + public static void validateFindPatient(String[] parameters) throws UserInputErrorException { + minParameterCheck(parameters, 2); + switch (parameters[0].toLowerCase()) { + case "nric": + validateNric(parameters[1]); + break; + case "name": + validateFullName(parameters[1]); + break; + case "age": + validateAge(parameters[1]); + break; + case "gender": + validateGender(parameters[1]); + break; + case "address": + validateAddress(parameters[1]); + break; + case "dob": + validateDob(parameters[1]); + break; + case "registrationdate": + validateAdmissionDate(parameters[1]); + break; + default: + throw new UserInputErrorException("Input must be an attribute of Patient"); + } + } + + public static void validateDispenseMedicine(String[] dispenseMedicineParameters) throws UserInputErrorException { + validateNric(dispenseMedicineParameters[0]); + if (dispenseMedicineParameters.length < 3 || dispenseMedicineParameters.length % 2 != 1) { + throw new UserInputErrorException("Not all medicines in list have both " + + "the name of the medicine and the quantity to prescribe!"); + } + for (int i = 1; i < dispenseMedicineParameters.length; i += 2) { + String medicineName = dispenseMedicineParameters[i]; + String medicineQuantity = dispenseMedicineParameters[i + 1]; + validateMedicineName(medicineName); + } + } +} diff --git a/src/main/java/seedu/duke/helper/command/AddAppointmentCommand.java b/src/main/java/seedu/duke/helper/command/AddAppointmentCommand.java new file mode 100644 index 0000000000..6d204e7350 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/AddAppointmentCommand.java @@ -0,0 +1,42 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.List; +import seedu.duke.assets.PatientList; +import seedu.duke.assets.DoctorList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class AddAppointmentCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public AddAppointmentCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an AppointmentList that needs to be acted on. + * Uses parameterArray as inputs to add a new Appointment to the List. + * @ param list a List object - should be an instance of AppointmentList + * @ return Status.ADD_APPOINTMENT_SUCCESS if changes made to list was successful + * @ throws DuplicateEntryException if similar entry already exist. + */ + @Override + public Status execute(List appointmentList) throws DuplicateEntryException, UserInputErrorException { + if (appointmentList instanceof AppointmentList) { + appointmentList.add(parameterArray); + } else if (appointmentList instanceof PatientList) { + ((PatientList) appointmentList).addAppointmentDate(parameterArray[0], parameterArray[2]); + } else if (appointmentList instanceof DoctorList) { + ((DoctorList) appointmentList).addAppointmentDate(parameterArray[1], parameterArray[2]); + } + return Status.ADD_APPOINTMENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/AddDoctorCommand.java b/src/main/java/seedu/duke/helper/command/AddDoctorCommand.java new file mode 100644 index 0000000000..a84a54980a --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/AddDoctorCommand.java @@ -0,0 +1,32 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class AddDoctorCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public AddDoctorCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a DoctorList that needs to be acted on. + * Uses parameterArray as inputs to add a new Doctor to the List. + * @ param list a List object - should be an instance of DoctorList + * @ return Status.ADD_DOCTOR_SUCCESS if changes made to list was successful + * @ throws DuplicateEntryException if similar entry already exist. + */ + public Status execute(List doctorList) throws DuplicateEntryException { + doctorList.add(parameterArray); + return Status.ADD_DOCTOR_SUCCESS; + } + +} diff --git a/src/main/java/seedu/duke/helper/command/AddMedicineCommand.java b/src/main/java/seedu/duke/helper/command/AddMedicineCommand.java new file mode 100644 index 0000000000..c403c7b457 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/AddMedicineCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class AddMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public AddMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a MedicineList that needs to be acted on. + * Uses parameterArray as inputs to add a new Medicine to the List. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.ADD_MEDICINE_SUCCESS if changes made to list was successful + * @ throws DuplicateEntryException if similar entry already exist. + */ + public Status execute(List medicineList) throws DuplicateEntryException { + medicineList.add(parameterArray); + return Status.ADD_MEDICINE_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/AddPatientCommand.java b/src/main/java/seedu/duke/helper/command/AddPatientCommand.java new file mode 100644 index 0000000000..902b9bd2d2 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/AddPatientCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class AddPatientCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public AddPatientCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a PatientList that needs to be acted on. + * Uses parameterArray as inputs to add a new Patient to the List. + * @ param list a List object - should be an instance of PatientList + * @ return Status.ADD_PATIENT_SUCCESS; if changes made to list was successful + * @ throws DuplicateEntryException if similar entry already exist. + */ + public Status execute(List patientList) throws DuplicateEntryException { + patientList.add(this.parameterArray); + return Status.ADD_PATIENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/CheckForMedicineStockCommand.java b/src/main/java/seedu/duke/helper/command/CheckForMedicineStockCommand.java new file mode 100644 index 0000000000..f8f5e66249 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/CheckForMedicineStockCommand.java @@ -0,0 +1,44 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +import java.util.Arrays; + +/* + * Class that extends Abstract Command Class. + */ +public class CheckForMedicineStockCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public CheckForMedicineStockCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in MedicineList that needs to be acted on. + * Uses parameterArray as inputs to find if required medicines exit in List. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.MEDICINE_STOCK_FOUND_SUCCESS if changes made to list was successful + * @ throws HalpMiException if some medicines cannot be found. + * If exception thrown, a table of missing medicines printed. + */ + @Override + public Status execute(List medicineList) throws DuplicateEntryException, NotFoundException, + UserInputErrorException { + String[] medicineArray = Arrays.copyOfRange(parameterArray,1,parameterArray.length); + if (medicineList instanceof MedicineList) { + ((MedicineList) medicineList).checkStock(medicineArray); + return Status.MEDICINE_STOCK_FOUND_SUCCESS; + } + assert false; + throw new UserInputErrorException("Error with code! Approach Developer."); + } +} diff --git a/src/main/java/seedu/duke/helper/command/CheckIfAppointmentTodayCommand.java b/src/main/java/seedu/duke/helper/command/CheckIfAppointmentTodayCommand.java new file mode 100644 index 0000000000..6ef37915f5 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/CheckIfAppointmentTodayCommand.java @@ -0,0 +1,39 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.List; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class CheckIfAppointmentTodayCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public CheckIfAppointmentTodayCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in AppointmentList that needs to be acted on. + * Uses parameterArray as inputs to find if Patient has appointment today. + * @ param list a List object - should be an instance of AppointmentList + * @ return Status.APPOINTMENT_FOUND_SUCCESS if patient has appointment today. + * @ throws HalpMiException if patient does not exist or patient does not have appointment today. + */ + @Override + public Status execute(List appointmentList) throws DuplicateEntryException, NotFoundException, + UserInputErrorException { + if (appointmentList instanceof AppointmentList) { + ((AppointmentList) appointmentList).hasAppointmentToday("P",parameterArray[0]); + + } + return Status.APPOINTMENT_FOUND_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/CheckIfDoctorExistsCommand.java b/src/main/java/seedu/duke/helper/command/CheckIfDoctorExistsCommand.java new file mode 100644 index 0000000000..e278218da8 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/CheckIfDoctorExistsCommand.java @@ -0,0 +1,28 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.Doctor; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.finder.DoctorFinder; +import seedu.duke.status.Status; + +import java.util.ArrayList; + +public class CheckIfDoctorExistsCommand extends Command { + public CheckIfDoctorExistsCommand(String[] parameterArray) { + super(parameterArray); + } + + @Override + public Status execute(List doctorList) throws NotFoundException { + String inputDoctorNric = parameterArray[1]; + DoctorFinder doctorFinder = new DoctorFinder(); + ArrayList foundDoctor = doctorFinder.findDoctorByNric(((DoctorList)doctorList).getList(), + inputDoctorNric); + if (foundDoctor == null) { + throw new NotFoundException("There is no doctor with the NRIC given. Please try again."); + } + return Status.FIND_DOCTOR_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/CheckIfPatientExistsCommand.java b/src/main/java/seedu/duke/helper/command/CheckIfPatientExistsCommand.java new file mode 100644 index 0000000000..c1f816661f --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/CheckIfPatientExistsCommand.java @@ -0,0 +1,28 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.Patient; +import seedu.duke.assets.PatientList; +import seedu.duke.exception.NotFoundException; +import seedu.duke.helper.finder.PatientFinder; +import seedu.duke.status.Status; + +import java.util.ArrayList; + +public class CheckIfPatientExistsCommand extends Command { + public CheckIfPatientExistsCommand(String[] parameterArray) { + super(parameterArray); + } + + @Override + public Status execute(List patientList) throws NotFoundException { + String inputPatientNric = parameterArray[0]; + PatientFinder patientFinder = new PatientFinder(); + ArrayList foundPatient = patientFinder.findPatientByNric(((PatientList)patientList).getList(), + inputPatientNric); + if (foundPatient == null) { + throw new NotFoundException("There is no patient with the NRIC given. Please try again."); + } + return Status.FIND_PATIENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/ClearExpiredMedicineCommand.java b/src/main/java/seedu/duke/helper/command/ClearExpiredMedicineCommand.java new file mode 100644 index 0000000000..ba439dc2fd --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/ClearExpiredMedicineCommand.java @@ -0,0 +1,23 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +public class ClearExpiredMedicineCommand extends Command { + public ClearExpiredMedicineCommand() { + super(null); + } + + @Override + public Status execute(List medicineList) throws DuplicateEntryException, NotFoundException { + if (medicineList instanceof MedicineList) { + ((MedicineList) medicineList).clearStock(); + return Status.CLEAR_EXPIRED_MEDICINE_SUCCESS; + } + assert false; + throw new NotFoundException("Error in code, approach developer!"); + } +} diff --git a/src/main/java/seedu/duke/helper/command/Command.java b/src/main/java/seedu/duke/helper/command/Command.java new file mode 100644 index 0000000000..69124f8ca3 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/Command.java @@ -0,0 +1,32 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Abstract class that is parent to various other specific command classes. + * Holds an array of Strings named parameterArray. + */ +public abstract class Command { + public String[] parameterArray; + + /* + * Constructor method that assigns value to parameterArray + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public Command(String[] parameterArray) { + this.parameterArray = parameterArray; + } + + /* + * Abstract Method that takes in a list that needs to be acted on. + * @ param list a List object + */ + public abstract Status execute(List list) throws DuplicateEntryException, NotFoundException, + UserInputErrorException; +} + + diff --git a/src/main/java/seedu/duke/helper/command/DeleteAppointmentCommand.java b/src/main/java/seedu/duke/helper/command/DeleteAppointmentCommand.java new file mode 100644 index 0000000000..791392ee07 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/DeleteAppointmentCommand.java @@ -0,0 +1,47 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.Appointment; +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.List; +import seedu.duke.assets.PatientList; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class DeleteAppointmentCommand extends Command { + String[] newArray = new String[3]; + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public DeleteAppointmentCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an AppointmentList that needs to be acted on. + * Uses parameterArray as inputs to delete an existing Appointment in the List. + * @ param list a List object - should be an instance of AppointmentList + * @ return Status.DELETE_APPOINTMENT_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + public Status execute(List appointmentList) throws NotFoundException { + if (appointmentList instanceof AppointmentList) { + String info = ((AppointmentList) appointmentList).appointmentInformation(parameterArray[0]); + appointmentList.remove(parameterArray[0]); + newArray = info.split(","); + } + if (appointmentList instanceof PatientList) { + System.out.println(newArray[1]); + ((PatientList) appointmentList).removeAppointmentDate(newArray[1],newArray[2]); + } + if (appointmentList instanceof DoctorList) { + ((DoctorList) appointmentList).removeAppointmentDate(newArray[0],newArray[2]); + } + return Status.DELETE_APPOINTMENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/DeleteDoctorCommand.java b/src/main/java/seedu/duke/helper/command/DeleteDoctorCommand.java new file mode 100644 index 0000000000..b1fe81fe26 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/DeleteDoctorCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class DeleteDoctorCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public DeleteDoctorCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a DoctorList that needs to be acted on. + * Uses parameterArray as inputs to delete an existing Doctor in the List. + * @ param list a List object - should be an instance of DoctorList + * @ return Status.DELETE_DOCTOR_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + public Status execute(List doctorList) throws NotFoundException { + doctorList.remove(parameterArray[0]); + return Status.DELETE_DOCTOR_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/DeleteMedicineCommand.java b/src/main/java/seedu/duke/helper/command/DeleteMedicineCommand.java new file mode 100644 index 0000000000..c50b734451 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/DeleteMedicineCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class DeleteMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public DeleteMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a MedicineList that needs to be acted on. + * Uses parameterArray as inputs to delete an existing Medicine in the List. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.DELETE_MEDICINE_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + public Status execute(List medicineList) throws NotFoundException { + medicineList.remove(parameterArray[0]); + return Status.DELETE_MEDICINE_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/DeletePatientCommand.java b/src/main/java/seedu/duke/helper/command/DeletePatientCommand.java new file mode 100644 index 0000000000..662fb09dd4 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/DeletePatientCommand.java @@ -0,0 +1,31 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class DeletePatientCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public DeletePatientCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a PatientList that needs to be acted on. + * Uses parameterArray as inputs to delete an existing Patient in the List. + * @ param list a List object - should be an instance of PatientList + * @ return Status.DELETE_PATIENT_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + public Status execute(List patientList) throws NotFoundException { + patientList.remove(parameterArray[0]); + return Status.DELETE_PATIENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/DispenseMedicineCommand.java b/src/main/java/seedu/duke/helper/command/DispenseMedicineCommand.java new file mode 100644 index 0000000000..35667175b7 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/DispenseMedicineCommand.java @@ -0,0 +1,48 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.List; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +import java.util.Arrays; + +/* + * Class that extends Abstract Command Class. + */ +public class DispenseMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public DispenseMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in MedicineList or AppointmentList that needs to be acted on. + * Uses parameterArray as inputs to shift required medicines from medicine inventory to Appointment. + * @ param list a List object - should be an instance of MedicineList/AppointmentList + * @ return Status.DISPENSE_SUCCESS if changes made to list was successful + * Also prints out table of medicines to dispense. + */ + @Override + public Status execute(List list) throws DuplicateEntryException, NotFoundException, UserInputErrorException { + String patientNric = parameterArray[0]; + String[] medicineArray = Arrays.copyOfRange(parameterArray, 1, parameterArray.length); + if (list instanceof AppointmentList) { + ((AppointmentList) list).dispenseMedicine(patientNric,medicineArray); + return Status.DISPENSE_SUCCESS; + } + if (list instanceof MedicineList) { + ((MedicineList) list).dispenseMedicine(medicineArray); + return Status.DISPENSE_SUCCESS; + } + assert false; + throw new NotFoundException("Error in code, approach developer!"); + } +} diff --git a/src/main/java/seedu/duke/helper/command/EditAppointmentCommand.java b/src/main/java/seedu/duke/helper/command/EditAppointmentCommand.java new file mode 100644 index 0000000000..99a313b98b --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/EditAppointmentCommand.java @@ -0,0 +1,32 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class EditAppointmentCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public EditAppointmentCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an AppointmentList that needs to be acted on. + * Uses parameterArray as inputs to edit an existing Appointment in the List. + * @ param list a List object - should be an instance of AppointmentList + * @ return Status.EDIT_APPOINTMENT_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + @Override + public Status execute(List appointmentList) throws NotFoundException { + appointmentList.edit(parameterArray); + return Status.EDIT_APPOINTMENT_SUCCESS; + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/helper/command/EditDoctorCommand.java b/src/main/java/seedu/duke/helper/command/EditDoctorCommand.java new file mode 100644 index 0000000000..5c983c41a9 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/EditDoctorCommand.java @@ -0,0 +1,29 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +public class EditDoctorCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public EditDoctorCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a DoctorList that needs to be acted on. + * Uses parameterArray as inputs to edit an existing Doctor in the List. + * @ param list a List object - should be an instance of DoctorList + * @ return Status.EDIT_DOCTOR_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + @Override + public Status execute(List doctorList) throws NotFoundException { + doctorList.edit(parameterArray); + return Status.EDIT_DOCTOR_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/EditMedicineCommand.java b/src/main/java/seedu/duke/helper/command/EditMedicineCommand.java new file mode 100644 index 0000000000..4f21834014 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/EditMedicineCommand.java @@ -0,0 +1,32 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class EditMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public EditMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an MedicineList that needs to be acted on. + * Uses parameterArray as inputs to edit an existing Medicine in the List. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.EDIT_MEDICINE_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + @Override + public Status execute(List medicineList) throws NotFoundException { + medicineList.edit(parameterArray); + return Status.EDIT_MEDICINE_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/EditPatientCommand.java b/src/main/java/seedu/duke/helper/command/EditPatientCommand.java new file mode 100644 index 0000000000..01864a637d --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/EditPatientCommand.java @@ -0,0 +1,33 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class EditPatientCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public EditPatientCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an PatientList that needs to be acted on. + * Uses parameterArray as inputs to edit an existing Patient in the List. + * @ param list a List object - should be an instance of PatientList + * @ return Status.EDIT_PATIENT_SUCCESS if changes made to list was successful + * @ throws NotFoundException if entry does not exist. + */ + @Override + public Status execute(List patientList) throws NotFoundException { + patientList.edit(parameterArray); + return Status.EDIT_PATIENT_SUCCESS; + } +} + diff --git a/src/main/java/seedu/duke/helper/command/FindAppointmentCommand.java b/src/main/java/seedu/duke/helper/command/FindAppointmentCommand.java new file mode 100644 index 0000000000..fee853bc87 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/FindAppointmentCommand.java @@ -0,0 +1,49 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.AppointmentList; +import seedu.duke.assets.List; +import seedu.duke.status.Status; + +import java.util.Locale; + +/* + * Class that extends Abstract Command Class. + */ +public class FindAppointmentCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public FindAppointmentCommand(String[] parameterArray) { + super(parameterArray); + } + + public Status execute(List appointmentList) { + if (appointmentList instanceof AppointmentList) { + switch (parameterArray[0].toLowerCase()) { + case "id": + ((AppointmentList) appointmentList).findById(parameterArray); + break; + case "patient nric": + ((AppointmentList) appointmentList).findByPatientNric(parameterArray); + break; + case "patient name": + ((AppointmentList) appointmentList).findByPatientName(parameterArray); + break; + case "doctor nric": + ((AppointmentList) appointmentList).findByDoctorNric(parameterArray); + break; + case "doctor name": + ((AppointmentList) appointmentList).findByDoctorName(parameterArray); + break; + case "date": + ((AppointmentList) appointmentList).findByAppointmentDate(parameterArray); + break; + default: + break; + } + } + return Status.FIND_MEDICINE_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/FindDoctorCommand.java b/src/main/java/seedu/duke/helper/command/FindDoctorCommand.java new file mode 100644 index 0000000000..32466418ae --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/FindDoctorCommand.java @@ -0,0 +1,50 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.List; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class FindDoctorCommand extends Command { + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public FindDoctorCommand(String[] parameterArray) { + super(parameterArray); + } + + + public Status execute(List doctorList) { + if (doctorList instanceof DoctorList) { + switch (parameterArray[0].toLowerCase()) { + case "nric": + ((DoctorList) doctorList).findByNric(parameterArray); + break; + case "name": + ((DoctorList) doctorList).findByName(parameterArray); + break; + case "age": + ((DoctorList) doctorList).findByAge(parameterArray); + break; + case "gender": + ((DoctorList) doctorList).findByGender(parameterArray); + break; + case "address": + ((DoctorList) doctorList).findByAddress(parameterArray); + break; + case "dob": + ((DoctorList) doctorList).findByDob(parameterArray); + break; + case "specialization": + ((DoctorList) doctorList).findBySpecialization(parameterArray); + break; + default: + break; + } + } + return Status.FIND_DOCTOR_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/FindMedicineCommand.java b/src/main/java/seedu/duke/helper/command/FindMedicineCommand.java new file mode 100644 index 0000000000..2f43c97e85 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/FindMedicineCommand.java @@ -0,0 +1,47 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.MedicineList; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class FindMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public FindMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + public Status execute(List medicineList) { + if (medicineList instanceof MedicineList) { + switch (parameterArray[0].toLowerCase()) { + case "id": + ((MedicineList) medicineList).findById(parameterArray); + break; + case "name": + ((MedicineList) medicineList).findByName(parameterArray); + break; + case "dosage": + ((MedicineList) medicineList).findByDosage(parameterArray); + break; + case "expiry": + ((MedicineList) medicineList).findByExpiry(parameterArray); + break; + case "sideeffects": + ((MedicineList) medicineList).findBySideEffects(parameterArray); + break; + case "quantity": + ((MedicineList) medicineList).findByQuantity(parameterArray); + break; + default: + break; + } + } + return Status.FIND_MEDICINE_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/FindPatientCommand.java b/src/main/java/seedu/duke/helper/command/FindPatientCommand.java new file mode 100644 index 0000000000..00f2fd9ffa --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/FindPatientCommand.java @@ -0,0 +1,50 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.PatientList; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class FindPatientCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public FindPatientCommand(String[] parameterArray) { + super(parameterArray); + } + + public Status execute(List patientList) { + if (patientList instanceof PatientList) { + switch (parameterArray[0].toLowerCase()) { + case "nric": + ((PatientList) patientList).findByNric(parameterArray); + break; + case "name": + ((PatientList) patientList).findByName(parameterArray); + break; + case "age": + ((PatientList) patientList).findByAge(parameterArray); + break; + case "gender": + ((PatientList) patientList).findByGender(parameterArray); + break; + case "address": + ((PatientList) patientList).findByAddress(parameterArray); + break; + case "dob": + ((PatientList) patientList).findByDob(parameterArray); + break; + case "registrationdate": + ((PatientList) patientList).findByDateAdmission(parameterArray); + break; + default: + break; + } + } + return Status.FIND_PATIENT_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/UpdateMedicineInventoryCommand.java b/src/main/java/seedu/duke/helper/command/UpdateMedicineInventoryCommand.java new file mode 100644 index 0000000000..4432047ea1 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/UpdateMedicineInventoryCommand.java @@ -0,0 +1,40 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.exception.NotFoundException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class UpdateMedicineInventoryCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public UpdateMedicineInventoryCommand() { + super(null); + } + + /* + * Method that takes in MedicineList that needs to be acted on. + * Uses parameterArray as inputs to find expired and run out Medicines in the List. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.UPDATE_MEDICINE_INVENTORY_SUCCESS if changes made to list was successful + * @ throws HalpMiException if none of the existing medicines have run out or expired. + */ + @Override + public Status execute(List medicineList) throws DuplicateEntryException, NotFoundException, + UserInputErrorException { + if (medicineList instanceof MedicineList) { + ((MedicineList) medicineList).updateStock(); + return Status.UPDATE_MEDICINE_INVENTORY_SUCCESS; + } + assert false; + throw new NotFoundException("Error in code, approach developer!"); + } +} diff --git a/src/main/java/seedu/duke/helper/command/ViewAppointmentCommand.java b/src/main/java/seedu/duke/helper/command/ViewAppointmentCommand.java new file mode 100644 index 0000000000..a11bc2c155 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/ViewAppointmentCommand.java @@ -0,0 +1,35 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class ViewAppointmentCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public ViewAppointmentCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an AppointmentList that needs to be acted on. + * parameterArray should be NULL. Prints list of existing Appointments. + * @ param list a List object - should be an instance of AppointmentList + * @ return Status.VIEW_SUCCESS if list was printed. + * @ throws HalpmiException if issues with parameterArray. + */ + public Status execute(List appointmentList) throws UserInputErrorException { + if (parameterArray == null) { + appointmentList.view(); + } else { + throw new UserInputErrorException("View Appointment Command only accepts null parameters!"); + } + return Status.VIEW_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/ViewDoctorCommand.java b/src/main/java/seedu/duke/helper/command/ViewDoctorCommand.java new file mode 100644 index 0000000000..4210768d81 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/ViewDoctorCommand.java @@ -0,0 +1,35 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class ViewDoctorCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public ViewDoctorCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in a DoctorList that needs to be acted on. + * parameterArray should be NULL. Prints list of existing Doctors. + * @ param list a List object - should be an instance of DoctorList + * @ return Status.VIEW_SUCCESS if list was printed. + * @ throws HalpmiException if issues with parameterArray. + */ + public Status execute(List doctorList) throws UserInputErrorException { + if (parameterArray == null) { + doctorList.view(); + } else { + throw new UserInputErrorException("View Doctor Command only accepts null parameters!"); + } + return Status.VIEW_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/ViewMedicineCommand.java b/src/main/java/seedu/duke/helper/command/ViewMedicineCommand.java new file mode 100644 index 0000000000..4c48aa0ea7 --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/ViewMedicineCommand.java @@ -0,0 +1,35 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class ViewMedicineCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public ViewMedicineCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an MedicineList that needs to be acted on. + * parameterArray should be NULL. Prints list of existing Medicines. + * @ param list a List object - should be an instance of MedicineList + * @ return Status.VIEW_SUCCESS if list was printed. + * @ throws HalpmiException if issues with parameterArray. + */ + public Status execute(List medicineList) throws UserInputErrorException { + if (parameterArray == null) { + medicineList.view(); + } else { + throw new UserInputErrorException("View Medicine Command only accepts null parameters!"); + } + return Status.VIEW_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/command/ViewPatientCommand.java b/src/main/java/seedu/duke/helper/command/ViewPatientCommand.java new file mode 100644 index 0000000000..f1188bf9ad --- /dev/null +++ b/src/main/java/seedu/duke/helper/command/ViewPatientCommand.java @@ -0,0 +1,35 @@ +package seedu.duke.helper.command; + +import seedu.duke.assets.List; +import seedu.duke.exception.UserInputErrorException; +import seedu.duke.status.Status; + +/* + * Class that extends Abstract Command Class. + */ +public class ViewPatientCommand extends Command { + + /* + * Constructor method that calls constructor of super class + * @ param parameterArray an array of Strings - additional parameters given by user + */ + public ViewPatientCommand(String[] parameterArray) { + super(parameterArray); + } + + /* + * Method that takes in an PatientList that needs to be acted on. + * parameterArray should be NULL. Prints list of existing Patients. + * @ param list a List object - should be an instance of PatientList + * @ return Status.VIEW_SUCCESS if list was printed. + * @ throws HalpmiException if issues with parameterArray. + */ + public Status execute(List patientList) throws UserInputErrorException { + if (parameterArray == null) { + patientList.view(); + } else { + throw new UserInputErrorException("View Patient Command only accepts null parameters!"); + } + return Status.VIEW_SUCCESS; + } +} diff --git a/src/main/java/seedu/duke/helper/finder/AppointmentFinder.java b/src/main/java/seedu/duke/helper/finder/AppointmentFinder.java new file mode 100644 index 0000000000..57af8f53ac --- /dev/null +++ b/src/main/java/seedu/duke/helper/finder/AppointmentFinder.java @@ -0,0 +1,81 @@ +package seedu.duke.helper.finder; + +import seedu.duke.assets.Appointment; + +import java.util.ArrayList; + +public class AppointmentFinder { + public static ArrayList findAppointmentById(ArrayList appointments, + String appointmentId) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getAppointmentId().equals(appointmentId)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + public static ArrayList findAppointmentByPatientName(ArrayList appointments, + String patientName) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getPatientName().contains(patientName)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + public static ArrayList findAppointmentByPatientNric(ArrayList appointments, + String patientNric) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getPatientNric().equals(patientNric)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + public static ArrayList findAppointmentByDoctorName(ArrayList appointments, + String doctorName) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getDoctorName().contains(doctorName)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + public static ArrayList findAppointmentByDoctorNric(ArrayList appointments, + String doctorNric) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getDoctorNric().equals(doctorNric)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + public static ArrayList findAppointmentByDate(ArrayList appointments, + String date) { + ArrayList appointmentArrayList = new ArrayList<>(); + for (Appointment appointment : appointments) { + if (appointment.getAppointmentDate().equals(date)) { + appointmentArrayList.add(appointment); + } + } + return getAppointments(appointmentArrayList); + } + + private static ArrayList getAppointments(ArrayList appointmentArrayList) { + if (appointmentArrayList.isEmpty()) { + return null; + } else { + return appointmentArrayList; + } + } +} diff --git a/src/main/java/seedu/duke/helper/finder/DoctorFinder.java b/src/main/java/seedu/duke/helper/finder/DoctorFinder.java new file mode 100644 index 0000000000..21912e6fe6 --- /dev/null +++ b/src/main/java/seedu/duke/helper/finder/DoctorFinder.java @@ -0,0 +1,90 @@ +package seedu.duke.helper.finder; + +import seedu.duke.assets.Doctor; + +import java.util.ArrayList; + +public class DoctorFinder { + + public static ArrayList findDoctorByNric(ArrayList doctors, String requiredNric) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getNric().equals(requiredNric)) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorByName(ArrayList doctors, String requiredName) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getFullName().contains(requiredName)) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorByAge(ArrayList doctors, int requiredAge) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getAge() == requiredAge) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorByGender(ArrayList doctors, char requiredGender) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getGender() == requiredGender) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorByAddress(ArrayList doctors, String requiredAddress) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getAddress().contains(requiredAddress)) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorByDob(ArrayList doctors, String requiredDob) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getDob().contains(requiredDob)) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + public static ArrayList findDoctorBySpecialization(ArrayList doctors, + String requiredSpecialization) { + ArrayList doctorArrayList = new ArrayList<>(); + for (Doctor doctor : doctors) { + if (doctor.getSpecialization().contains(requiredSpecialization)) { + doctorArrayList.add(doctor); + } + } + return getDoctors(doctorArrayList); + } + + private static ArrayList getDoctors(ArrayList doctorArrayList) { + if (doctorArrayList.isEmpty()) { + return null; + } else { + return doctorArrayList; + } + } + +} + + diff --git a/src/main/java/seedu/duke/helper/finder/MedicineFinder.java b/src/main/java/seedu/duke/helper/finder/MedicineFinder.java new file mode 100644 index 0000000000..bb1e8e8e74 --- /dev/null +++ b/src/main/java/seedu/duke/helper/finder/MedicineFinder.java @@ -0,0 +1,80 @@ +package seedu.duke.helper.finder; + +import seedu.duke.assets.Medicine; + +import java.util.ArrayList; + +public class MedicineFinder { + + public static ArrayList findMedicineById(ArrayList medicines, String requiredId) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getMedicineId().equals(requiredId)) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + public static ArrayList findMedicineByName(ArrayList medicines, String requiredName) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getMedicineName().contains(requiredName)) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + public static ArrayList findMedicineByDosage(ArrayList medicines, int requiredDosage) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getDosage() == requiredDosage) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + public static ArrayList findMedicineByExpiry(ArrayList medicines, String requiredExpiry) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getExpiry().equals(requiredExpiry)) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + public static ArrayList findMedicineBySideEffects(ArrayList medicines, + String requiredSideEffects) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getSideEffects().equals(requiredSideEffects)) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + public static ArrayList findMedicineByQuantity(ArrayList medicines, int requiredQuantity) { + ArrayList medicineArrayList = new ArrayList<>(); + for (Medicine medicine : medicines) { + if (medicine.getQuantity() == requiredQuantity) { + medicineArrayList.add(medicine); + } + } + return getMedicines(medicineArrayList); + } + + private static ArrayList getMedicines(ArrayList medicineArrayList) { + if (medicineArrayList.isEmpty()) { + return null; + } else { + return medicineArrayList; + } + } + +} + + diff --git a/src/main/java/seedu/duke/helper/finder/PatientFinder.java b/src/main/java/seedu/duke/helper/finder/PatientFinder.java new file mode 100644 index 0000000000..817e4b4018 --- /dev/null +++ b/src/main/java/seedu/duke/helper/finder/PatientFinder.java @@ -0,0 +1,89 @@ +package seedu.duke.helper.finder; + +import seedu.duke.assets.Patient; + +import java.util.ArrayList; + +public class PatientFinder { + + public static ArrayList findPatientByNric(ArrayList patients, String requiredNric) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getNric().equals(requiredNric)) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByName(ArrayList patients, String requiredName) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getFullName().contains(requiredName)) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByAge(ArrayList patients, int requiredAge) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getAge() == requiredAge) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByGender(ArrayList patients, char requiredGender) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getGender() == requiredGender) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByAddress(ArrayList patients, String requiredAddress) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getAddress().contains(requiredAddress)) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByDob(ArrayList patients, String requiredDob) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getDob().contains(requiredDob)) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + public static ArrayList findPatientByDateAdmission(ArrayList patients, String requiredDob) { + ArrayList patientArrayList = new ArrayList<>(); + for (Patient patient : patients) { + if (patient.getDateAdmission().contains(requiredDob)) { + patientArrayList.add(patient); + } + } + return getPatients(patientArrayList); + } + + private static ArrayList getPatients(ArrayList patientArrayList) { + if (patientArrayList.isEmpty()) { + return null; + } else { + return patientArrayList; + } + } + +} + + diff --git a/src/main/java/seedu/duke/status/Status.java b/src/main/java/seedu/duke/status/Status.java new file mode 100644 index 0000000000..6ad61e1424 --- /dev/null +++ b/src/main/java/seedu/duke/status/Status.java @@ -0,0 +1,30 @@ +package seedu.duke.status; + +/* + * Holds SUCCESS messages + */ +public enum Status { + ADD_PATIENT_SUCCESS, + ADD_DOCTOR_SUCCESS, + ADD_MEDICINE_SUCCESS, + ADD_APPOINTMENT_SUCCESS, + DELETE_PATIENT_SUCCESS, + DELETE_DOCTOR_SUCCESS, + DELETE_MEDICINE_SUCCESS, + DELETE_APPOINTMENT_SUCCESS, + EDIT_PATIENT_SUCCESS, + EDIT_DOCTOR_SUCCESS, + EDIT_MEDICINE_SUCCESS, + EDIT_APPOINTMENT_SUCCESS, + UPDATE_MEDICINE_INVENTORY_SUCCESS, + CLEAR_EXPIRED_MEDICINE_SUCCESS, + VIEW_SUCCESS, + PRINT_HELP, + END_APP, + FIND_DOCTOR_SUCCESS, + FIND_MEDICINE_SUCCESS, + FIND_PATIENT_SUCCESS, + APPOINTMENT_FOUND_SUCCESS, + MEDICINE_STOCK_FOUND_SUCCESS, + DISPENSE_SUCCESS +} diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/HalpMiTest.java similarity index 90% rename from src/test/java/seedu/duke/DukeTest.java rename to src/test/java/seedu/duke/HalpMiTest.java index 2dda5fd651..899d2b285f 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/HalpMiTest.java @@ -1,10 +1,10 @@ package seedu.duke; -import static org.junit.jupiter.api.Assertions.assertTrue; - import org.junit.jupiter.api.Test; -class DukeTest { +import static org.junit.jupiter.api.Assertions.assertTrue; + +class HalpMiTest { @Test public void sampleTest() { assertTrue(true); diff --git a/src/test/java/seedu/duke/assets/MedicineListTest.java b/src/test/java/seedu/duke/assets/MedicineListTest.java new file mode 100644 index 0000000000..f2d5ae30fa --- /dev/null +++ b/src/test/java/seedu/duke/assets/MedicineListTest.java @@ -0,0 +1,20 @@ +package seedu.duke.assets; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class MedicineListTest { + @Test + void checkSize_arrayOfMedicines_expectedNumber() { + MedicineList medicineList = new MedicineList(); + int currentNumber = 0; + assertEquals(currentNumber, medicineList.getSize()); + } + + @Test + void demoTestMethod() { + assertTrue(true); + } +} diff --git a/src/test/java/seedu/duke/assets/PatientListTest.java b/src/test/java/seedu/duke/assets/PatientListTest.java new file mode 100644 index 0000000000..68cb046d08 --- /dev/null +++ b/src/test/java/seedu/duke/assets/PatientListTest.java @@ -0,0 +1,33 @@ +package seedu.duke.assets; + +import org.junit.jupiter.api.Test; +import seedu.duke.exception.DuplicateEntryException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PatientListTest { + @Test + void checkSize_onePatientInList_expectOne() { + PatientList testPatientList = new PatientList(); + int currentNumber = 0; + assertEquals(currentNumber, testPatientList.getSize()); + } + + @Test + void checkGetPatient_correctNricGiven_patientFound() throws DuplicateEntryException { + String testNric = "S1234567A"; + String testFullName = "Tan Wei Li"; + String testAge = "20"; + String testGender = "M"; + String testAddress = "14 Baker Street"; + String testDob = "1999-03-11"; + String testDateAdmission = "2022-01-01"; + String[] testAddPatientParameters = {testNric, testFullName,testAge, testGender, testAddress, testDob, + testDateAdmission}; + Patient testPatient = new Patient(testNric, testFullName,Integer.parseInt(testAge), testGender.charAt(0), + testAddress, testDob, testDateAdmission); + PatientList testPatientList = new PatientList(); + testPatientList.add(testAddPatientParameters); + assertEquals(testPatientList.getPatient(testNric).getNric(), testPatient.getNric()); + } +} diff --git a/src/test/java/seedu/duke/helper/CommandTest.java b/src/test/java/seedu/duke/helper/CommandTest.java new file mode 100644 index 0000000000..435507c50a --- /dev/null +++ b/src/test/java/seedu/duke/helper/CommandTest.java @@ -0,0 +1,22 @@ +package seedu.duke.helper; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; + +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +class CommandTest { + static final Logger logger = Logger.getLogger("CommmandTest"); + + @BeforeEach + void printDetails(TestInfo testInfo) { + logger.info("Now testing ->" + testInfo.getDisplayName()); + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/ParserTest.java b/src/test/java/seedu/duke/helper/ParserTest.java new file mode 100644 index 0000000000..05e1a6dec7 --- /dev/null +++ b/src/test/java/seedu/duke/helper/ParserTest.java @@ -0,0 +1,378 @@ +package seedu.duke.helper; + + +import org.junit.jupiter.api.Test; +import seedu.duke.exception.UserInputErrorException; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.fail; + + +class ParserTest { + + @Test + void parseAddPatientTest() { + String parameter = "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01,2022-01-01"; + String[] parameterArray = {"S1234567A", "JOHN", "23", "M", "SINGAPORE", "1999-01-01", "2022-01-01"}; + try { + assertArrayEquals(parameterArray, Parser.parseAddPatient(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseAddPatientInvalidParamTest() { + String[] parameters = {"S1234567,JOHN,23,M,SINGAPORE,1999-01-01,2022-01-01", + "S1234567A,JOHN1,23,M,SINGAPORE,1999-01-01,2022-01-01", + "S1234567A,JOHN,2B,M,SINGAPORE,1999-01-01,2022-01-01", + "S1234567A,JOHN,23,T,SINGAPORE,1999-01-01,2022-01-01", + "S1234567A,JOHN,23,M,SINGAPORE,1999,2022-01-01", + "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01,2022-100-01", + "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01,2022-01-01,123"}; + for (String s : parameters) { + try { + Parser.parseAddPatient(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseAddDoctorTest() { + String parameter = "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01,Paediatrics"; + String[] parameterArray = {"S1234567A", "JOHN", "23", "M", "SINGAPORE", "1999-01-01", "Paediatrics"}; + try { + assertArrayEquals(parameterArray, Parser.parseAddDoctor(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseAddDoctorInvalidParamTest() { + String[] parameters = {"S1234567,JOHN,23,M,SINGAPORE,1999-01-01,Paediatrics", + "S1234567A,JOHN1,23,M,SINGAPORE,1999-01-01,Paediatrics", + "S1234567A,JOHN,2B,M,SINGAPORE,1999-01-01,Paediatrics", + "S1234567A,JOHN,23,T,SINGAPORE,1999-01-01,Paediatrics", + "S1234567A,JOHN,23,M,SINGAPORE,1999,Paediatrics", + "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01,Paediatrics1", + "S1234567A,JOHN,23,M,SINGAPORE,1999-01-01"}; + for (String s : parameters) { + try { + Parser.parseAddDoctor(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseAddMedicineTest() { + String parameter = "S123,Paracetamol,500,2025-02-02,Headaches,100"; + String[] parameterArray = {"S123", "Paracetamol", "500", "2025-02-02", "Headaches", "100"}; + try { + assertArrayEquals(parameterArray, Parser.parseAddMedicine(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception"); + } + } + + @Test + void parseAddMedicineInvalidParamTest() { + String[] parameters = {"S123,Paracetamol1,500,2025-02-02,Headaches,100", + "S123,Paracetamol,-1,2025-02-02,Headaches,100", + "S123,Paracetamol,50b,2025-02-02,Headaches,100", + "S123,Paracetamol,500,2025-24-02,Headaches,100", + "S123,Paracetamol,500,2025-02-02,Headaches"}; + + for (String s : parameters) { + try { + Parser.parseAddMedicine(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseDeletePatientTest() { + String parameter = "S1234567A"; + String[] parameterArray = {"S1234567A"}; + try { + assertArrayEquals(parameterArray, Parser.parseDeletePatient(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseDeletePatientInvalidParamTest() { + String[] parameters = {"S1234567", "S1234567A,S1235467A", ""}; + for (String s : parameters) { + try { + Parser.parseDeletePatient(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException h) { + assert true; + } + } + } + + @Test + void parseDeleteDoctorTest() { + String parameter = "S1234567A"; + String[] parameterArray = {"S1234567A"}; + try { + assertArrayEquals(parameterArray, Parser.parseDeleteDoctor(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseDeleteDoctorInvalidParamTest() { + String[] parameters = {"S1234567", "S1234567A,S1235467A", ""}; + for (String s : parameters) { + try { + Parser.parseDeleteDoctor(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException h) { + assert true; + } + } + } + + @Test + void parseDeleteMedicineTest() { + String parameter = "S123"; + String[] parameterArray = {"S123"}; + try { + assertArrayEquals(parameterArray, Parser.parseDeleteMedicine(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseDeleteMedicineInvalidParamTest() { + String[] parameters = {"S1234567A,S1235467A"}; + for (String s : parameters) { + try { + Parser.parseDeleteMedicine(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException h) { + assert true; + } + } + } + + @Test + void parseViewDoctorWithParamTest() { + String parameter = "nric, S1234567A"; + String[] parameterArray = {"nric", "S1234567A"}; + try { + assertArrayEquals(parameterArray, Parser.parseViewDoctor(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewDoctorWithoutParamTest() { + String parameter = null; + String[] parameterArray = null; + try { + assertArrayEquals(parameterArray, Parser.parseViewDoctor(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewDoctorInvalidParamTest() { + String[] parameters = {"S1234567", "S1234567A,S1235467A", ""}; + + for (String s : parameters) { + try { + Parser.parseViewDoctor(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseViewPatientWithParamTest() { + String parameter = "nric, S1234567A"; + String[] parameterArray = {"nric", "S1234567A"}; + try { + assertArrayEquals(parameterArray, Parser.parseViewPatient(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewPatientWithoutParamTest() { + String parameter = null; + String[] parameterArray = null; + try { + assertArrayEquals(parameterArray, Parser.parseViewPatient(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewPatientInvalidParamTest() { + String[] parameters = {"S1234567", "S1234567A,S1235467A", ""}; + + for (String s : parameters) { + try { + Parser.parseViewPatient(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseViewMedicineWithParamTest() { + String parameter = "id, S1234"; + String[] parameterArray = {"id", "S1234"}; + try { + assertArrayEquals(parameterArray, Parser.parseViewMedicine(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewMedicineWithoutParamTest() { + String parameter = null; + String[] parameterArray = null; + try { + assertArrayEquals(parameterArray, Parser.parseViewMedicine(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseViewMedicineInvalidParamTest() { + String[] parameters = {"S1234567A"}; + + for (String s : parameters) { + try { + Parser.parseViewMedicine(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseEditMedicineTest() { + String parameter = "S123,Paracetamol,500,2025-02-02,Headaches,100"; + String[] parameterArray = {"S123", "Paracetamol", "500", "2025-02-02", "Headaches", "100"}; + try { + assertArrayEquals(parameterArray, Parser.parseEditMedicine(parameter).parameterArray); + } catch (UserInputErrorException e) { + fail("Should not be throwing exception"); + } + } + + @Test + void parseEditMedicineInvalidParamTest() { + String[] parameters = {"S123,Paracetamol1,500,2025-02-02,Headaches,100", + "S123,Paracetamol,-1,2025-02-02,Headaches,100", + "S123,Paracetamol,50b,2025-02-02,Headaches,100", + "S123,Paracetamol,500,2025-24-02,Headaches,100", + "S123,Paracetamol,500,2025-02-02,Headaches"}; + + for (String s : parameters) { + try { + Parser.parseAddMedicine(s); + fail("Should be throwing exception! Failed for: " + s); + } catch (UserInputErrorException e) { + assert true; + } + } + } + + @Test + void parseUpdateMedicineStockTest() { + try { + Parser.parseUpdateMedicineStock(null); + assert true; + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseUpdateMedicineStockInvalidParamTest() { + try { + Parser.parseUpdateMedicineStock(""); + fail("Should be throwing exception!"); + } catch (UserInputErrorException e) { + assert true; + } + } + + @Test + void parseClearExpiredMedicineTest() { + try { + Parser.parseClearExpiredMedicine(null); + assert true; + } catch (UserInputErrorException e) { + fail("Should not be throwing exception!"); + } + } + + @Test + void parseClearExpiredMedicineInvalidParamTest() { + try { + Parser.parseClearExpiredMedicine(""); + fail("Should be throwing exception!"); + } catch (UserInputErrorException e) { + assert true; + } + } + + /* + @Test + void parseAddAppointmentTest_CorrectFormatInput_returnCommand() { + String parameters = "ID1,S1234567A,Thomas,S7654321A,Anderson,2023-01-01,Headache"; + Command testCommand = null; + try { + testCommand = Parser.parseAddAppointment(parameters); + } catch (HalpmiException e) { + e.toString(); + } + assertTrue(testCommand instanceof AddAppointmentCommand); + } + + + @Test + void parseViewAppointmentTest_CorrectFormatInput_returnCommand() { + String viewParameters = "nric,S1234567A"; + Command testCommand = null; + try { + testCommand = Parser.parseViewAppointment(viewParameters); + } catch (HalpmiException e) { + e.toString(); + } + assertTrue(testCommand instanceof ViewAppointmentCommand); + } + */ + +} diff --git a/src/test/java/seedu/duke/helper/UiTest.java b/src/test/java/seedu/duke/helper/UiTest.java new file mode 100644 index 0000000000..18a70ba764 --- /dev/null +++ b/src/test/java/seedu/duke/helper/UiTest.java @@ -0,0 +1,15 @@ +package seedu.duke.helper; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; + +import java.util.logging.Logger; + +public class UiTest { + static final Logger logger = Logger.getLogger("UiTest"); + + @BeforeEach + void printDetails(TestInfo testInfo) { + logger.info("Now testing:"); + } +} diff --git a/src/test/java/seedu/duke/helper/command/AddDoctorCommandTest.java b/src/test/java/seedu/duke/helper/command/AddDoctorCommandTest.java new file mode 100644 index 0000000000..02438c60ff --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/AddDoctorCommandTest.java @@ -0,0 +1,38 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.DoctorList; +import seedu.duke.exception.DuplicateEntryException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static seedu.duke.status.Status.ADD_DOCTOR_SUCCESS; + +class AddDoctorCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","Endocrinology"}; + DoctorList doctors = new DoctorList(); + AddDoctorCommand command = new AddDoctorCommand(parameterArray); + try { + assertEquals(ADD_DOCTOR_SUCCESS,command.execute(doctors)); + } catch (DuplicateEntryException e) { + fail("Should give success status, not throw exception"); + } + } + + @Test + void executeTestDuplicate() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","Endocrinology"}; + DoctorList doctors = new DoctorList(); + AddDoctorCommand command = new AddDoctorCommand(parameterArray); + try { + command.execute(doctors); + command.execute(doctors); + fail("Should throw Duplicate Entry exception"); + } catch (Exception e) { + assert true; + } + } +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/AddMedicineCommandTest.java b/src/test/java/seedu/duke/helper/command/AddMedicineCommandTest.java new file mode 100644 index 0000000000..fd232bbe87 --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/AddMedicineCommandTest.java @@ -0,0 +1,41 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static seedu.duke.status.Status.ADD_DOCTOR_SUCCESS; +import static seedu.duke.status.Status.ADD_MEDICINE_SUCCESS; + +class AddMedicineCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S123","Paracetamol","500","2024-01-01","Headaches","10"}; + MedicineList medicines = new MedicineList(); + AddMedicineCommand command = new AddMedicineCommand(parameterArray); + try { + assertEquals(ADD_MEDICINE_SUCCESS,command.execute(medicines)); + } catch (DuplicateEntryException e) { + fail("Should give success status, not throw exception"); + } + } + + @Test + void executeTestDuplicate() { + String[] parameterArray = {"S123","Paracetamol","500","2024-01-01","Headaches","10"}; + MedicineList medicines = new MedicineList(); + AddMedicineCommand command = new AddMedicineCommand(parameterArray); + try { + command.execute(medicines); + command.execute(medicines); + fail("Should be throwing Duplicate Entry Exception"); + } catch (Exception e) { + assert true; + } + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/AddPatientCommandTest.java b/src/test/java/seedu/duke/helper/command/AddPatientCommandTest.java new file mode 100644 index 0000000000..6a13e3f165 --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/AddPatientCommandTest.java @@ -0,0 +1,40 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.MedicineList; +import seedu.duke.assets.PatientList; +import seedu.duke.exception.DuplicateEntryException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static seedu.duke.status.Status.ADD_MEDICINE_SUCCESS; +import static seedu.duke.status.Status.ADD_PATIENT_SUCCESS; + +class AddPatientCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","2022-02-02"}; + PatientList patients = new PatientList(); + AddPatientCommand command = new AddPatientCommand(parameterArray); + try { + assertEquals(ADD_PATIENT_SUCCESS,command.execute(patients)); + } catch (DuplicateEntryException e) { + fail("Should give success status, not throw exception"); + } + } + + @Test + void executeTestDuplicate() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","2022-02-02"}; + PatientList patients = new PatientList(); + AddPatientCommand command = new AddPatientCommand(parameterArray); + try { + command.execute(patients); + command.execute(patients); + fail("Should be throwing Duplicate Entry Exception"); + } catch (Exception e) { + assert true; + } + } +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/DeleteDoctorCommandTest.java b/src/test/java/seedu/duke/helper/command/DeleteDoctorCommandTest.java new file mode 100644 index 0000000000..0ea351c08f --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/DeleteDoctorCommandTest.java @@ -0,0 +1,44 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.DoctorList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; + +import static org.junit.jupiter.api.Assertions.fail; + + +class DeleteDoctorCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","Endocrinology"}; + String[] parameterArray2 = {"S1234567A"}; + DoctorList doctors = new DoctorList(); + AddDoctorCommand command = new AddDoctorCommand(parameterArray); + DeleteDoctorCommand commandInTest = new DeleteDoctorCommand(parameterArray2); + try { + command.execute(doctors); + commandInTest.execute(doctors); + assert true; + } catch (DuplicateEntryException e) { + fail("AddDoctorCommand is not working correctly!"); + } catch (NotFoundException n) { + fail("Shouldn't be throwing NotFoundException as doctor exists!"); + } + } + + @Test + void executeTestNotFound() { + String[] parameterArray2 = {"S1234567A"}; + DoctorList doctors = new DoctorList(); + DeleteDoctorCommand commandInTest = new DeleteDoctorCommand(parameterArray2); + try { + commandInTest.execute(doctors); + fail("Should be throwing NotFoundException!"); + } catch (NotFoundException n) { + assert true; + } + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/DeleteMedicineCommandTest.java b/src/test/java/seedu/duke/helper/command/DeleteMedicineCommandTest.java new file mode 100644 index 0000000000..3104a854c9 --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/DeleteMedicineCommandTest.java @@ -0,0 +1,44 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; + +import static org.junit.jupiter.api.Assertions.fail; + + +class DeleteMedicineCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S123","Paracetamol","500","2024-01-01","Headaches","10"}; + String[] parameterArray2 = {"S123"}; + MedicineList medicines = new MedicineList(); + AddMedicineCommand command = new AddMedicineCommand(parameterArray); + DeleteMedicineCommand commandInTest = new DeleteMedicineCommand(parameterArray2); + try { + command.execute(medicines); + commandInTest.execute(medicines); + assert true; + } catch (DuplicateEntryException e) { + fail("AddMedicineCommand is not working correctly!"); + } catch (NotFoundException n) { + fail("Shouldn't be throwing NotFoundException as medicine exists!"); + } + } + + @Test + void executeTestNotFound() { + String[] parameterArray2 = {"S123"}; + MedicineList medicines = new MedicineList(); + DeleteMedicineCommand commandInTest = new DeleteMedicineCommand(parameterArray2); + try { + commandInTest.execute(medicines); + fail("Should be throwing NotFoundException!"); + } catch (NotFoundException n) { + assert true; + } + } +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/DeletePatientCommandTest.java b/src/test/java/seedu/duke/helper/command/DeletePatientCommandTest.java new file mode 100644 index 0000000000..8a96fa87b8 --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/DeletePatientCommandTest.java @@ -0,0 +1,45 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.DoctorList; +import seedu.duke.assets.MedicineList; +import seedu.duke.assets.PatientList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; + +import static org.junit.jupiter.api.Assertions.fail; + + +class DeletePatientCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S1234567A","John","23","M","Singapore","1999-01-01","2020-01-01"}; + String[] parameterArray2 = {"S1234567A"}; + PatientList patients = new PatientList(); + AddPatientCommand command = new AddPatientCommand(parameterArray); + DeletePatientCommand commandInTest = new DeletePatientCommand(parameterArray2); + try { + command.execute(patients); + commandInTest.execute(patients); + assert true; + } catch (DuplicateEntryException e) { + fail("AddPatientCommand is not working correctly!"); + } catch (NotFoundException n) { + fail("Shouldn't be throwing NotFoundException as patient exists!"); + } + } + + @Test + void executeTestNotFound() { + String[] parameterArray2 = {"S1234567A"}; + PatientList patients = new PatientList(); + DeletePatientCommand commandInTest = new DeletePatientCommand(parameterArray2); + try { + commandInTest.execute(patients); + fail("Should be throwing NotFoundException!"); + } catch (NotFoundException n) { + assert true; + } + } +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/command/EditMedicineCommandTest.java b/src/test/java/seedu/duke/helper/command/EditMedicineCommandTest.java new file mode 100644 index 0000000000..6f372909ba --- /dev/null +++ b/src/test/java/seedu/duke/helper/command/EditMedicineCommandTest.java @@ -0,0 +1,44 @@ +package seedu.duke.helper.command; + +import org.junit.jupiter.api.Test; +import seedu.duke.assets.MedicineList; +import seedu.duke.exception.DuplicateEntryException; +import seedu.duke.exception.NotFoundException; + +import static org.junit.jupiter.api.Assertions.fail; + + +class EditMedicineCommandTest { + + @Test + void executeTest() { + String[] parameterArray = {"S123","Paracetamol","500","2024-01-01","Headaches","10"}; + String[] parameterArray2 = {"S123","Aspirin","500","2024-01-01","Headaches","10"}; + MedicineList medicines = new MedicineList(); + AddMedicineCommand command = new AddMedicineCommand(parameterArray); + EditMedicineCommand commandInTest = new EditMedicineCommand(parameterArray2); + try { + command.execute(medicines); + commandInTest.execute(medicines); + assert true; + } catch (DuplicateEntryException d) { + fail("AddMedicineCommand is not working properly!"); + } catch (NotFoundException n) { + fail("There exists a Medicine with the stated Batch ID. Should not be throwing exception!"); + } + } + + @Test + void executeTestNotFound() { + String[] parameterArray2 = {"S123","Aspirin","500","2024-01-01","Headaches","10"}; + MedicineList medicines = new MedicineList(); + EditMedicineCommand commandInTest = new EditMedicineCommand(parameterArray2); + try { + commandInTest.execute(medicines); + fail("Should be throwing Not Found Exception"); + } catch (NotFoundException n) { + assert true; + } + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/helper/finder/DoctorFinderTest.java b/src/test/java/seedu/duke/helper/finder/DoctorFinderTest.java new file mode 100644 index 0000000000..633f27a2f7 --- /dev/null +++ b/src/test/java/seedu/duke/helper/finder/DoctorFinderTest.java @@ -0,0 +1,6 @@ +package seedu.duke.helper.finder; + +class DoctorFinderTest { + +} + diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..5f2812dbab 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,10 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| +HalpMi: No saved data found! +------------------------------ +HALPMI +------------------------- +HalpMi: Welcome! This is the Hospital Management System. + Please type in your input -What is your name? -Hello James Gosling +You: HalpMi: Invalid Command given! + +You: Terminated diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..386a968044 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1,2 @@ -James Gosling \ No newline at end of file +hi +bye \ No newline at end of file