diff --git a/.gitignore b/.gitignore index f69985ef1f..f1359e204d 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,9 @@ src/main/resources/docs/ bin/ /text-ui-test/ACTUAL.txt -text-ui-test/EXPECTED-UNIX.TXT +/text-ui-test/EXPECTED-UNIX.TXT +/text-ui-test/EXPECTED.TXT +/text-ui-test/input.txt +/text-ui-test/runtest.bat +/text-ui-test/runtest.sh + diff --git a/Duke.txt b/Duke.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/Duke.txt @@ -0,0 +1 @@ + diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..f3131026c1 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Duke.java + diff --git a/build.gradle b/build.gradle index b0c5528fb5..6978e341b6 100644 --- a/build.gradle +++ b/build.gradle @@ -44,3 +44,7 @@ checkstyle { run{ standardInput = System.in } + +run { + enableAssertions = true +} diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..51ba07cff7 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,8 +2,8 @@ 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) +![Kairos](Team%20pictures/kairos.png) | Kairos Koh | [Github](https://github.com/kairoskoh) | [Portfolio](team/kairoskoh.md) +![Jerrell](Team pictures/jerrell.jpg) | Jerrell Low | [Github](https://github.com/jerrelllzw) | [Portfolio](team/jerrelllzw.md) +![Cheok Feng](Team%20pictures/cheokfeng.jpg) | Lee Cheok Feng | [Github](https://github.com/leecheokfeng) | [Portfolio](team/leecheokfeng.md) +![LIU ZEHANG](Team%20pictures/LiuZehang.jpg) | Liu Zehang | [Github](https://github.com/Cesare4869) | [Portfolio](docs/team/LIU ZEHANG.md) + diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..93095e9919 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,38 +1,323 @@ # Developer Guide -## Acknowledgements +## Introduction +Restaurant Buddy is a command-line-interface (CLI) application for **restaurant managers** to +help **keep track of restaurant data** such as its employees, dishes and ingredients in storage. -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +## Contents +1. [Design](#1-design) + 1. [Architecture](#11-architecture) + 2. [Employee Component](#12-employee-component) + 3. [Dish Component](#13-dish-component) + 4. [Ingredient Component](#14-ingredient-component) + 6. [Storage Component](#16-storage-component) +2. [Implementation](#2-implementation) + 1. Employee + 1. [Add Employee](#2ia-add-employee) + 2. [Remove Employee](#2ib-remove-employee) + 3. [List Employees](#2ic-list-employees) + 2. Dish + 1. [Add Dish](#2iia-add-dishes) + 2. [Remove Dish](#2iib-remove-dish) + 3. [Edit Dish](#2iic-edit-dish) + 4. [Discount Dish](#2iid-discount-dish) + 5. [List Dishes](#2iie-list-dishes) + 3. Ingredient + 1. [Add Ingredient](#2iiia-add-ingredient) + 2. [Remove Ingredient](#2iiib-remove-ingredient) + 3. [Find Expired Ingredients](#2iiic-find-expired-ingredients) + 4. [List Ingredients](#2iiid-list-ingredients) + 4. Finance + 1. [Add Finance](#2iva-add-finance) + 2. [Remove Finance](#2ivb-remove-finance) + 3. [Edit Finance](#2ivc-edit-finance) + 4. [Show Finance](#2ivd-show-finance-feature) + 5. [List Finances](#2ive-list-finances) + 5. Storage + 1. [Save Storage](#2va-save-storage) + 2. [Load Storage](#2vb-load-storage) +3. [Appendix](#3-appendix) + 1. [Product Scope](#3i-product-scope) + 2. [User Stories](#3ii-user-stories) + 3. [Non Functional Requirements](#3iii-non-functional-requirements) + 4. [Glossary](#3iv-glossary) -## Design & implementation +## 1. Design -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +### 1.1 Architecture +The Main component has 2 classes, `MainParser` and `MainUI`. It is responsible for parsing user commands and +displaying messages to interact with the user. +The rest of the app consists of 4 components: +1. Employee: Modify data related to employee classes +2. Dish: Modify data related to dish classes +3. Ingredient: Modify data related to ingredient classes +4. Storage: Reads and writes data to and from the hard disk -## Product scope -### Target user profile +### 1.2 Employee Component -{Describe the target user profile} +![employee](Diagrams/employee/employee_class_diagram.png) -### Value proposition +The employee component consists of the following four classes: `Employee`, `EmployeeList`, `EmployeeParser` +and `EmployeeUI`. -{Describe the value proposition: what problem does it solve?} +* `Employee` stores the name, phone number, employment status and salary of an individual employee working at the restaurant, as well as methods +to retrieve employee information. +* `EmployeeList` is an array list of multiple Employee. +* `EmployeeParser` contains operations that decode user inputs into meaningful commands, and modifies the list of +employees accordingly. +* `EmployeeUI` contains methods that display messages that interacts with the user. -## User Stories +### 1.3 Dish Component +![dish](Diagrams/dish/Dish.png) -|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| +The dish component consists of the `Dish`, `Menu`, `DishParser`, and `DishUI` classes. -## Non-Functional Requirements +* `Dish` stores the name, price and discount of a certain dish sold by the restaurant and the methods used to retrieve + them. +* `Menu` is an array list of Dish. +* `DishParser` contains methods that parses user inputs into meaningful parameters and modify the menu accordingly. +* `DishUI` contains methods that display messages to interact with the user. -{Give non-functional requirements} +### 1.4 Ingredient Component +![ingredient](Diagrams/ingredient/Ingredient.png) -## Glossary +The ingredient component consists of the `Ingredient`, `IngredientList`, `IngredientParser`, and `IngredientUI` classes. -* *glossary item* - Definition +* `Ingredient` stores the name and quantity of a particular ingredient used by the restaurant, as well as methods to +retrieve ingredient data. +* `IngredientList` is an array list of Ingredient. +* `IngredientParser` contains operations that decode user inputs into meaningful commands, and modifies the list of +ingredients accordingly. +* `IngredientUI` contains methods that display messages to interact with the user. -## Instructions for manual testing +### 1.5 Finance Component +The Finance component consists of the `Finance`, `FinanceList`, `FinanceParser`, `FinanceUI` classes. -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} +* `Finance` stores the date, account of a certain days earn and methods to retrieve them. +* `FinanceList` is the arrayList of Finance. +* `FinanceParser` contains methods that decode user inputs to meaningful parameters and modify the finance accordingly. +* `FinanceUI` contains methods that display messages to interact with the user. + +![finance](Diagrams/Finance.png) + +### 1.6 Storage Component +![storage](Diagrams/storage/Storage.png) + +The storage component has a `Storage` class which can load data from the file and save data into the file with the +methods to encode and decode data. + +## 2. Implementation + +### 2.i.a Add Employee +The mechanism of adding an employee into the list of employees is facilitated by `EmployeeParser`. It first creates a +new instance of `Employee`, and adds it to the existing instance of `EmployeeList`. A confirmation message is then +displayed to the user. + +![add](Diagrams/employee/add_employee_sequence_diagram.png) + +### 2.i.b Remove Employee +The mechanism of removing an employee from the employee list is facilitated by `EmployeeParser`. It identifies the +index of the employee to be removed from the current instance of `EmployeeList`, and removes that instance of +`Employee` from the list. It then displays a message to the user to inform them of the successful deletion. + +### 2.i.c List Employees +The mechanism for listing all current employees in the list of employees is facilitated by `EmployeeParser`. It checks +if the current instance of `EmployeeList` is empty, and if it is, displays a message to inform the user that the +employee list is empty. Otherwise, it displays all employees and their information in the list to the user. + +### 2.ii.a Add Dishes +The `add-dish` feature is designed to allow users to add dishes to their menu for keeping track of. The details of the +dishes stored include the dish name, price and discount. The following depicts the procedure for when a dish is added: + 1. User executes the `add-dish` command by typing `add-dish/DISH_NAME/DISH_PRICE`. + 2. This invokes the `MainParser` class which then calls for the `addDish` function in the `DishParser` class. + 3. Next, `addDish` calls for the functions `addDishCommandChecker` and `duplicateDishChecker` in the same class to + ensure that the user's input is valid. + 4. If it is valid, `addDish` creates a new instance of `Dish` and adds it to the `menu` in the `Menu` class. + 5. Lastly, `printAddDishMessage` in the `DishUI` class is called to display a confirmation message to the user. + +This is also illustrated in the sequence diagram below. + +![add](Diagrams/dish/addDish.png) + +### 2.ii.b Remove Dish +The `remove-dish` feature is designed to allow users to remove dishes from their menu that are no longer needed. The +following depicts the procedure for when a dish is removed: + 1. User executes the `remove-dish` command by typing `remove-dish/DISH_INDEX`. + 2. This invokes the `MainParser` class which then calls for the `removeDish` function in the `DishParser` class. + 3. Next, `removeDish` calls for the functions `removeDishCommandChecker` in the same class to ensure that the + user's input is valid. + 4. If it is valid, `removeDish` removes the instance of `Dish` at `DISH_INDEX` from the `menu` in the `Menu` class. + 5. Lastly, `printRemoveDishMessage` in the `DishUI` class is called to display a confirmation message to the user. + +This is also illustrated in the sequence diagram below. + +![add](Diagrams/dish/removeDish.png) + +### 2.ii.c Edit Dish +The `edit-dish` feature is designed to allow users to edit the prices of the dishes in their menu. The following +depicts the procedure for when a dish's price is edited: + 1. User executes the `edit-dish` command by typing `edit-dish/DISH_INDEX/NEW_PRICE`. + 2. This invokes the `MainParser` class which then calls for the `editDish` function in the `DishParser` class. + 3. Next, `editDish` calls for the functions `editDishCommandChecker` in the same class to ensure that the + user's input is valid. + 4. If it is valid, `editDish` calls for the `setPrice` function in the `Dish` class to set the price of the + instance of `Dish` at `DISH_INDEX` to `NEW_PRICE`. + 5. Lastly, `printEditDishMessage` in the `DishUI` class is called to display a confirmation message to the user. + +This is also illustrated in the sequence diagram below. + +![add](Diagrams/dish/editDish.png) + +### 2.ii.d Discount Dish +The `discount-dish` feature is designed to allow users to add discounts to the dishes in their menu. The following +depicts the procedure for when a discount is added to a dish: +1. User executes the `discount-dish` command by typing `discount-dish/DISH_INDEX/DISCOUNT`. +2. This invokes the `MainParser` class which then calls for the `discountDish` function in the `DishParser` class. +3. Next, `discountDish` calls for the functions `discountDishCommandChecker` in the same class to ensure that the + user's input is valid. +4. If it is valid, `discountDish` calls for the `setDiscount` function in the `Dish` class to set the discount of the + instance of `Dish` at `DISH_INDEX` to `DISCOUNT`. +5. Lastly, `printDiscountDishMessage` in the `DishUI` class is called to display a confirmation message to the user. + +### 2.ii.e List Dishes +The `list-dish` feature is designed to allow users view all the dishes in their menu. The prices of each dish are also +displayed. The following depicts the procedure for when a dish's price is edited: +1. User executes the `list-dish` command by typing `list-dish`. +2. This invokes the `MainParser` class which then calls for the `listDish` function in the `DishParser` class. +3. Next, `listDish` calls for either the function `printMenu` or the function `printEmptyMenu` in the `DishUI` class + depending on whether the user's menu is empty. +4. `printMenu` displays all the dishes in the menu while `printEmptyMenu` displays an empty menu. + +### 2.iii.a Add Ingredient +The mechanism of adding an ingredient into the ingredient list is facilitated by `IngredientParser`. It creates a new +instance of `Ingredient`, and adds it to the existing instance of `IngredientList`. It then calls a method from +`IngredientUI` to display a confirmation message to the user. + +![addIngredient](Diagrams/ingredient/addIngredient.png) + +### 2.iii.b Remove Ingredient +The mechanism of removing an ingredient from the ingredient list is facilitated by `IngredientParser`. It identifies +the index of the ingredient to be removed from the existing instance of `IngredientList` and removes that instance of +`Ingredient` from the list. It then calls a method from `IngredientUI` which displays to the user that the deletion was +successful. + +### 2.iii.c Find Expired Ingredients +The mechanism of finding expired ingredients is facilitated by `IngredientParser` as well as the Java `LocalDate` +class. `IngredientParser` converts the input String into a `LocalDate` object and calls a method from `IngredientUI`. +This method loops through the current `IngredientList` and finds all instances of `Ingredient` with an expiry date +before the input `LocalDate` object. It then displays to the user the list of ingredients that are expired, or informs +the user that no ingredients are expired. + +### 2.iii.d List Ingredients +The mechanism for listing all existing ingredients in the ingredient list is facilitated by `IngredientParser`. It +checks if the existing instance of `IngredientList` is empty or not, and calls a method from `IngredientUI` to +display the entire list of ingredients and their quantities to the user. + +### 2.iv.a Add Finance +The mechanism of adding an account into the financeList is facilitated by `FinanceParser`. It is firstly identified +by mainParser to handle add finance command. Then, it creates new `Finance` object with user command. Next, it will add +the Finance object to the FinanceList and add the account number to the totalAccount. Lastly, it will call +printAddFinanceMessage() of FinanceUI to show the result. + +![add](Diagrams/finance/addFinance.png) + +### 2.iv.b Remove Finance +The mechanism of removing an account from the financeList is facilitated by `FinanceParser`. It is firstly identified +by mainParser to handle remove finance command. Then, it generates the deletedFinanceIndex with user command. Next, it +will get the deletedAccount using get method from the financeList. Besides, it will remove the deletedAccount from the +financeList and the totalAccount will minus the account number of deletedAccount. Lastly, it will call +printRemoveFinanceMessage() of FinanceUI to show the result. + +![remove](Diagrams/finance/removeFinance.png) + +### 2.iv.c Edit Finance +The mechanism of editing an account form the financeList is facilitated by `FinanceParser`. It is firstly identified +by mainParser to handle edit finance command. Then, it generates the editedFinanceIndex with user command. Next, it +will get the editedAccount using get method from the financeList. Besides,it will edit the editedAccount using setAccount +method and change the totalAccount number. Lastly, it will call printEditFinanceMessage() of FinanceUI to +show the result. + +![edit](Diagrams/finance/editFinance.png) + +### 2.iv.d Show Finance Feature +The mechanism of showing total account from the financeList is facilitated by `FinanceParser`. It is firstly +identified by MainParser to handle show finance command. Then, it will call printTotalAccount() of FinanceUI to +show the total account to the user. + +### 2.iv.e List Finances +The mechanism of listing the accounts from the financeList is facilitated by `FinanceParser`. It is firstly +identified by MainParser to handle list finance command. Then, it will check the list size. If the size is 0, then +it will call printEmptyListMessage() of FinanceUI. If the size is larger than 0, it will call printFinanceListMessage() +of FinanceUI and print all the accounts in financeList to the user. + +### 2.v.a Save Storage +The mechanism of saving all the data is facilitated by `Storage`. After executing the bye command, the +program goes into saving data stage automatically. It will call saveStorage() method whose parameters are the lists need +to save to file in the `Storage` and open a default file with fileWriter. Next, it goes in a loop to get each target object +in the list. In `Storage`, it will encode the target object based its toString format and then write into the file. +Lastly, it will have four loops for the four different lists. Given below is the sequence diagram when storing +employeeList and ingredientList. + +![save](Diagrams/storage/save.png) + +### 2.v.b Load Storage +The mechanism of loading all the data from the storage file is facilitated by `Storage`. It will firstly create a file +object with the default path. Secondly, it will check whether the save file exists. If the file does not exist, it will print +the file not found Message. If exists, it will create a scanner to read the file and generate four different parsers. +It goes in a loop until there are no more lines to read. Then, it will create new object according to the lines start with. +Lastly, it will use `loadEmployeeFromStorage` method to different object to add them into target lists. Given below +is the sequence diagram of loading `Employee` from the Storage. + +![load](Diagrams/storage/load.png) + +## 3. Appendix + +### 3.i Product Scope + +**Target user profile:** +* needs to manage a significant amount of different types of restaurant data +* prefers using a desktop application +* is able to type quickly +* prefers typing as compared to mouse interactions +* is reasonably comfortable using CLI apps + +**Value proposition:** manage restaurant data faster than a typical mouse/_graphical user interface (GUI)_ driven +application + +### 3.ii User Stories + +Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` + +| **Priority** | **As a ...** | **I want to ...** | **So that I can ...** | +| ------------ | ------------- | ------------- | ------------- | +| `* * *` | restaurant manager | view all my current employees | keep track of them | +| `* * *` | restaurant manager | add new employees | keep track of newly hired employees | +| `* * *` | restaurant manager | delete employees | remove entries I no longer need | +| `* * *` | restaurant manager | keep track of the ingredients I have left | know when to order more | +| `* * *` | restaurant manager | add new ingredients | adjust to changes in my menu | +| `* * *` | restaurant manager | delete ingredients | remove entries I no longer need | +| `* * *` | restaurant manager | view my menu | keep track of it | +| `* * *` | restaurant manager | add new dishes into my menu | increase the variety of my menu | +| `* * *` | restaurant manager | remove dishes from my menu | focus more on my other dishes | +| `* *` | restaurant manager | view all my employees' salaries | better manage my finances | +| `* *` | restaurant manager | increase my employees' salaries | give them a raise when they are performing well | +| `* *` | restaurant manager | decrease my employees' salaries | reduce my expenses when the cash flow is tight | +| `* *` | restaurant manager | keep track of my employees' offs | plan my manpower effectively | +| `* *` | restaurant manager | change the price of a dish | adjust it according to other external factors | +| `* *` | restaurant manager | add a discount to a dish | organise promotions to attract more customers | +| `* *` | restaurant manager | add daily earnings and expenditure | keep track of my finances | +| `*` | restaurant manager | check for loss of utensils | account for them and order more accordingly | +| `*` | restaurant manager | check the prices for advertisements | evaluate the benefits they bring | +| `*` | restaurant manager | view customer complaints | improve my restaurant based on their feedback | +| `*` | restaurant manager | keep track of popular dishes | plan the menu in the way that maximises my revenue | + +### 3.iii Non Functional Requirements +1. You need to have a _mainstream operating system (OS)_ with Java `11` or above installed. +2. For normal usage without noticeable lag, total data entries stored should be less than 1000. +3. To be faster than a typical mouse/GUI driven application, you need to have an above average typing speed for regular + English text (i.e. not code, not system admin commands). + +### 3.iv Glossary +* **Mainstream OS:** Windows, Linux, Unix, macOS +* **GUI:** A type of user interface that allows users to interact with applications through graphical icons. diff --git a/docs/Diagrams/Finance.png b/docs/Diagrams/Finance.png new file mode 100644 index 0000000000..f06f3c4832 Binary files /dev/null and b/docs/Diagrams/Finance.png differ diff --git a/docs/Diagrams/dish/Dish.png b/docs/Diagrams/dish/Dish.png new file mode 100644 index 0000000000..f440d803d7 Binary files /dev/null and b/docs/Diagrams/dish/Dish.png differ diff --git a/docs/Diagrams/dish/addDish.png b/docs/Diagrams/dish/addDish.png new file mode 100644 index 0000000000..468579f19f Binary files /dev/null and b/docs/Diagrams/dish/addDish.png differ diff --git a/docs/Diagrams/dish/editDish.png b/docs/Diagrams/dish/editDish.png new file mode 100644 index 0000000000..2a7841fde2 Binary files /dev/null and b/docs/Diagrams/dish/editDish.png differ diff --git a/docs/Diagrams/dish/removeDish.png b/docs/Diagrams/dish/removeDish.png new file mode 100644 index 0000000000..ba284bb9e3 Binary files /dev/null and b/docs/Diagrams/dish/removeDish.png differ diff --git a/docs/Diagrams/employee/add_employee_sequence_diagram.png b/docs/Diagrams/employee/add_employee_sequence_diagram.png new file mode 100644 index 0000000000..01a667e432 Binary files /dev/null and b/docs/Diagrams/employee/add_employee_sequence_diagram.png differ diff --git a/docs/Diagrams/employee/employee_class_diagram.png b/docs/Diagrams/employee/employee_class_diagram.png new file mode 100644 index 0000000000..0524342135 Binary files /dev/null and b/docs/Diagrams/employee/employee_class_diagram.png differ diff --git a/docs/Diagrams/finance/addFinance.png b/docs/Diagrams/finance/addFinance.png new file mode 100644 index 0000000000..6ee53e7ffc Binary files /dev/null and b/docs/Diagrams/finance/addFinance.png differ diff --git a/docs/Diagrams/finance/editFinance.png b/docs/Diagrams/finance/editFinance.png new file mode 100644 index 0000000000..d8d682597c Binary files /dev/null and b/docs/Diagrams/finance/editFinance.png differ diff --git a/docs/Diagrams/finance/removeFinance.png b/docs/Diagrams/finance/removeFinance.png new file mode 100644 index 0000000000..94a61d8f38 Binary files /dev/null and b/docs/Diagrams/finance/removeFinance.png differ diff --git a/docs/Diagrams/ingredient/Ingredient.png b/docs/Diagrams/ingredient/Ingredient.png new file mode 100644 index 0000000000..5ad2221d2d Binary files /dev/null and b/docs/Diagrams/ingredient/Ingredient.png differ diff --git a/docs/Diagrams/ingredient/addIngredient.png b/docs/Diagrams/ingredient/addIngredient.png new file mode 100644 index 0000000000..33c8a34148 Binary files /dev/null and b/docs/Diagrams/ingredient/addIngredient.png differ diff --git a/docs/Diagrams/storage/Storage.png b/docs/Diagrams/storage/Storage.png new file mode 100644 index 0000000000..6a5cd5a196 Binary files /dev/null and b/docs/Diagrams/storage/Storage.png differ diff --git a/docs/Diagrams/storage/load.png b/docs/Diagrams/storage/load.png new file mode 100644 index 0000000000..b65c5aac6e Binary files /dev/null and b/docs/Diagrams/storage/load.png differ diff --git a/docs/Diagrams/storage/save.png b/docs/Diagrams/storage/save.png new file mode 100644 index 0000000000..1b3d4f580a Binary files /dev/null and b/docs/Diagrams/storage/save.png differ diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..9a2e9646ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,9 @@ -# Duke +# Restaurant Buddy -{Give product intro here} +Restaurant Buddy is a desktop application designed for restaurant managers to help **keep track of restaurant data** +such as its employees, dishes in the menu and ingredients in storage via a **Command Line Interface (CLI)**. +In particular, Restaurant Buddy was developed specifically for users who can type fast and prefer typing to other +means of input. Useful links: * [User Guide](UserGuide.md) diff --git a/docs/Team pictures/LiuZehang.jpg b/docs/Team pictures/LiuZehang.jpg new file mode 100644 index 0000000000..71458bc8c0 Binary files /dev/null and b/docs/Team pictures/LiuZehang.jpg differ diff --git a/docs/Team pictures/cheokfeng.jpg b/docs/Team pictures/cheokfeng.jpg new file mode 100644 index 0000000000..777823e4a7 Binary files /dev/null and b/docs/Team pictures/cheokfeng.jpg differ diff --git a/docs/Team pictures/jerrell.jpg b/docs/Team pictures/jerrell.jpg new file mode 100644 index 0000000000..96a1492920 Binary files /dev/null and b/docs/Team pictures/jerrell.jpg differ diff --git a/docs/Team pictures/kairos.png b/docs/Team pictures/kairos.png new file mode 100644 index 0000000000..f977d095a0 Binary files /dev/null and b/docs/Team pictures/kairos.png differ diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..0bcddd796a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,42 +1,462 @@ # User Guide -## Introduction +Restaurant Buddy is a desktop application designed for restaurant managers to help **keep track of restaurant data** +such as its employees, dishes in the menu and ingredients in storage via a **Command Line Interface (CLI)**. +In particular, Restaurant Buddy was developed specifically for users who can type fast and prefer typing to other +means of input. -{Give a product intro} +1. [Quick Start](#1-quick-start-for-windows) +2. [Features](#2-features) + 1. [Employee](#2i-employee) + 1. [Adding an employee: `add-employee`](#2ia-adding-an-employee-add-employee) + 2. [Removing an employee: `remove-employee`](#2ib-removing-an-employee-remove-employee) + 3. [Listing all employees: `list-employee`](#2ic-listing-all-employees-list-employee) + 2. Dish + 1. [Adding a dish: `add-dish`](#2iia-adding-a-dish-add-dish) + 2. [Removing a dish: `remove-dish`](#2iib-removing-a-dish-remove-dish) + 3. [Editing a dish's price: `edit-dish`](#2iic-editing-a-dishs-price-edit-dish) + 4. [Adding a discount to a dish: `discount-dish`](#2iid-adding-a-discount-to-a-dish-discount-dish) + 5. [Listing all dishes: `list-dish`](#2iie-listing-all-dishes-list-dish) + 3. Ingredient + 1. [Adding an ingredient: `add-ingredient`](#2iiia-adding-an-ingredient-add-ingredient) + 2. [Removing an ingredient: `remove-ingredient`](#2iiib-removing-an-ingredient-remove-ingredient) + 3. [Listing all ingredients: `list-ingredient`](#2iiic-listing-all-ingredients-list-ingredient) + 4. [Finding expired ingredients: `find-expired-ingredient`](#2iiid-finding-expired-ingredients-find-expired-ingredient) + 4. Finance + 1. [Adding a finance record: `add-finance`](#2iva-adding-a-finance-record-add-finance) + 2. [Removing a finance record: `remove-finance`](#2ivb-removing-a-finance-record-remove-finance) + 3. [Editing a finance record: `edit-finance`](#2ivc-editing-a-finance-record-edit-finance) + 4. [Showing total account of finance records: `show-finance`](#2ivd-showing-total-account-of-finance-records-show-finance) + 5. [Listing all finance records: `list-finance`](#2ive-listing-all-finance-records-list-finance) + 5. [Listing all commands: `help`](#2v-listing-all-commands-help) + 6. [Exiting the program: `bye`](#2vi-exiting-the-program-bye) +3. [FAQ](#3-faq) +4. [Command Summary](#4-command-summary) -## Quick Start +--- -{Give steps to get started quickly} +## 1. Quick Start for Windows +1. Ensure you have **Java 11** or above installed on your Windows computer. +2. Download the latest `tp.jar` from [here](https://github.com/AY2122S1-CS2113T-T12-4/tp/releases). +3. Copy the file to the folder you want to use as the _home folder_ for Restaurant Buddy. +4. Navigate to your _home folder_ as chosen in step 3 in command prompt. + 1. Search for `cmd` in your search bar. + 2. Then, press enter to open command prompt. + 3. Next enter `cd DIRECTORY_NAME` until you reached your _home folder_. e.g. `cd desktop` navigates to your + desktop. +5. Type `java -jar tp.jar` in the command prompt and press enter to run Restaurant Buddy. +6. Type a command in Restaurant Buddy's command box and press enter to execute it. +7. Refer to the **[Features](#2-features)** below for details of all available commands. -1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +--- -## Features +## 2. Features +**Notes about the command format:** + * Words in UPPER_CASE are the parameters to be supplied by the user. + e.g. in `add-employee/EMPLOYEE_NAME/PHONE_NUMBER/EMPLOYMENT_STATUS/SALARY`, `EMPLOYEE_NAME` and `PHONE_NUMBER` are + parameters which can be used as `add-employee/John/81145812/PERM/6000`. -{Give detailed description of each feature} +### 2.i Employee +Employee refers to any person working at your restaurant. Restaurant Buddy needs some details from you about the employees. +This includes: employee name, phone number, employment status and salary. -### Adding a todo: `todo` -Adds a new item to the list of todo items. +### 2.i.a Adding an employee: `add-employee` +Adds an employee to the employee list. -Format: `todo n/TODO_NAME d/DEADLINE` +Format: `add-employee/EMPLOYEE_NAME/PHONE_NUMBER/EMPLOYMENT_STATUS/SALARY` + * `PHONE_NUMBER` must be a positive integer. + * `EMPLOYMENT_STATUS` must be either PERM, TEMP or ADHOC. + * `SALARY` must be a positive integer. -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. +Example: +`add-employee/John/81145812/PERM/6000` Adds the employee named `John` with `81145812` as his phone number to the +employee list. In addition, he/she is a `PERM` staff and gets paid $`6000`. +``` +--------------------------------------------- + I have added: + John - 81145812 - PERM STAFF - $6000 + You now have 1 employees. +--------------------------------------------- +``` -Example of usage: +### 2.i.b Removing an employee: `remove-employee` +Removes an employee from the employee list. -`todo n/Write the rest of the User Guide d/next week` +Format: `remove-employee/EMPLOYEE_INDEX` + * Removes the employee at the specified `EMPLOYEE_INDEX`. + * `EMPLOYEE_INDEX` refers to the index number shown in the displayed employee list. + * `EMPLOYEE_INDEX` must be a positive integer. -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +Example: +`remove-employee/1` Removes the 1st employee from the employee list. +``` +--------------------------------------------- + I have deleted: + John - 81145812 - PERM STAFF - $6000 +--------------------------------------------- +``` -## FAQ +### 2.i.c Listing all employees: `list-employee` +Lists all employees in the employee list. -**Q**: How do I transfer my data to another computer? +Format: `list-employee` -**A**: {your answer here} +Example: +`list-employee` +``` +--------------------------------------------- + Here are the employees in your list: + 1. Don - 81145812 - PERM STAFF - $1000 + 2. Jack - 83408743 - PERM STAFF - $2000 + 3. Alice - 81230844 - TEMP STAFF - $900 + 4. David - 81230412 - ADHOC STAFF - $100 +--------------------------------------------- +``` -## Command Summary +### 2.ii.a Adding a dish: `add-dish` +Adds a dish to the menu. -{Give a 'cheat sheet' of commands here} +Format: `add-dish/DISH_NAME/PRICE` + * `PRICE` must be a positive number. + * `PRICE` would only be displayed up to 2 decimal places. -* Add todo `todo n/TODO_NAME d/DEADLINE` +Example: +`add-dish/Pizza/5.80` Adds `Pizza` which costs `$5.80` to the menu. +``` +--------------------------------------------- + I have added the following dish to the menu: + 1. Pizza - $5.8 +--------------------------------------------- +``` + +### 2.ii.b Removing a dish: `remove-dish` +Removes a dish from the menu. + +Format: `remove-dish/DISH_INDEX` + * Removes the dish at the specified `DISH_INDEX`. + * `DISH_INDEX` refers to the index number shown in the displayed menu. + * `DISH_INDEX` must be a positive integer. + +Example: +`remove-dish/1` Removes the 1st dish from the menu. +``` +--------------------------------------------- + I have removed the following dish from the menu: + 1. Cake - $7.5 +--------------------------------------------- +``` + +### 2.ii.c Editing a dish's price: `edit-dish` +Edits the price of a dish in the menu. + +Format: `edit-dish/DISH_INDEX/NEW_PRICE` + * Updates the price of the dish at the specified `DISH_INDEX` to `NEW_PRICE`. + * `DISH_INDEX` refers to the index number shown in the displayed finance list. + * `DISH_INDEX` must be a positive integer. + * `NEW_PRICE` must be a number. + * `NEW_PRICE` would only be displayed up to 2 decimal places. + +Example: +`edit-dish/1/10` Increases the price of the 1st dish in the menu to `$10`. +``` +--------------------------------------------- + Got it! The updated price of the dish is as follows: + 1. Steak - $10.0 +--------------------------------------------- +``` + +### 2.ii.d Adding a discount to a dish: `discount-dish` +Adds a discount to a dish in the menu. + +Format: `discount-dish/DISH_INDEX/DISCOUNT(%)` + * Adds a `DISCOUNT` to the dish at the specified `DISH_INDEX`. + * `DISH_INDEX` refers to the index number shown in the displayed finance list. + * `DISH_INDEX` must be a positive integer. + * `DISCOUNT` must be a positive number. + * Maximum value `DISCOUNT` is 100 i.e. maximum possible discount is 100%. + * Discounted price would only be displayed up to 2 decimal places. + +Example: +`discount-dish/1/30` Adds a `30%` discount to the 1st dish in the menu. +``` +--------------------------------------------- + Got it! I have added the discount to the dish! + The discounted price is as follows: + 1. Roast Chicken - $10.0 ---> $7.0 +--------------------------------------------- +``` + +### 2.ii.e Listing all dishes: `list-dish` +Lists all dishes in the menu. + +Format: `list-dish` + * Prices would only be displayed up to 2 decimal places. + +Example: +`list-dish` +``` +--------------------------------------------- + Here are the dishes in your menu: + 1. Laksa - $5.8 + 2. Curry Chicken - $4.0 ---> $2.5 + 3. Prata - $2.0 + 4. Steamed Fish - $6.3 +--------------------------------------------- +``` + +### 2.iii.a Adding an ingredient: `add-ingredient` +Adds an ingredient to the ingredient list. + +Format: `add-ingredient/INGREDIENT_NAME/QUANTITY/PRICE/EXPIRY_DATE` + * `INGREDIENT_NAME` must be a string. + * `QUANTITY` must be a positive, non-zero integer. + * `PRICE` must be a positive number of at least `0.01`. All values will be rounded to 2 decimal places. + * `EXPIRY_DATE` must be a valid date in YYYY-MM-DD format. + +Example: +`add-ingredient/Carrot/50/1.50/2021-10-21` Adds `50` `carrots` with unit price `1.50` and expiry date `2021-10-21` +to the ingredient list. +``` +--------------------------------------------- + Got it. This ingredient was added: + Ingredient Name: Carrot + Ingredient Quantity: 50 + Ingredient Unit Price: 1.50 + Expiry Date: 2021-10-21 + + Carrot [50] [$1.50] [2021-10-21] +--------------------------------------------- +``` + +### 2.iii.b Removing an ingredient: `remove-ingredient` +Removes an ingredient from the ingredient list. + +Format: `remove-ingredient/INGREDIENT_INDEX` + * Removes the ingredient at the specified `INGREDIENT_INDEX`. + * `INGREDIENT_INDEX` refers to the index number shown in the displayed ingredient list. + * `INGREDIENT_INDEX` must be a positive integer. + +Example: +`remove-ingredient/1` Removes the 1st ingredient from the ingredient list. +``` +--------------------------------------------- + Got it. This ingredient was deleted: + Strawberry [30] [$1.00] [2021-10-30] +--------------------------------------------- +``` + +### 2.iii.c Listing all ingredients: `list-ingredient` +Lists all ingredients in the ingredient list. + +Format: `list-ingredient` + +Example: +`list-ingredient` +``` +--------------------------------------------- + Here are the ingredients in your list: + 1. Potato [55] [$1.50] [2021-11-01] + 2. Stock Cube [30] [$0.50] [2021-12-20] + 3. Chilli [23] [$0.70] [2021-11-18] + 4. Onion [44] [$1.00] [2021-10-29] +--------------------------------------------- +``` + +### 2.iii.d Finding expired ingredients: `find-expired-ingredient` +Finds all ingredients from the ingredient list that are expired on a particular +date. There is some flexibility here for you to choose the input date according +to your needs. For instance, you can enter a future date to check which ingredients +would be expired by that date, and hence plan your inventory accordingly. If you +wish to find currently expired ingredients, simply enter the current date as +the input date. + +Format: `find-expired-ingredient/INPUT_DATE` + * `INPUT_DATE` must be a valid date in YYYY-MM-DD format. + +Example: +`find-expired-ingredient/2021-11-05` +``` +--------------------------------------------- + These ingredients are expired: + Potato [55] [$1.50] [2021-11-01] + Onion [44] [$1.00] [2021-10-29] +--------------------------------------------- +``` + +### 2.iv.a Adding a finance record: `add-finance` +Adds a finance record to the finance list. + +Format: `add-finance/DATE/ACCOUNT` + * `DATE` must be a valid date in YYYY-MM-DD format + * `ACCOUNT` must be an integer. +Example: +`add-finance/2021-10-23/5000` Adds a finance account of `$5000` on `23 October 2021`. +``` +--------------------------------------------- + Got it. This account is added: + Finance Date: 2021-10-23 + Account: 5000 +--------------------------------------------- +``` + +### 2.iv.b Removing a finance record: `remove-finance` +Removes the specified finance record from the finance list. + +Format: `remove-finance/FINANCE_INDEX` + * Removes the finance record at the specified `FINANCE_INDEX`. + * `FINANCE_INDEX` refers to the index number shown in the displayed finance list. + * `FINANCE_INDEX` must be a positive integer. + +Example: +`remove_finance/1` Removes the 1st finance record in the finance list. +``` +--------------------------------------------- + Got it. This account was deleted: + 16 Feb 2021 $3980 +--------------------------------------------- +``` + +### 2.iv.c Editing a finance record: `edit-finance` +Edits a finance record in the finance list. + +Format: `edit-finance/FINANCE_INDEX/NEW_ACCOUNT` + * Updates the account of the finance record at the specified `FINANCE_INDEX` to `NEW_ACCOUNT`. + * `FINANCE_INDEX` refers to the index number shown in the displayed finance list. + * `FINANCE_INDEX` must be a positive integer. + * `NEW_ACCOUNT` must be an integer. + +Example: +`edit-finance/1/9000` Increases the account of the 1st finance record in the finance list to `$9000`. +``` +--------------------------------------------- + Got it. This account is edited: + Finance Date: 31 Aug 2021 + Account: 9000 +--------------------------------------------- +``` + +### 2.iv.d Showing total account of finance records: `show-finance` +Shows the total account of all finance records in the finance list. + +Format: `show-finance` + +Example: +`show-finance` +``` +--------------------------------------------- + Here is the total account you have: $15324 +--------------------------------------------- +``` + +### 2.iv.e Listing all finance records: `list-finance` +Lists all finance records in the finance list. + +Format: `list-finance` + +Example: +`list-finance` +``` +--------------------------------------------- + Here are the accounts in your list: + 1. 23 Oct 2021 9000 + 2. 11 Jan 2021 8432 + 3. 7 Nov 2021 7819 + 4. 27 Sep 2021 10031 +--------------------------------------------- +``` + +### 2.v Listing all commands: `help` + +Lists all commands. + +Format: `help` + +Example: `help` + +``` +--------------------------------------------- +Hello! You seem like you need a hand to get started. +To interact with Restaurant Buddy, type in any of the following commands and press Enter! +The words that are CAPITALISED are the parameters that you can change. +--------------------------------------------- +- Employee Commands: +add-employee/EMPLOYEE_NAME/PHONE_NUMBER/EMPLOYMENT_STATUS/SALARY +remove-employee/EMPLOYEE_INDEX +list-employee +--------------------------------------------- +- Menu Commands: +add-dish/DISH_NAME/PRICE +remove-dish/DISH_INDEX +edit-dish/DISH_INDEX/NEW_PRICE +discount-dish/DISH_INDEX/DISCOUNT(%) +list-dish +--------------------------------------------- +- Ingredient Commands: +add-ingredient/INGREDIENT_NAME/QUANTITY +remove-ingredient/INGREDIENT_INDEX +list-ingredient +--------------------------------------------- +- Finance Commands: +add-finance/DATE/ACCOUNT +remove-finance/FINANCE_INDEX +edit-finance/FINANCE_INDEX/NEW_ACCOUNT +show-finance +list-finance +--------------------------------------------- +To exit the program safely, please type in the command: +bye +--------------------------------------------- +If you require more help, please refer to the User Guide on Github. +Let's get started at once! Feel free to try out the commands :D +--------------------------------------------- +``` + +### 2.vi Exiting the program: `bye` +Exits the program. + +Format: `bye` + +Example: +`bye` +``` +--------------------------------------------- + Thank you. Goodbye! +--------------------------------------------- +--------------------------------------------- + Storage saved successfully. + See you again! +--------------------------------------------- +``` + +--- + +## 3. FAQ +**Q**: How do I transfer my data to another computer? + +**A**: Copy the _home folder_ of Restaurant Buddy over to the other computer and run it as usual. + +--- + +## 4. Command Summary + +| Command | Format | +| ------------ | ------------- | +| add-employee | `add-employee/EMPLOYEE_NAME/PHONE_NUMBER/EMPLOYMENT_STATUS/SALARY` | +| remove-employee | `remove-employee/EMPLOYEE_INDEX` | +| list-employee | `list-employee` | +| add-dish | `add-dish/DISH_NAME/PRICE` | +| remove-dish | `remove-dish/DISH_INDEX` | +| edit-dish | `edit-dish/DISH_INDEX/NEW_PRICE` | +| discount-dish | `discount-dish/DISH_INDEX/DISCOUNT(%)` | +| list-dish | `list-dish` | +| add-ingredient | `add-ingredient/INGREDIENT_NAME/QUANTITY/PRICE/EXPIRY_DATE` | +| remove-ingredient | `remove-ingredient/INGREDIENT_INDEX` | +| list-ingredient | `list-ingredient` | +| find-expired-ingredient | `find-expired-ingredient/INPUT_DATE` | +| add-finance | `add-finance/DATE/ACCOUNT` | +| remove-finance | `remove-finance/FINANCE_INDEX` | +| edit-finance | `edit-finance/FINANCE_INDEX/NEW_ACCOUNT` | +| show-finance | `show-finance` | +| list-finance | `list-finance` | +| help | `help` | +| bye | `bye` | diff --git a/docs/team/LIU ZEHANG.md b/docs/team/LIU ZEHANG.md new file mode 100644 index 0000000000..39823f29c7 --- /dev/null +++ b/docs/team/LIU ZEHANG.md @@ -0,0 +1,24 @@ +# LIU ZEHANG - Project Portfolio Page + +## Project: Restaurant Buddy + +### Overview +Restaurant Buddy is a desktop application designed for restaurant managers to help **keep track of restaurant data** +such as its employees, dishes in the menu and ingredients in storage via a **Command Line Interface (CLI)**. +In particular, Restaurant Buddy was developed specifically for users who can type fast and prefer typing to other +means of input. + +### Summary of Contributions +Given below are my contributions to the project. +Code contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=T12-4&sort=groupTitle&sortWithin=title&since=2021-09-25&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=Cesare4869&tabRepo=AY2122S1-CS2113T-T12-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false) +- Enhancements implemented: + - Achieve code consistency including changing the type of class attributes and + editing storage load and save functions. +- Contributions to the UG: + - Edited the documentation for `Finance` and `addFinance`. +- Contributions to the DG: + - Added the description and diagrams for `Finance` part and `Storage` part. +- Project Management: + - keep the project progress, check and solve the issues in the issue tracker. + + \ No newline at end of file diff --git a/docs/team/jerrelllzw.md b/docs/team/jerrelllzw.md new file mode 100644 index 0000000000..3bbe13f4b0 --- /dev/null +++ b/docs/team/jerrelllzw.md @@ -0,0 +1,45 @@ +# Jerrell Low - Project Portfolio Page + +## Project: Restaurant Buddy +Restaurant Buddy is a desktop CLI application used to help restaurant managers keep track of their data. It is written +in Java and has about 3 kLoC. + +## Contributions + +* **New feature:** Added the ability to edit dish prices. + * What it does: Allow users to edit the prices of existing dishes in their menu. + * Justification: The price of dishes are not usually fixed as they are based on many external factors. This feature + improves the product significantly as it provide users a convenient way to edit the prices of their dishes. + + +* **New feature:** Added the ability to add discounts to a dish. + * What it does: Allows users to add discounts to existing dishes in their menu. + * Justification: In the restaurant business, promotions are often used to increase publicity and exposure. This + feature give users an easy way to keep track of the prices of their dishes during promotions. + + +* **Code contributed:** [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2021-09-25&tabOpen=true&tabType=authorship&zFR=false&tabAuthor=jerrelllzw&tabRepo=AY2122S1-CS2113T-T12-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false) + + +* **Project management:** + * Managed releases `v1.0` - `v2.1` (3 releases) + * Summarized tasks to be done + + +* **Community:** + * Reported bugs and suggestions for other teams in the class + + +
+ + +## Documentation + * **User Guide:** + * Added the sections Quick Start, FAQ and Command Summary. + * Added documentation for the features `add-dish`, `remove-dish`, `edit-dish`, `discount-dish` and `list-dish` + * **Developer Guide:** + * Added the sections Product Scope, User Stories, Non-Functional Requirements and Glossary. + * Added implementation details for the features `add-dish`, `remove-dish`, `edit-dish`, `discount-dish` and + `list-dish` + * Added UML diagram for dish component + * Added sequence diagrams for the features `add-dish`, `remove-dish`, `edit-dish` 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/kairoskoh.md b/docs/team/kairoskoh.md new file mode 100644 index 0000000000..73a1dca957 --- /dev/null +++ b/docs/team/kairoskoh.md @@ -0,0 +1,41 @@ +# Kairos Koh - Project Portfolio Page + +## Project: Restaurant Buddy + +### Overview +Restaurant Buddy is a desktop application designed for restaurant managers to help **keep track of restaurant data** +such as its employees, dishes in the menu and ingredients in storage via a **Command Line Interface (CLI)**. +In particular, Restaurant Buddy was developed specifically for users who can type fast and prefer typing to other +means of input. It is written in Java, and has about 3 kLoC. + +### Summary of Contributions +Given below are my contributions to the project. +- New Feature: Added a help command that allows the user to list all possible commands. + - What it does: This command lists down all the possible commands that is accepted in the application. + - Justification: This allows users to have a quick reference to possible commands through the CLI instead of through + the User Guide. + - Highlights: This command required extensive understanding of the possible commands and is manually included towards + the end of the project. + +- New Feature: Added the ability to interact with the list of employees. + - What it does: These commands allow users to interact with their list of employees. + - Justification: This enables users to keep track of important information of their employees quickly and easily. + - Highlights: Considerable amount of research was conducted through online sources to determine the type of + information that is important to our target users. This enabled our application to be a better fit for them. + +- Code Contributed: [RepoSense link](https://nus-cs2113-ay2122s1.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&since=2021-09-25&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=kairoskoh&tabRepo=AY2122S1-CS2113T-T12-4%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false). +- Project Management: + - Managed release `v2.0` (1 release) on GitHub + - Organised and hosted weekly meetings through Zoom + - Ensured the team is progressing according to schedule +- Enhancements To Existing Features: + - Included an ASCII art of "Restaurant Buddy" in the welcome message (Pull Request [#34](https://github.com/AY2122S1-CS2113T-T12-4/tp/pull/34)) + - Improve output messages to make it more friendly (Pull Request [#71](https://github.com/AY2122S1-CS2113T-T12-4/tp/pull/71)) +- Documentation: + - User Guide: + - Added documentation for the features `help` and `employee` + - Developer Guide + - Added implementation details of the `help` and `employee` features +- Community: + - Reported bugs and suggestions for other teams in the class + - Reviewed PRs (with non-trivial review comments) \ No newline at end of file diff --git a/docs/team/leecheokfeng.md b/docs/team/leecheokfeng.md new file mode 100644 index 0000000000..61e98b23fe --- /dev/null +++ b/docs/team/leecheokfeng.md @@ -0,0 +1,44 @@ +# Lee Cheok Feng - Project Portfolio Page + +## Project: Restaurant Buddy +Restaurant Buddy is a Command Line Interface (CLI) application meant to help +restaurant managers keep track of their restaurant data. Such data includes +their employees, dishes on the menu, ingredient inventory and finances. +Restaurant Buddy is written in Java, and has about 4 kLoC. + +### Summary of Contributions +* New Feature: Added the ability to add, remove and list ingredients. + * What it does: This allows users to display all ingredients on their list, + and interact with the list by adding or removing ingredients. + * Justification: Restaurant managers need to be able to keep track and + take stock of their ingredient inventory. + + +* New Feature: Added the ability to find expired ingredients in the list. + * What it does: This allows users to find ingredients that would be expired + by a certain input date. + * Justification: Restaurant managers have many ingredients and may not be + able to remember which ingredients expire by what date. This feature helps + managers plan ahead on what ingredients they may need to stock up on. + + +* Code Contributed: https://nus-cs2113-ay2122s1.github.io/tp-dashboard/#breakdown=true&search=leecheokfeng + + +* Project Management: + * Recorded notes and minutes from team meetings for easy future reference. + + +* Documentation: + * User Guide: + * Added documentation for the `add-ingredient`, `list-ingredient`, + `remove-ingredient` and `find-expired-ingredient` features. + * Developer Guide: + * Added documentation for the Design Architecture and the Employee and + Ingredient component. + * Added documentation for the Implementation of the Employee and Ingredient + functions. + + +* Community: + * Reported bugs and suggestions for other teams in the class. diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..19e86fe56e --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: seedu.duke.Duke + diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..6da2d975c9 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -1,21 +1,47 @@ package seedu.duke; +import seedu.duke.employee.EmployeeList; +import seedu.duke.ingredient.IngredientList; +import seedu.duke.main.MainParser; +import seedu.duke.main.MainUI; +import seedu.duke.dish.Menu; +import seedu.duke.finance.FinanceList; +import seedu.duke.storage.Storage; + import java.util.Scanner; public class Duke { - /** - * 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()); + EmployeeList employeeList = new EmployeeList(); + Menu menu = new Menu(); + IngredientList ingredientList = new IngredientList(); + FinanceList financeList = new FinanceList(); + + // Load Storage + Storage.loadStorage(employeeList, menu, ingredientList, financeList); + + // Hello + MainUI.printWelcomeMessage(); + + // Active Chat + Scanner input = new Scanner(System.in); + String userInput; + boolean isBye = false; + + while (!isBye) { + //store input into String + userInput = input.nextLine(); + //process input + isBye = MainParser.handleCommand(employeeList, menu, ingredientList, financeList, userInput); + } + + // Bye + MainUI.printGoodbyeMessage(); + + // Save Storage + Storage.saveStorage(employeeList, menu, ingredientList, financeList); + MainUI.printStorageSaved(); } + } diff --git a/src/main/java/seedu/duke/dish/Dish.java b/src/main/java/seedu/duke/dish/Dish.java new file mode 100644 index 0000000000..f521203b19 --- /dev/null +++ b/src/main/java/seedu/duke/dish/Dish.java @@ -0,0 +1,99 @@ +//@@author jerrelllzw + +package seedu.duke.dish; + +/** + * Represents a user's dish. Contains the name, price and discount of the dish. + */ +public class Dish { + + private String name; + private double price; + private double discount; + + /** + * Constructs an instance of Dish. + * + * @param name Name of the dish. + * @param price Price of the dish. + */ + public Dish(String name, double price) { + double roundedPrice = Math.round(price * 100.0) / 100.0; + this.name = name; + this.price = roundedPrice; + this.discount = 0; + } + + /** + * Gets the name of the dish. + * + * @return Name of the dish in String format. + */ + public String getName() { + return this.name; + } + + /** + * Gets the price of the dish. + * + * @return Price of the dish in Double format. + */ + public double getPrice() { + return this.price; + } + + /** + * Sets the price of the dish. + * + * @param price New price of the dish. + */ + public void setPrice(double price) { + double roundedPrice = Math.round(price * 100.0) / 100.0; + this.price = roundedPrice; + } + + /** + * Gets the discount of the dish. + * + * @return Discount of the dish in Double format. + */ + public double getDiscount() { + return this.discount; + } + + /** + * Sets the discount of the dish. + * + * @param discount New discount of the dish. + */ + public void setDiscount(double discount) { + this.discount = discount; + } + + /** + * Gets the discounted price of the dish. + * + * @return Discounted price of the dish in Double format. + */ + public double getDiscountedPrice() { + double discountMultiplier = 1 - getDiscount() / 100; + double discountedPrice = getPrice() * discountMultiplier; + double roundedDiscountedPrice = Math.round(discountedPrice * 100.0) / 100.0; + return roundedDiscountedPrice; + } + + /** + * Gets the discounted price of the dish. + * + * @return Discounted price of the dish in String format. + */ + public String getDiscountedPriceString() { + return "$" + getDiscountedPrice(); + } + + @Override + public String toString() { + return name + " - $" + getPrice(); + } + +} diff --git a/src/main/java/seedu/duke/dish/DishParser.java b/src/main/java/seedu/duke/dish/DishParser.java new file mode 100644 index 0000000000..bcef2818d0 --- /dev/null +++ b/src/main/java/seedu/duke/dish/DishParser.java @@ -0,0 +1,253 @@ +//@@author jerrelllzw + +package seedu.duke.dish; + +import seedu.duke.main.MainUI; + +/** + * Contains all Dish related methods. + * Deals with the user's Dish related input commands. + */ +public class DishParser { + + /** + * Checks whether an add-dish command is in the correct format. + * + * @param command User's command in ArrayList format. + * @return Boolean representing whether the add-dish command is in the correct format. + */ + public boolean addDishCommandChecker(String[] command) { + try { + boolean emptyDescription = command[1].stripLeading().stripTrailing().equals(""); + if (emptyDescription) { + MainUI.printWrongCommandMessage(); + return false; + } + double dishPrice = Double.parseDouble(command[2]); + boolean negativePrice = dishPrice < 1; + if (negativePrice) { + DishUI.printInvalidPriceMessage(); + return false; + } + } catch (ArrayIndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidPriceMessage(); + return false; + } + return true; + } + + /** + * Checks whether the dish to be added is already in the menu. + * + * @param dishName Name of the dish to be added. + * @param menu Menu of the user. + * @return Boolean representing whether the dish to be added is already in the menu. + */ + public boolean duplicateDishChecker(String dishName, Menu menu) { + for (int i = 0; i < menu.menu.size(); i++) { + if (menu.menu.get(i).getName().equals(dishName)) { + DishUI.printDuplicateDishMessage(); + return true; + } + } + return false; + } + + /** + * Adds a new dish to the menu. + * + * @param command User's command in ArrayList format. + * @param menu User's menu. + */ + public void addDish(String[] command, Menu menu) { + boolean isValidAddDishCommand = addDishCommandChecker(command); + boolean noDuplicateDishes = !duplicateDishChecker(command[1], menu); + if (isValidAddDishCommand && noDuplicateDishes) { + String dishName = command[1].stripLeading().stripTrailing(); + String dishPriceString = command[2].stripLeading().stripTrailing(); + double dishPrice = Double.parseDouble(dishPriceString); + Dish newDish = new Dish(dishName, dishPrice); + menu.menu.add(newDish); + DishUI.printAddDishMessage(newDish, menu.menu.size()); + } + } + + /** + * Adds a new dish to the menu without printing any messages. + * + * @param menu User's menu. + * @param dish Dish to be added. + */ + public void loadDishFromStorage(Menu menu, Dish dish) { + menu.menu.add(dish); + } + + /** + * Checks whether a remove-dish command is in the correct format. + * + * @param command User's command in ArrayList format. + * @param menuSize Size of user's menu. + * @return Boolean representing whether the remove-dish command is in the correct format. + */ + public boolean removeDishCommandChecker(String[] command, int menuSize) { + try { + int dishIndex = Integer.parseInt(command[1]); + boolean validDishIndex = (0 < dishIndex) && (dishIndex < menuSize + 1); + if (!validDishIndex) { + DishUI.printInvalidIndexMessage(); + return false; + } + } catch (IndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidIndexMessage(); + return false; + } + return true; + } + + /** + * Removes an existing dish from the menu. + * + * @param command User's command in ArrayList format. + * @param menu User's menu. + */ + public void removeDish(String[] command, Menu menu) { + boolean isValidRemoveDishCommand = removeDishCommandChecker(command, menu.menu.size()); + if (isValidRemoveDishCommand) { + int dishIndex = Integer.parseInt(command[1]); + assert 0 < dishIndex : "Index should be more than 0"; + assert dishIndex < menu.menu.size() + 1 : "Index should not be bigger than the menu size"; + Dish oldDish = menu.menu.get(dishIndex - 1); + menu.menu.remove(dishIndex - 1); + DishUI.printRemoveDishMessage(oldDish, dishIndex); + } + } + + /** + * Checks whether an edit-dish command is in the correct format. + * + * @param command User's command in ArrayList format. + * @param menuSize Size of user's menu. + * @return Boolean representing whether the edit-dish command is in the correct format. + */ + public boolean editDishCommandChecker(String[] command, int menuSize) { + try { + int dishIndex = Integer.parseInt(command[1]); + boolean validDishIndex = (0 < dishIndex) && (dishIndex < menuSize + 1); + if (!validDishIndex) { + DishUI.printInvalidIndexMessage(); + return false; + } + } catch (ArrayIndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidIndexMessage(); + return false; + } + try { + Double.parseDouble(command[2]); + } catch (ArrayIndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidPriceMessage(); + return false; + } + return true; + } + + /** + * Edits the price of an existing dish in the menu. + * + * @param command User's command in ArrayList format. + * @param menu User's menu. + */ + public void editDish(String[] command, Menu menu) { + boolean isValidEditDishCommand = editDishCommandChecker(command, menu.menu.size()); + if (isValidEditDishCommand) { + int dishIndex = Integer.parseInt(command[1]); + assert 0 < dishIndex : "Index should be more than 0"; + assert dishIndex < menu.menu.size() + 1 : "Index should not be bigger than the menu size"; + double newPrice = Double.parseDouble(command[2]); + menu.menu.get(dishIndex - 1).setPrice(newPrice); + DishUI.printEditDishMessage(menu.menu.get(dishIndex - 1), dishIndex); + } + } + + /** + * Checks whether a discount-dish command is in the correct format. + * + * @param command User's command in ArrayList format. + * @param menuSize Size of user's menu. + * @return Boolean representing whether the discount-dish command is in the correct format. + */ + public boolean discountDishCommandChecker(String[] command, int menuSize) { + try { + int dishIndex = Integer.parseInt(command[1]); + boolean validDishIndex = (0 < dishIndex) && (dishIndex < menuSize + 1); + if (!validDishIndex) { + DishUI.printInvalidIndexMessage(); + return false; + } + } catch (ArrayIndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidIndexMessage(); + return false; + } + try { + double discount = Double.parseDouble(command[2]); + boolean validDiscount = (0 <= discount) && (discount <= 100); + if (!validDiscount) { + DishUI.printInvalidDiscountMessage(); + return false; + } + } catch (ArrayIndexOutOfBoundsException e) { + MainUI.printWrongCommandMessage(); + return false; + } catch (NumberFormatException e) { + DishUI.printInvalidDiscountMessage(); + return false; + } + return true; + } + + /** + * Adds a discount to an existing dish in the menu. + * + * @param command User's command in ArrayList format. + * @param menu User's menu. + */ + public void discountDish(String[] command, Menu menu) { + boolean isValidDiscountDishCommand = discountDishCommandChecker(command, menu.menu.size()); + if (isValidDiscountDishCommand) { + int dishIndex = Integer.parseInt(command[1]); + assert 0 < dishIndex : "Index should be more than 0"; + assert dishIndex < menu.menu.size() + 1 : "Index should not be bigger than the menu size"; + double discount = Double.parseDouble(command[2]); + menu.menu.get(dishIndex - 1).setDiscount(discount); + DishUI.printDiscountDishMessage(menu.menu.get(dishIndex - 1), dishIndex); + } + } + + /** + * Prints a list of all the dishes in the menu. + * + * @param menu Menu to be printed. + */ + public void listMenu(Menu menu) { + if (menu.menu.size() < 1) { + DishUI.printEmptyMenu(); + } else { + DishUI.printMenu(menu); + } + } + +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/dish/DishUI.java b/src/main/java/seedu/duke/dish/DishUI.java new file mode 100644 index 0000000000..de6aec446e --- /dev/null +++ b/src/main/java/seedu/duke/dish/DishUI.java @@ -0,0 +1,142 @@ +//@@author jerrelllzw + +package seedu.duke.dish; + +import seedu.duke.main.MainUI; + +/** + * Contains all UI related methods. + */ +public class DishUI { + + /** + * Prints a message to the user whenever a dish is added. + * + * @param newDish Dish added. + * @param dishIndex Index number of the added dish as shown in the displayed menu. + */ + public static void printAddDishMessage(Dish newDish, int dishIndex) { + MainUI.printSingleLine(); + System.out.println(" I have added the following dish to the menu:"); + System.out.println(" " + dishIndex + ". " + newDish); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever a dish is removed. + * + * @param oldDish Dish removed. + * @param dishIndex Index number of the added dish as shown in the displayed menu. + */ + public static void printRemoveDishMessage(Dish oldDish, int dishIndex) { + MainUI.printSingleLine(); + System.out.println(" I have removed the following dish from the menu:"); + System.out.println(" " + dishIndex + ". " + oldDish); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever there is an attempt to print an empty menu. + */ + public static void printEmptyMenu() { + MainUI.printSingleLine(); + System.out.println(" Sorry, there are no dishes in the menu yet :("); + MainUI.printSingleLine(); + } + + /** + * Prints a list of all the dishes in the menu. + * + * @param menu Menu to be printed. + */ + public static void printMenu(Menu menu) { + MainUI.printSingleLine(); + System.out.println(" Here are the dishes in your menu:"); + for (int i = 0; i < menu.menu.size(); i++) { + int index = i + 1; + boolean notDiscounted = menu.menu.get(i).getDiscount() == 0; + if (notDiscounted) { + System.out.println(" " + index + ". " + menu.menu.get(i)); + } else { + System.out.println(" " + index + ". " + menu.menu.get(i) + + " ---> " + menu.menu.get(i).getDiscountedPriceString()); + } + } + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever a dish's price is edited. + * + * @param newDish Dish which price has been edited. + * @param dishIndex Index number of the added dish as shown in the displayed menu. + */ + public static void printEditDishMessage(Dish newDish, int dishIndex) { + MainUI.printSingleLine(); + System.out.println(" Got it! The updated price of the dish is as follows:"); + System.out.println(" " + dishIndex + ". " + newDish); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever a discount is added to a dish. + * + * @param discountedDish Dish which a discount has been added to. + * @param dishIndex Index number of the added dish as shown in the displayed menu. + */ + public static void printDiscountDishMessage(Dish discountedDish, int dishIndex) { + boolean originalPrice = discountedDish.getDiscount() == 0; + MainUI.printSingleLine(); + if (originalPrice) { + System.out.println(" Got it! I have set the dish back to its original price!"); + System.out.println(" " + dishIndex + ". " + discountedDish); + } else { + System.out.println(" Got it! I have added the discount to the dish!"); + System.out.println(" The discounted price is as follows:"); + System.out.println(" " + dishIndex + ". " + discountedDish + + " ---> " + discountedDish.getDiscountedPriceString()); + } + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever there is an attempt to add an already existing dish to the menu. + */ + public static void printDuplicateDishMessage() { + MainUI.printSingleLine(); + System.out.println(" The dish that you entered is already in the menu!"); + System.out.println(" Please try again :)"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever an invalid index number is entered. + */ + public static void printInvalidIndexMessage() { + MainUI.printSingleLine(); + System.out.println(" You have entered an invalid index number!"); + System.out.println(" Please try again :)"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever an invalid price is entered. + */ + public static void printInvalidPriceMessage() { + MainUI.printSingleLine(); + System.out.println(" You have entered an invalid price!"); + System.out.println(" Please try again :)"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever an invalid discount is entered. + */ + public static void printInvalidDiscountMessage() { + MainUI.printSingleLine(); + System.out.println(" You have entered an invalid discount percentage!"); + System.out.println(" Please try again :)"); + MainUI.printSingleLine(); + } + +} diff --git a/src/main/java/seedu/duke/dish/Menu.java b/src/main/java/seedu/duke/dish/Menu.java new file mode 100644 index 0000000000..43f6f29fd9 --- /dev/null +++ b/src/main/java/seedu/duke/dish/Menu.java @@ -0,0 +1,14 @@ +//@@author jerrelllzw + +package seedu.duke.dish; + +import java.util.ArrayList; + +/** + * Represents the user's menu. + */ +public class Menu { + + public ArrayList menu = new ArrayList<>(); + +} diff --git a/src/main/java/seedu/duke/employee/Employee.java b/src/main/java/seedu/duke/employee/Employee.java new file mode 100644 index 0000000000..8320f54050 --- /dev/null +++ b/src/main/java/seedu/duke/employee/Employee.java @@ -0,0 +1,59 @@ +//@@author kairoskoh + +package seedu.duke.employee; + +/** + * Represents each individual employee. + * Contains important information such as name, phone number, employment status and salary. + */ +public class Employee { + + /** + * Contains three possible values for employment status of employees. + * PERM represents permanent employees. + * TEMP represents temporary or part-time employees. + * ADHOC represents adhoc employees, usually a one-time basis. + */ + public enum EmploymentStatus { + ADHOC, + PERM, + TEMP + } + + private String name; + private int phoneNum; + private EmploymentStatus status; + private int salary; + + public Employee(String name, int phoneNum, EmploymentStatus status, int salary) { + this.name = name; + this.phoneNum = phoneNum; + this.status = status; + this.salary = salary; + } + + @Override + public String toString() { + return name + " - " + phoneNum + " - " + status + " STAFF - $" + salary; + } + + public String toStringStorage() { + return "add-employee/" + name + "/" + phoneNum + "/" + status + "/" + salary; + } + + public String getName() { + return name; + } + + public int getPhoneNum() { + return phoneNum; + } + + public EmploymentStatus getStatus() { + return status; + } + + public int getSalary() { + return salary; + } +} diff --git a/src/main/java/seedu/duke/employee/EmployeeList.java b/src/main/java/seedu/duke/employee/EmployeeList.java new file mode 100644 index 0000000000..3f399a173d --- /dev/null +++ b/src/main/java/seedu/duke/employee/EmployeeList.java @@ -0,0 +1,16 @@ +//@@author kairoskoh + +package seedu.duke.employee; + +import java.util.ArrayList; + +/** + * Contains the list of employees in a restaurant, which can be modified. + * Keeps track of the total number of employees in a restaurant. + */ +public class EmployeeList { + + public ArrayList employeeList = new ArrayList<>(); + public int totalEmployee = 0; + +} diff --git a/src/main/java/seedu/duke/employee/EmployeeParser.java b/src/main/java/seedu/duke/employee/EmployeeParser.java new file mode 100644 index 0000000000..9be4eb1180 --- /dev/null +++ b/src/main/java/seedu/duke/employee/EmployeeParser.java @@ -0,0 +1,233 @@ +//@@author kairoskoh + +package seedu.duke.employee; + +import java.security.InvalidParameterException; +import java.util.Objects; +import java.util.logging.Logger; +import java.util.logging.Level; + +/** + * Processes the different commands which interacts with the list of employees. + * Enables users to add, remove and list employees. + */ +public class EmployeeParser { + + private static Logger logger = Logger.getLogger("EmployeeParser"); + + /** + * Adds a single employee into the list of employees. + * Requires critical information of the employee to be added such as name, phone number, + * employment status and salary. + * + * @param command contains the input from users. + * @param masterList references to the list of employees where changes will be made. + */ + public void addEmployee(String[] command, EmployeeList masterList) { + logger.log(Level.FINE, "going to add employee"); + + try { + Employee employee = new Employee(command[1].stripLeading().stripTrailing(), + checkNumber(command[2].stripLeading().stripTrailing()), + convertToStatus(command[3].stripLeading().stripTrailing()), + checkSalary(command[4].stripLeading().stripTrailing())); + + checkDuplicate(employee, masterList); + + masterList.employeeList.add(employee); + masterList.totalEmployee += 1; + + EmployeeUI.printAddEmployeeMessage(masterList); + } catch (ArrayIndexOutOfBoundsException e) { + logger.log(Level.FINE, "error input: out of bound index"); + } catch (NumberFormatException e) { + logger.log(Level.FINE, "error input: number format incorrect"); + } catch (InvalidParameterException e) { + logger.log(Level.FINE, "error input: employee status format incorrect"); + } + logger.log(Level.FINE, "end of adding employee"); + assert masterList.totalEmployee >= 0 : "total employee should be equals to or greater than zero"; + } + + /** + * Checks for duplicate entries by comparing user input with every single existing employee. + * + * @param employee contains the user input for the new employee. + * @param masterList references to the list of employees where changes will be made + */ + private void checkDuplicate(Employee employee, EmployeeList masterList) { + for (int i = 0; i < masterList.totalEmployee; i += 1) { + compareEmployee(employee, masterList, i); + } + } + + /** + * Checks for duplicate entries by comparing user input with a single employee. + * + * @param employee contains the user input for the new employee. + * @param masterList references to the list of employees where changes will be made + * @param i refers to the index of the current employee in the existing list that the + * new employee is being compared to. + */ + public void compareEmployee(Employee employee, EmployeeList masterList, int i) { + if (Objects.equals(employee.getName(), masterList.employeeList.get(i).getName())) { + if (Objects.equals(employee.getPhoneNum(), masterList.employeeList.get(i).getPhoneNum())) { + if (Objects.equals(employee.getStatus(), masterList.employeeList.get(i).getStatus())) { + if (Objects.equals(employee.getSalary(), masterList.employeeList.get(i).getSalary())) { + EmployeeUI.printDuplicateEntryMessage(i); + throw new InvalidParameterException(); + } + } + } + } + } + + /** + * Checks for duplicate entries by comparing user input with a single employee. + * + * @param employee contains the user input for the new employee. + * @param masterList references to the list of employees where changes will be made + * @param i refers to the index of the current employee in the existing list that the + * new employee is being compared to. + */ + public boolean isDuplicateEmployee(Employee employee, EmployeeList masterList, int i) { + if (Objects.equals(employee.getName(), masterList.employeeList.get(i).getName())) { + if (Objects.equals(employee.getPhoneNum(), masterList.employeeList.get(i).getPhoneNum())) { + if (Objects.equals(employee.getStatus(), masterList.employeeList.get(i).getStatus())) { + if (Objects.equals(employee.getSalary(), masterList.employeeList.get(i).getSalary())) { + EmployeeUI.printDuplicateEntryMessage(i); + return true; + } + } + } + } + return false; + } + + /** + * Checks if the format for salary is valid - must be a positive integer. + * If format is valid, string format is converted into integer format. + * + * @param number contains the user input for salary. + * @return the user input in integer format. + * @throws NumberFormatException If input from user is invalid. + */ + public int checkSalary(String number) { + int num = Integer.parseInt(number); + if (num <= 0) { + EmployeeUI.printInvalidSalaryMessage(); + throw new NumberFormatException(); + } + return num; + } + + /** + * Checks if the format for phone number is valid - must be a positive integer. + * If format is valid, string format is converted into integer format. + * + * @param number contains the user input for phone number. + * @return the user input in integer format. + * @throws NumberFormatException If input from user is invalid. + */ + public int checkNumber(String number) { + int num = Integer.parseInt(number); + if (num <= 0) { + EmployeeUI.printInvalidPhoneNumberMessage(); + throw new NumberFormatException(); + } + return num; + } + + /** + * Adds a single employee into the list of employees - from Duke.txt (storage location). + * Requires critical information of the employee to be added such as name, phone number, + * employment status and salary. + * + * @param command contains the input from storage. + * @param masterList references to the list of employees where changes will be made. + */ + public void addEmployeeFromStorage(String[] command, EmployeeList masterList) { + logger.log(Level.FINE, "going to add employee"); + + Employee.EmploymentStatus status = convertToStatus(command[3]); + Employee employee = new Employee(command[1], Integer.parseInt(command[2]), + status, Integer.parseInt(command[4])); + + masterList.employeeList.add(employee); + masterList.totalEmployee += 1; + + logger.log(Level.FINE, "end of adding employee"); + assert masterList.totalEmployee >= 0 : "total employee should be equals to or greater than zero"; + } + + /** + * Converts employee status from string format to enum. + * Employment status can only be perm, temp or adhoc, as specified in Employee.java. + * + * @param input contains the employment status specified by the users. + * @return enum of employment status. + * @throws InvalidParameterException If input from user is invalid. + */ + public Employee.EmploymentStatus convertToStatus(String input) throws InvalidParameterException { + logger.log(Level.FINE, "going to convert employee status from string to enum"); + switch (input) { + case "perm": + case "PERM": + return Employee.EmploymentStatus.PERM; + case "temp": + case "TEMP": + return Employee.EmploymentStatus.TEMP; + case "adhoc": + case "ADHOC": + return Employee.EmploymentStatus.ADHOC; + default: + EmployeeUI.printInvalidEmploymentStatusMessage(); + throw new InvalidParameterException(); + } + } + + /** + * Deletes a single employee from the list of employees. + * Requires information on which employee to remove, which must be specified by user. + * + * @param command contains the input from storage. + * @param masterList references to the list of employees where changes will be made. + */ + public void deleteEmployee(String[] command, EmployeeList masterList) { + logger.log(Level.FINE, "going to delete employee"); + try { + + int employeeIndex = Integer.parseInt(command[1]) - 1; + if (masterList.totalEmployee < 1) { + EmployeeUI.printNoEmployeeMessage(); + return; + } + EmployeeUI.printRemoveEmployeeMessage(masterList, employeeIndex); + + masterList.employeeList.remove(employeeIndex); + masterList.totalEmployee -= 1; + + } catch (ArrayIndexOutOfBoundsException e) { + logger.log(Level.FINE, "index from user input for removing employee is out of range"); + } + logger.log(Level.FINE, "end of deleting employee"); + assert masterList.totalEmployee >= 0 : "total employee should be equals to or greater than zero"; + } + + /** + * List all the employees in the list and their respective information. + * Information that are listed includes: name, phone number, employment status and salary. + * + * @param masterList references to the list of employees where changes will be made. + */ + public void listEmployee(EmployeeList masterList) { + logger.log(Level.FINE, "going to list employee"); + if (masterList.totalEmployee < 1) { + EmployeeUI.printNoEmployeeMessage(); + return; + } + EmployeeUI.printEmployeeListMessage(masterList); + logger.log(Level.FINE, "end of listing employee"); + } + +} diff --git a/src/main/java/seedu/duke/employee/EmployeeUI.java b/src/main/java/seedu/duke/employee/EmployeeUI.java new file mode 100644 index 0000000000..36d8639a82 --- /dev/null +++ b/src/main/java/seedu/duke/employee/EmployeeUI.java @@ -0,0 +1,82 @@ +//@@author kairoskoh + +package seedu.duke.employee; + +import seedu.duke.main.MainUI; + +import java.sql.SQLOutput; + +/** + * Prints messages to interact with the users. + */ +public class EmployeeUI { + + public static void printNoEmployeeMessage() { + MainUI.printSingleLine(); + System.out.println(" You have no employee."); + MainUI.printSingleLine(); + } + + public static void printAddEmployeeMessage(EmployeeList masterList) { + MainUI.printSingleLine(); + System.out.println(" I have added: "); + System.out.println(" " + masterList.employeeList.get(masterList.totalEmployee - 1)); + System.out.println(" You now have " + masterList.totalEmployee + " employees."); + MainUI.printSingleLine(); + } + + public static void printInvalidRemoveMessage() { + MainUI.printSingleLine(); + System.out.println(" Invalid input detected."); + System.out.println(" Please include employee index found in \"list-employee\"."); + MainUI.printSingleLine(); + } + + public static void printRemoveEmployeeMessage(EmployeeList masterList, int employeeIndex) { + MainUI.printSingleLine(); + System.out.println(" I have deleted: "); + System.out.println(" " + masterList.employeeList.get(employeeIndex)); + MainUI.printSingleLine(); + } + + public static void printEmployeeListMessage(EmployeeList masterList) { + MainUI.printSingleLine(); + System.out.println(" Here are the employees in your list:"); + for (int i = 1; i <= masterList.totalEmployee; i += 1) { + System.out.println(" " + i + ". " + masterList.employeeList.get(i - 1).getName() + + " - " + masterList.employeeList.get(i - 1).getPhoneNum() + + " - " + masterList.employeeList.get(i - 1).getStatus() + " STAFF" + + " - " + "$" + masterList.employeeList.get(i - 1).getSalary()); + } + MainUI.printSingleLine(); + } + + public static void printInvalidEmploymentStatusMessage() { + MainUI.printSingleLine(); + System.out.println("Invalid employment status."); + System.out.println("Please use one of the three options: perm, temp or adhoc."); + MainUI.printSingleLine(); + } + + public static void printInvalidPhoneNumberMessage() { + MainUI.printSingleLine(); + System.out.println("Invalid phone number."); + System.out.println("Please ensure that it is a positive integer."); + MainUI.printSingleLine(); + } + + public static void printInvalidSalaryMessage() { + MainUI.printSingleLine(); + System.out.println("Invalid salary."); + System.out.println("Please ensure that it is a positive integer."); + MainUI.printSingleLine(); + } + + public static void printDuplicateEntryMessage(int i) { + MainUI.printSingleLine(); + System.out.println("You have entered the exact same employee details before."); + System.out.println("Refer to your employee with index \'" + (i + 1) + "\' when you type in list-employee."); + System.out.println("This is a duplicate!"); + MainUI.printSingleLine(); + } +} diff --git a/src/main/java/seedu/duke/finance/Finance.java b/src/main/java/seedu/duke/finance/Finance.java new file mode 100644 index 0000000000..2dc8d635b3 --- /dev/null +++ b/src/main/java/seedu/duke/finance/Finance.java @@ -0,0 +1,65 @@ +//@@author Cesare4869 + +package seedu.duke.finance; + +import java.time.LocalDate; + +/** + * Represents a user's account. Contains the date, and the number of the account. + */ +public class Finance { + private LocalDate date; + private String account; + + /** + * Constructs an instance of Finance. + * + * @param date Date of the account. + * @param account Number of the account. + */ + public Finance(LocalDate date, String account) { + this.date = date; + this.account = account; + } + + @Override + public String toString() { + return date + " $" + account; + } + + /** + * Gets the date of the account. + * + * @return Date of the account in LocalDate format. + */ + public LocalDate getDate() { + return date; + } + + /** + * Sets the date of the account. + * + * @param date Date of the account. + */ + public void setDate(LocalDate date) { + this.date = date; + } + + /** + * Gets the number of the account. + * + * @return Number of the account in Double format. + */ + public Double getAccount() { + return Double.parseDouble(account); + } + + /** + * Sets the account number. + * + * @param account number of the account. + */ + public void setAccount(String account) { + this.account = account; + } +} diff --git a/src/main/java/seedu/duke/finance/FinanceList.java b/src/main/java/seedu/duke/finance/FinanceList.java new file mode 100644 index 0000000000..8e4b2336a6 --- /dev/null +++ b/src/main/java/seedu/duke/finance/FinanceList.java @@ -0,0 +1,14 @@ +//@@author Cesare4869 + +package seedu.duke.finance; + + +import java.util.ArrayList; + +/** + * Represents the user's account list. + */ +public class FinanceList { + public ArrayList financeList = new ArrayList<>(); + public double totalAccount = 0; +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/finance/FinanceParser.java b/src/main/java/seedu/duke/finance/FinanceParser.java new file mode 100644 index 0000000000..d5555cedf0 --- /dev/null +++ b/src/main/java/seedu/duke/finance/FinanceParser.java @@ -0,0 +1,118 @@ +//@@author Cesare4869 + +package seedu.duke.finance; + +import java.time.LocalDate; +import java.time.format.DateTimeParseException; + +/** + * Contains all Finance related methods. + * Deals with the user's Finance related input commands. + */ +public class FinanceParser { + + /** + * Adds a new account to the Finance list. + * + * @param command User's command in ArrayList format. + * @param finances User's finance list. + */ + public void addFinance(String[] command, FinanceList finances) { + try { + Finance newAccount = new Finance(LocalDate.parse(command[1]), command[2]); + + finances.financeList.add(newAccount); + finances.totalAccount += newAccount.getAccount(); + + FinanceUI.printAddFinanceMessage(newAccount); + + } catch (ArrayIndexOutOfBoundsException e) { + seedu.duke.finance.FinanceUI.printInvalidCommandSyntaxMessage(); + } catch (DateTimeParseException e) { + FinanceUI.printInvalidCommandSyntaxMessage(); + } + } + + /** + * Adds a new account to the finance list without printing any messages. + * + * @param finances User's finance list. + * @param account Account to be added. + */ + public void loadFinanceFromStorage(FinanceList finances, Finance account) { + finances.financeList.add(account); + finances.totalAccount += account.getAccount(); + } + + /** + * Removes an existing account from the menu. + * + * @param command User's command in ArrayList format. + * @param finances User's finance list. + */ + public void deleteFinance(String[] command, FinanceList finances) { + try { + int deletedFinanceIndex = Integer.parseInt(command[1]) - 1; + + Finance deletedAccount = finances.financeList.get(deletedFinanceIndex); + finances.financeList.remove(deletedFinanceIndex); + finances.totalAccount -= deletedAccount.getAccount(); + + FinanceUI.printRemoveFinanceMessage(deletedAccount); + + } catch (ArrayIndexOutOfBoundsException e) { + FinanceUI.printInvalidCommandSyntaxMessage(); + } catch (IndexOutOfBoundsException e) { + FinanceUI.printInvalidIndexMessage(); + } catch (NumberFormatException e) { + FinanceUI.printInvalidCommandSyntaxMessage(); + } + } + + /** + * Prints a list of all the accounts in the finance list. + * + * @param finances Finance list to be printed. + */ + public void listFinance(FinanceList finances) { + if (finances.financeList.size() < 1) { + FinanceUI.printEmptyListMessage(); + return; + } + assert finances.financeList.size() > 0 : "Finance list should not be empty"; + + FinanceUI.printFinanceListMessage(finances); + } + + /** + * Prints the total account . + * + * @param finances Finance list to be computed to get the total account. + */ + public void showFinance(FinanceList finances) { + FinanceUI.printTotalAccount(finances.totalAccount); + } + + /** + * Edits the number of an existing account in the finance list. + * + * @param command User's command in ArrayList format. + * @param finances User's finance list. + */ + public void editFinance(String[] command, FinanceList finances) { + try { + int editedFinanceIndex = Integer.parseInt(command[1]) - 1; + Finance editedAccount = finances.financeList.get(editedFinanceIndex); + finances.totalAccount -= editedAccount.getAccount(); + editedAccount.setAccount(command[2]); + finances.totalAccount += editedAccount.getAccount(); + FinanceUI.printEditFinanceMessage(editedAccount); + } catch (ArrayIndexOutOfBoundsException e) { + FinanceUI.printInvalidCommandSyntaxMessage(); + } catch (IndexOutOfBoundsException e) { + FinanceUI.printInvalidIndexMessage(); + } catch (NumberFormatException e) { + FinanceUI.printInvalidCommandSyntaxMessage(); + } + } +} diff --git a/src/main/java/seedu/duke/finance/FinanceUI.java b/src/main/java/seedu/duke/finance/FinanceUI.java new file mode 100644 index 0000000000..9acb411900 --- /dev/null +++ b/src/main/java/seedu/duke/finance/FinanceUI.java @@ -0,0 +1,95 @@ +//@@author Cesare4869 + +package seedu.duke.finance; + +import seedu.duke.main.MainUI; + + +/** + * Print messages to interact with the users. + */ +public class FinanceUI { + + /** + * Print a message to the user whenever an account is added. + * + * @param newAccount Finance added. + */ + public static void printAddFinanceMessage(Finance newAccount) { + MainUI.printSingleLine(); + System.out.println(" Got it. This account is added:"); + System.out.println(" Finance Date: " + newAccount.getDate()); + System.out.println(" Account: " + newAccount.getAccount()); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever there is an invalid attempt of wrong syntax of command. + */ + public static void printInvalidCommandSyntaxMessage() { + MainUI.printSingleLine(); + System.out.println(" Invalid command syntax!"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever there is an invalid attempt of invalid index to delete an account. + */ + public static void printInvalidIndexMessage() { + MainUI.printSingleLine(); + System.out.println(" That account does not exist!"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever an account is removed. + * + * @param deletedAccount Finance removed. + */ + public static void printRemoveFinanceMessage(Finance deletedAccount) { + MainUI.printSingleLine(); + System.out.println(" Got it. This account was deleted:"); + System.out.println(" " + deletedAccount.getDate() + " $" + deletedAccount.getAccount()); + MainUI.printSingleLine(); + } + + public static void printFinanceListMessage(FinanceList finances) { + MainUI.printSingleLine(); + System.out.println(" Here are the accounts in your list:"); + for (int i = 0; i < finances.financeList.size(); i++) { + System.out.println(" " + (i + 1) + ". " + finances.financeList.get(i)); + } + MainUI.printSingleLine(); + } + + /** + * Print a message to the user whenever there is an attempt to print an empty finance list. + */ + public static void printEmptyListMessage() { + MainUI.printSingleLine(); + System.out.println(" No accounts found."); + MainUI.printSingleLine(); + } + + /** + * Print a message to the user to show the total account of the finance list. + */ + public static void printTotalAccount(double totalAccount) { + MainUI.printSingleLine(); + System.out.format(" Here is the total account you have: $ %.2f %n", totalAccount); + MainUI.printSingleLine(); + } + + /** + * Print a message to the user whenever an account is edited. + * + * @param editedAccount the account is edited + */ + public static void printEditFinanceMessage(Finance editedAccount) { + MainUI.printSingleLine(); + System.out.println(" Got it. This account is edited:"); + System.out.println(" Finance Date: " + editedAccount.getDate()); + System.out.println(" Account: " + editedAccount.getAccount()); + MainUI.printSingleLine(); + } +} diff --git a/src/main/java/seedu/duke/ingredient/Ingredient.java b/src/main/java/seedu/duke/ingredient/Ingredient.java new file mode 100644 index 0000000000..9cee2de326 --- /dev/null +++ b/src/main/java/seedu/duke/ingredient/Ingredient.java @@ -0,0 +1,61 @@ +//@@author leecheokfeng + +package seedu.duke.ingredient; + +import java.time.LocalDate; + +/** + * Represents each different ingredient in the restaurant's ingredient inventory. + * Contains information about the ingredient's name, quantity, price and expiry date. + */ +public class Ingredient { + + private String name; + private String quantity; + private String price; + private LocalDate expiry; + + public Ingredient(String name, String quantity, String price, LocalDate expiry) { + this.name = name; + this.quantity = quantity; + this.price = price; + this.expiry = expiry; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getQuantity() { + return quantity; + } + + public void setQuantity(String quantity) { + this.quantity = quantity; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public LocalDate getExpiry() { + return expiry; + } + + public void setExpiry(LocalDate expiry) { + this.expiry = expiry; + } + + @Override + public String toString() { + return name + " [" + quantity + "]" + " [$" + price + "]" + " [" + expiry + "]"; + } +} diff --git a/src/main/java/seedu/duke/ingredient/IngredientList.java b/src/main/java/seedu/duke/ingredient/IngredientList.java new file mode 100644 index 0000000000..a52d1c2c1f --- /dev/null +++ b/src/main/java/seedu/duke/ingredient/IngredientList.java @@ -0,0 +1,14 @@ +//@@author leecheokfeng + +package seedu.duke.ingredient; + +import java.util.ArrayList; + +/** + * Contains the list of ingredients within the restaurant's inventory. + * Keeps track of the total number of ingredients within the inventory. + */ +public class IngredientList { + public ArrayList ingredientList = new ArrayList<>(); + public int totalIngredients = 0; +} diff --git a/src/main/java/seedu/duke/ingredient/IngredientParser.java b/src/main/java/seedu/duke/ingredient/IngredientParser.java new file mode 100644 index 0000000000..3b6f6c208e --- /dev/null +++ b/src/main/java/seedu/duke/ingredient/IngredientParser.java @@ -0,0 +1,143 @@ +//@@author leecheokfeng + +package seedu.duke.ingredient; + +import java.time.LocalDate; +import java.time.format.DateTimeParseException; + +/** + * Parses the input parameters entered by users to interact with the list of ingredients. + * Allows users to add, remove, list and find ingredients. + */ +public class IngredientParser { + + /** + * Adds a single ingredient to the list of ingredients. + * Ingredient details are provided by the user via the command parameter. + * + * @param command contains the ingredient information input by the users. + * @param ingredients refers to an existing list of ingredients where the + * new ingredient will be added. + * @throws ArrayIndexOutOfBoundsException If invalid parameters are entered by the user. + * @throws DateTimeParseException If invalid date format is entered by the user. + * @throws NumberFormatException If invalid number format is entered by the user. + */ + public void addIngredient(String[] command, IngredientList ingredients) { + try { + String name = command[1].stripLeading().stripTrailing(); + if (name.length() == 0) { + throw new ArrayIndexOutOfBoundsException(); + } + + int quantity = Integer.parseInt(command[2].stripLeading().stripTrailing()); + if (quantity < 1) { + throw new NumberFormatException(); + } + + double price = Double.parseDouble(command[3]); + String priceTwoDp = String.format("%.2f", price); + if (Double.parseDouble(priceTwoDp) <= 0) { + throw new NumberFormatException(); + } + + Ingredient newIngredient = new Ingredient(command[1].stripLeading().stripTrailing(), + command[2].stripLeading().stripTrailing(), + priceTwoDp.stripLeading().stripTrailing(), + LocalDate.parse(command[4])); + + ingredients.ingredientList.add(newIngredient); + ingredients.totalIngredients++; + + IngredientUI.printAddIngredientMessage(newIngredient); + + } catch (ArrayIndexOutOfBoundsException e) { + IngredientUI.printInvalidCommandSyntaxMessage("add"); + } catch (DateTimeParseException e) { + IngredientUI.printInvalidCommandSyntaxMessage("add"); + } catch (NumberFormatException e) { + IngredientUI.printInvalidCommandSyntaxMessage("add"); + } + } + + /** + * Adds a single ingredient (from storage location - Duke.txt) into the list of ingredients + * Ingredient details are based on the contents of the storage file. + * + * @param ingredients refers to an existing list of ingredients where the + * new ingredient will be added. + * @param ingredient the new ingredient with details based on storage file contents. + */ + public void loadIngredientFromStorage(IngredientList ingredients, Ingredient ingredient) { + ingredients.ingredientList.add(ingredient); + ingredients.totalIngredients++; + } + + /** + * Deletes a single ingredient from the list of ingredients. + * The list number of the ingredient to be deleted must be specified by the user. + * + * @param command contains the list number of the ingredient to be deleted. + * @param ingredients refers to an existing list of ingredients where a + * selected ingredient will be deleted from the list. + * @throws ArrayIndexOutOfBoundsException If an invalid parameter is entered by the user. + * @throws IndexOutOfBoundsException If a non-existent list number is entered by the user. + * @throws NumberFormatException If the list number entered by the user is of the wrong format. + */ + public void deleteIngredient(String[] command, IngredientList ingredients) { + try { + int deletedIngredientIndex = Integer.parseInt(command[1]) - 1; + + Ingredient deletedIngredient = ingredients.ingredientList.get(deletedIngredientIndex); + ingredients.ingredientList.remove(deletedIngredientIndex); + ingredients.totalIngredients--; + + IngredientUI.printRemoveIngredientMessage(deletedIngredient); + + } catch (ArrayIndexOutOfBoundsException e) { + IngredientUI.printInvalidCommandSyntaxMessage("remove"); + } catch (IndexOutOfBoundsException e) { + IngredientUI.printInvalidIndexMessage(); + } catch (NumberFormatException e) { + IngredientUI.printInvalidCommandSyntaxMessage("remove"); + } + } + + /** + * Lists all ingredients in the list and their respective information. + * Listed information includes: name, quantity, price, expiry date. + * + * @param ingredients refers to the existing list of ingredients which + * will be displayed to the user. + */ + public void listIngredient(IngredientList ingredients) { + if (ingredients.ingredientList.size() < 1) { + IngredientUI.printEmptyListMessage(); + return; + } + assert ingredients.ingredientList.size() > 0 : "Ingredient list should not be empty"; + + IngredientUI.printIngredientListMessage(ingredients); + } + + /** + * Finds all ingredients in the list that are expired by a particular date. + * The date is chosen and input by the user. Ingredients with expiry dates earlier + * than the input date are considered expired and will be displayed to the user. + * + * @param command contains the input date of the user. + * @param ingredients refers to the existing list of ingredients to be searched. + * @throws ArrayIndexOutOfBoundsException If an invalid parameter is entered by the user. + * @throws DateTimeParseException If an invalid date format is entered by the user. + */ + public void findExpiredIngredient(String[] command, IngredientList ingredients) { + try { + LocalDate inputDate = LocalDate.parse(command[1]); + + IngredientUI.printExpiredIngredientMessage(inputDate, ingredients); + } catch (ArrayIndexOutOfBoundsException e) { + IngredientUI.printInvalidCommandSyntaxMessage("find"); + } catch (DateTimeParseException e) { + IngredientUI.printInvalidCommandSyntaxMessage("find"); + } + } +} diff --git a/src/main/java/seedu/duke/ingredient/IngredientUI.java b/src/main/java/seedu/duke/ingredient/IngredientUI.java new file mode 100644 index 0000000000..e34c5f6bd6 --- /dev/null +++ b/src/main/java/seedu/duke/ingredient/IngredientUI.java @@ -0,0 +1,149 @@ +//@@author leecheokfeng + +package seedu.duke.ingredient; + +import seedu.duke.main.MainUI; + +import java.time.LocalDate; + +/** + * Prints UI messages to interact with the users. + */ +public class IngredientUI { + + /** + * Prints a message when an ingredient is added to the list of ingredients. + * Informs the user that the new ingredient was added successfully. + * + * @param newIngredient the new ingredient to be added to the ingredient list. + */ + public static void printAddIngredientMessage(Ingredient newIngredient) { + MainUI.printSingleLine(); + System.out.println(" Got it. This ingredient was added:"); + System.out.println(" Ingredient Name: " + newIngredient.getName()); + System.out.println(" Ingredient Quantity: " + newIngredient.getQuantity()); + System.out.println(" Ingredient Unit Price: " + newIngredient.getPrice()); + System.out.println(" Expiry Date: " + newIngredient.getExpiry()); + System.out.println("\n " + newIngredient); + MainUI.printSingleLine(); + } + + /** + * Prints a message when the user enters a command with invalid syntax/format. + * Informs the user on the proper command syntax and gives a link to the user guide. + * + * @param command refers to the command type entered by the user, so that the corresponding + * correct command syntax can be shown to the user. + */ + public static void printInvalidCommandSyntaxMessage(String command) { + MainUI.printSingleLine(); + System.out.println(" Invalid command syntax!"); + printSampleCommandSyntaxMessage(command); + System.out.println(" Please refer to our user guide for more details: " + + "https://ay2122s1-cs2113t-t12-4.github.io/tp/UserGuide.html"); + MainUI.printSingleLine(); + } + + /** + * Prints a message when an ingredient is removed from the list of ingredients. + * Informs the user that the selected ingredient was removed successfully. + * + * @param deletedIngredient the selected ingredient to be removed from the list. + */ + public static void printRemoveIngredientMessage(Ingredient deletedIngredient) { + MainUI.printSingleLine(); + System.out.println(" Got it. This ingredient was deleted:"); + System.out.println(" " + deletedIngredient); + MainUI.printSingleLine(); + } + + /** + * Prints a message when an invalid index number of the ingredient list is entered. + * Informs the user that an ingredient with the index number they have selected does not exist. + */ + public static void printInvalidIndexMessage() { + MainUI.printSingleLine(); + System.out.println(" That ingredient does not exist!"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to inform users when the ingredient list is empty. + */ + public static void printEmptyListMessage() { + MainUI.printSingleLine(); + System.out.println(" No ingredients found."); + MainUI.printSingleLine(); + } + + /** + * Prints a message which lists all ingredients in the list, and their details. + * + * @param ingredients the list of ingredients to be displayed to the user. + */ + public static void printIngredientListMessage(IngredientList ingredients) { + MainUI.printSingleLine(); + System.out.println(" Here are the ingredients in your list:"); + for (int i = 0; i < ingredients.ingredientList.size(); i++) { + System.out.println(" " + (i + 1) + ". " + ingredients.ingredientList.get(i)); + } + MainUI.printSingleLine(); + } + + /** + * Prints a message which lists all expired ingredients based on an input date. + * Ingredients with expiry dates earlier than the input date are considered + * expired and will be displayed to the user. + * + * @param inputDate the date input by the user, in YYYY-MM-DD format. + * @param ingredients the list of ingredients to be searched. + */ + public static void printExpiredIngredientMessage(LocalDate inputDate, IngredientList ingredients) { + boolean hasExpiredIngredients = false; + MainUI.printSingleLine(); + System.out.println(" These ingredients are expired:"); + + for (int i = 0; i < ingredients.ingredientList.size(); i++) { + if (ingredients.ingredientList.get(i).getExpiry().isBefore(inputDate)) { + System.out.println(" " + ingredients.ingredientList.get(i)); + hasExpiredIngredients = true; + } + } + if (!hasExpiredIngredients) { + System.out.println(" " + "None :)"); + } + MainUI.printSingleLine(); + } + + /** + * Prints a message when the user enters a command with invalid syntax. + * Informs the user of the correct command syntax. + * + * @param command refers to the command type entered by the user, so that the corresponding + * correct command syntax can be shown to the user. + */ + public static void printSampleCommandSyntaxMessage(String command) { + switch (command) { + case "add": + System.out.println(" Please follow this syntax:"); + System.out.println(" add-ingredient/INGREDIENT_NAME/QUANTITY/PRICE/EXPIRY_DATE"); + System.out.println(" must be a string."); + System.out.println(" must be a positive, non-zero integer."); + System.out.println(" must be a positive number greater than 0.01."); + System.out.println(" must be a valid date in YYYY-MM-DD format."); + break; + case "remove": + System.out.println(" Please follow this syntax:"); + System.out.println(" remove-ingredient/INGREDIENT_INDEX"); + System.out.println(" must be a positive integer corresponding to the list index."); + break; + case "find": + System.out.println(" Please follow this syntax:"); + System.out.println(" find-expired-ingredient/INPUT_DATE"); + System.out.println(" must be a valid date in YYYY-MM-DD format."); + break; + default: + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/seedu/duke/main/MainParser.java b/src/main/java/seedu/duke/main/MainParser.java new file mode 100644 index 0000000000..e9a90101b6 --- /dev/null +++ b/src/main/java/seedu/duke/main/MainParser.java @@ -0,0 +1,87 @@ +package seedu.duke.main; + +import seedu.duke.employee.EmployeeList; +import seedu.duke.employee.EmployeeParser; +import seedu.duke.ingredient.IngredientList; +import seedu.duke.ingredient.IngredientParser; +import seedu.duke.finance.FinanceList; +import seedu.duke.finance.FinanceParser; +import seedu.duke.dish.Menu; +import seedu.duke.dish.DishParser; + +public class MainParser { + + public static boolean handleCommand(EmployeeList employeeList, Menu menu, IngredientList ingredientList, + FinanceList financeList, String userInput) { + EmployeeParser employeeParser = new EmployeeParser(); + DishParser dishParser = new DishParser(); + IngredientParser ingredientParser = new IngredientParser(); + FinanceParser financeParser = new FinanceParser(); + + String[] command = userInput.trim().split("/", 5); + + switch (command[0].stripLeading().stripTrailing().toLowerCase()) { + case "add-employee": + employeeParser.addEmployee(command, employeeList); + break; + case "remove-employee": + employeeParser.deleteEmployee(command, employeeList); + break; + case "list-employee": + employeeParser.listEmployee(employeeList); + break; + case "add-dish": + dishParser.addDish(command, menu); + break; + case "remove-dish": + dishParser.removeDish(command, menu); + break; + case "edit-dish": + dishParser.editDish(command, menu); + break; + case "discount-dish": + dishParser.discountDish(command, menu); + break; + case "list-dish": + dishParser.listMenu(menu); + break; + case "add-ingredient": + ingredientParser.addIngredient(command, ingredientList); + break; + case "remove-ingredient": + ingredientParser.deleteIngredient(command, ingredientList); + break; + case "list-ingredient": + ingredientParser.listIngredient(ingredientList); + break; + case "find-expired-ingredient": + ingredientParser.findExpiredIngredient(command, ingredientList); + break; + case "add-finance": + financeParser.addFinance(command, financeList); + break; + case "remove-finance": + financeParser.deleteFinance(command, financeList); + break; + case "list-finance": + financeParser.listFinance(financeList); + break; + case "show-finance": + financeParser.showFinance(financeList); + break; + case "edit-finance": + financeParser.editFinance(command, financeList); + break; + case "help": + MainUI.printHelpMessage(); + break; + case "bye": + return true; + default: + MainUI.printWrongCommandMessage(); + break; + } + return false; + } + +} diff --git a/src/main/java/seedu/duke/main/MainUI.java b/src/main/java/seedu/duke/main/MainUI.java new file mode 100644 index 0000000000..7bab0ab72a --- /dev/null +++ b/src/main/java/seedu/duke/main/MainUI.java @@ -0,0 +1,86 @@ +//@@author kairoskoh + +package seedu.duke.main; + +public class MainUI { + + public static void printSingleLine() { + System.out.println("---------------------------------------------"); + } + + public static void printWelcomeMessage() { + printSingleLine(); + System.out.println( + " ___ _ _ \n" + + "| _ \\___ __| |_ __ _ _ _ _ _ __ _ _ _| |_ \n" + + "| / -_|_-< _/ _` | || | '_/ _` | ' \\ _| \n" + + "|_|_\\___/__/\\__\\__,_|\\_,_|_| \\__,_|_||_\\__| \n" + + " ___ _ _ \n" + + "| _ )_ _ __| |__| |_ _ \n" + + "| _ \\ || / _` / _` | || | \n" + + "|___/\\_,_\\__,_\\__,_|\\_, | \n" + + " |__/ \n"); + System.out.println(" Hello! Welcome to Restaurant Buddy :D"); + System.out.println(" How may I help you today?"); + printSingleLine(); + } + + public static void printGoodbyeMessage() { + printSingleLine(); + System.out.println(" Thank you. Goodbye!"); + printSingleLine(); + } + + public static void printStorageSaved() { + printSingleLine(); + System.out.println(" Storage saved successfully."); + System.out.println(" See you again!"); + printSingleLine(); + } + + public static void printWrongCommandMessage() { + printSingleLine(); + System.out.println(" I do not recognise the input."); + System.out.println(" Please try again!"); + printSingleLine(); + } + + public static void printHelpMessage() { + printSingleLine(); + System.out.println("Hello! You seem like you need a hand to get started."); + System.out.println("To interact with Restaurant Buddy, type in any of the following commands and press Enter!"); + System.out.println("The words that are CAPITALISED are the parameters that you can change."); + printSingleLine(); + System.out.println("- Employee Commands:"); + System.out.println("add-employee/EMPLOYEE_NAME/PHONE_NUMBER/EMPLOYMENT_STATUS/SALARY"); + System.out.println("remove-employee/EMPLOYEE_INDEX"); + System.out.println("list-employee"); + printSingleLine(); + System.out.println("- Menu Commands:"); + System.out.println("add-dish/DISH_NAME/PRICE"); + System.out.println("remove-dish/DISH_INDEX"); + System.out.println("edit-dish/DISH_INDEX/NEW_PRICE"); + System.out.println("discount-dish/DISH_INDEX/DISCOUNT(%)"); + System.out.println("list-dish"); + printSingleLine(); + System.out.println("- Ingredient Commands:"); + System.out.println("add-ingredient/INGREDIENT_NAME/QUANTITY/PRICE/EXPIRY_DATE"); + System.out.println("remove-ingredient/INGREDIENT_INDEX"); + System.out.println("list-ingredient"); + System.out.println("find-expired-ingredient/INPUT_DATE"); + printSingleLine(); + System.out.println("- Finance Commands:"); + System.out.println("add-finance/DATE/ACCOUNT"); + System.out.println("remove-finance/FINANCE_INDEX"); + System.out.println("edit-finance/FINANCE_INDEX/NEW_ACCOUNT"); + System.out.println("show-finance"); + System.out.println("list-finance"); + printSingleLine(); + System.out.println("To exit the program safely, please type in the command:"); + System.out.println("bye"); + printSingleLine(); + System.out.println("If you require more help, please refer to the User Guide on Github."); + System.out.println("Let's get started at once! Feel free to try out the commands :D"); + printSingleLine(); + } +} diff --git a/src/main/java/seedu/duke/storage/Storage.java b/src/main/java/seedu/duke/storage/Storage.java new file mode 100644 index 0000000000..2f88efb739 --- /dev/null +++ b/src/main/java/seedu/duke/storage/Storage.java @@ -0,0 +1,199 @@ +//@@author Cesare4869 + +package seedu.duke.storage; + +import seedu.duke.employee.Employee; +import seedu.duke.employee.EmployeeList; +import seedu.duke.employee.EmployeeParser; +import seedu.duke.ingredient.Ingredient; +import seedu.duke.ingredient.IngredientList; +import seedu.duke.ingredient.IngredientParser; + +import seedu.duke.finance.Finance; +import seedu.duke.finance.FinanceList; +import seedu.duke.finance.FinanceParser; +import seedu.duke.dish.Dish; +import seedu.duke.dish.Menu; +import seedu.duke.dish.DishParser; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDate; +import java.util.Scanner; + +/** + * The storage to manage,load and save data. + */ +public class Storage { + + public static final String FILE_NAME = "Duke.txt"; + + /** + * Load data from the default file. + * + * @param employeeList the list of employees + * @param menu the list of dishes + * @param ingredientList the list of ingredients + * @param financeList the list of accounts + */ + public static void loadStorage(EmployeeList employeeList, Menu menu, IngredientList ingredientList, + FinanceList financeList) { + File file = new File(FILE_NAME); + EmployeeParser employeeParser = new EmployeeParser(); + DishParser dishParser = new DishParser(); + IngredientParser ingredientParser = new IngredientParser(); + FinanceParser financeParser = new FinanceParser(); + if (!file.exists()) { + //StorageUI.printFileNotFound(); + } + try { + Scanner fileReader = new Scanner(file); + while (fileReader.hasNextLine()) { + String line = fileReader.nextLine(); + if (line.isEmpty()) { + continue; + } + if (line.startsWith("add-employee")) { + String[] command = line.trim().split("/", 5); + employeeParser.addEmployeeFromStorage(command, employeeList); + } else if (line.startsWith("add-ingredient")) { + Ingredient newIngredient = decodeIngredient(line); + ingredientParser.loadIngredientFromStorage(ingredientList, newIngredient); + } else if (line.startsWith("add-dish")) { + Dish newDish = decodeDish(line); + dishParser.loadDishFromStorage(menu, newDish); + } else if (line.startsWith("add-finance")) { + Finance newFinance = decodeFinance(line); + financeParser.loadFinanceFromStorage(financeList, newFinance); + } + } + fileReader.close(); + } catch (FileNotFoundException e) { + //StorageUI.printFileReadException(); + } + } + + /** + * Decode the account from in the file. + * + * @param toRead the string format of the account + * @return the decoded account + */ + private static Finance decodeFinance(String toRead) { + String[] description = toRead.trim().split("\\|", 3); + Finance finance = new Finance(LocalDate.parse(description[1]), description[2]); + return finance; + } + + /** + * Encode the account to be stored in the file. + * + * @param toWrite the account to be encoded + * @return the string format of the account + */ + private static String encodeFinance(String toWrite) { + String encodedItem = null; + String[] description = toWrite.trim().split(" ", 2); + encodedItem = "add-finance" + "|" + description[0] + "|" + description[1].substring(1); + return encodedItem; + } + + /** + * Decode the ingredient from the file. + * + * @param toRead the string format of the ingredient + * @return the decoded ingredient + */ + private static Ingredient decodeIngredient(String toRead) { + String[] description = toRead.trim().split("\\|", 5); + Ingredient ingredient = new Ingredient(description[1], description[2], + description[3], LocalDate.parse(description[4])); + return ingredient; + } + + /** + * Encode the ingredient to be stored in the file. + * + * @param toWrite the ingredient to be encoded + * @return the string format of the ingredient + */ + private static String encodeIngredient(String toWrite) { + String encodedItem = null; + String[] description = toWrite.trim().split(" ", 4); + encodedItem = "add-ingredient" + "|" + description[0] + "|" + + description[1].substring(1, description[1].length() - 1) + "|" + + description[2].substring(2, description[2].length() - 1) + "|" + + description[3].substring(1, description[3].length() - 1); + assert (!encodedItem.contains("[")); + assert (!encodedItem.contains("]")); + return encodedItem; + } + + /** + * Decode the dish from the file. + * + * @param toRead the string format of the dish + * @return the decoded dish + */ + private static Dish decodeDish(String toRead) { + String[] description = toRead.trim().split("\\|", 4); + double dishPrice = Double.parseDouble(description[2]); + Dish dish = new Dish(description[1], dishPrice); + double discount = Double.parseDouble(description[3]); + dish.setDiscount(discount); + return dish; + } + + /** + * Encode the dish to be stored in the file. + * + * @param dish the dish to be encoded + * @return the string format of the dish + */ + private static String encodeDish(Dish dish) { + String encodedItem = null; + encodedItem = "add-dish" + "|" + dish.getName() + "|" + dish.getPrice() + "|" + dish.getDiscount(); + assert (!encodedItem.contains("$")); + return encodedItem; + } + + /** + * Save the date into the default file. + * + * @param employeeList the list of employees + * @param menu the list of dishes + * @param ingredientList the list of ingredients + * @param financeList the list of accounts + */ + public static void saveStorage(EmployeeList employeeList, Menu menu, + IngredientList ingredientList, FinanceList financeList) { + try { + FileWriter fileWriter = new FileWriter(FILE_NAME); + + for (int i = 0; i < employeeList.employeeList.size(); i += 1) { + Employee employee = employeeList.employeeList.get(i); + fileWriter.write(String.format("%s\n", employee.toStringStorage())); + } + for (int i = 0; i < ingredientList.ingredientList.size(); i += 1) { + Ingredient ingredient = ingredientList.ingredientList.get(i); + fileWriter.write(String.format("%s\n", encodeIngredient(ingredient.toString()))); + } + for (int i = 0; i < menu.menu.size(); i += 1) { + Dish dish = menu.menu.get(i); + fileWriter.write(String.format("%s\n", encodeDish(dish))); + } + for (int i = 0; i < financeList.financeList.size(); i += 1) { + Finance finance = financeList.financeList.get(i); + fileWriter.write(String.format("%s\n", encodeFinance(finance.toString()))); + } + fileWriter.close(); + } catch (IOException e) { + StorageUI.printFileWriteError(); + } catch (ArrayIndexOutOfBoundsException e) { + StorageUI.printOutOfBoundsException(); + } + } + +} diff --git a/src/main/java/seedu/duke/storage/StorageUI.java b/src/main/java/seedu/duke/storage/StorageUI.java new file mode 100644 index 0000000000..98b41c20f7 --- /dev/null +++ b/src/main/java/seedu/duke/storage/StorageUI.java @@ -0,0 +1,44 @@ +//@@author Cesare4869 + +package seedu.duke.storage; + +import seedu.duke.main.MainUI; + +public class StorageUI { + + /** + * Prints a message to the user whenever the file cannot been found and create a new file. + */ + public static void printFileNotFound() { + MainUI.printSingleLine(); + System.out.println("File is not found! A new file has been created"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever the file cannot been read. + */ + public static void printFileReadException() { + MainUI.printSingleLine(); + System.out.println("Cannot read the file"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever the file cannot be written. + */ + public static void printFileWriteError() { + MainUI.printSingleLine(); + System.out.println("Cannot be written in the file!"); + MainUI.printSingleLine(); + } + + /** + * Prints a message to the user whenever the item is out of range. + */ + public static void printOutOfBoundsException() { + MainUI.printSingleLine(); + System.out.println("Exception out of bounds array caught"); + MainUI.printSingleLine(); + } +} diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/duke/DukeTest.java index 2dda5fd651..0701e0446f 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/seedu/duke/DukeTest.java @@ -2,11 +2,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; +//import org.junit.Test; + class DukeTest { + /* @Test public void sampleTest() { assertTrue(true); } + + private void assertTrue(boolean b) { + }*/ } diff --git a/src/test/java/seedu/duke/dish/DishParserTest.java b/src/test/java/seedu/duke/dish/DishParserTest.java new file mode 100644 index 0000000000..4b4d460ff6 --- /dev/null +++ b/src/test/java/seedu/duke/dish/DishParserTest.java @@ -0,0 +1,65 @@ +//@@author jerrelllzw + +package seedu.duke.dish; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DishParserTest { + + @Test + void addDish_validMenu_success() { + Menu menu = new Menu(); + DishParser dishParser = new DishParser(); + String[] addCommand = "add-dish|Pizza|5.75".trim().split("\\|"); + dishParser.addDish(addCommand, menu); + assertEquals(1, menu.menu.size()); + } + + @Test + void deleteDish_emptyMenu_expectNoChange() { + Menu menu = new Menu(); + DishParser dishParser = new DishParser(); + String[] deleteCommand = "remove-dish|1".trim().split("\\|"); + dishParser.removeDish(deleteCommand, menu); + assertEquals(0, menu.menu.size()); + } + + @Test + void deleteDish_validMenu_success() { + Menu menu = new Menu(); + DishParser dishParser = new DishParser(); + String[] addCommand = "add-dish|Pizza|5.75".trim().split("\\|"); + String[] deleteCommand = "remove-dish|1".trim().split("\\|"); + dishParser.addDish(addCommand, menu); + assertEquals(1, menu.menu.size()); + dishParser.removeDish(deleteCommand, menu); + assertEquals(0, menu.menu.size()); + } + + @Test + void editDish_validMenu_success() { + Menu menu = new Menu(); + DishParser dishParser = new DishParser(); + String[] addCommand = "add-dish|Pizza|5.75".trim().split("\\|"); + String[] editCommand = "edit-dish|1|2".trim().split("\\|"); + dishParser.addDish(addCommand, menu); + assertEquals(1, menu.menu.size()); + dishParser.editDish(editCommand, menu); + assertEquals(2, menu.menu.get(0).getPrice()); + } + + @Test + void discountDish_validMenu_success() { + Menu menu = new Menu(); + DishParser dishParser = new DishParser(); + String[] addCommand = "add-dish|Pizza|6".trim().split("\\|"); + String[] discountCommand = "discount-dish|1|50".trim().split("\\|"); + dishParser.addDish(addCommand, menu); + assertEquals(1, menu.menu.size()); + dishParser.discountDish(discountCommand, menu); + assertEquals(3, menu.menu.get(0).getDiscountedPrice()); + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/employee/EmployeeParserTest.java b/src/test/java/seedu/duke/employee/EmployeeParserTest.java new file mode 100644 index 0000000000..7ec442176b --- /dev/null +++ b/src/test/java/seedu/duke/employee/EmployeeParserTest.java @@ -0,0 +1,72 @@ +//@@author kairoskoh + +package seedu.duke.employee; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class EmployeeParserTest { + + @Test + void deleteEmployee_emptyMasterList_expectNoChange() { + EmployeeList masterList = new EmployeeList(); + EmployeeParser test = new EmployeeParser(); + String[] command = { "remove-employee", "10" }; + test.deleteEmployee(command, masterList); + assertEquals(0, masterList.totalEmployee); + } + + @Test + void listEmployee_emptyMasterList_expectNoResult() { + EmployeeList masterList = new EmployeeList(); + EmployeeParser test = new EmployeeParser(); + test.listEmployee(masterList); + assertEquals(0, masterList.totalEmployee); + } + + @Test + void compareEmployee_emptyMasterList_expectFalse() { + Employee employee = new Employee("name", 12345678, Employee.EmploymentStatus.PERM, 1000); + EmployeeList masterList = new EmployeeList(); + EmployeeParser test = new EmployeeParser(); + masterList.employeeList.add(employee); + assertTrue(test.isDuplicateEmployee(employee, masterList, 0)); + } + + @Test + void checkSalary_positiveIntegerString_expectInteger() { + String num = "123"; + int number = 123; + EmployeeParser test = new EmployeeParser(); + assertEquals(number, test.checkSalary(num)); + } + + @Test + void checkNumber_positiveIntegerString_expectInteger() { + String num = "100"; + int number = 100; + EmployeeParser test = new EmployeeParser(); + assertEquals(number, test.checkSalary(num)); + } + + @Test + void convertToStatus_stringPerm_enumEmploymentStatus() { + EmployeeParser test = new EmployeeParser(); + assertEquals(Employee.EmploymentStatus.PERM, test.convertToStatus("perm")); + } + + @Test + void convertToStatus_stringTemp_enumEmploymentStatus() { + EmployeeParser test = new EmployeeParser(); + assertEquals(Employee.EmploymentStatus.TEMP, test.convertToStatus("temp")); + } + + @Test + void convertToStatus_stringAdhoc_enumEmploymentStatus() { + EmployeeParser test = new EmployeeParser(); + assertEquals(Employee.EmploymentStatus.ADHOC, test.convertToStatus("adhoc")); + } + +} \ No newline at end of file diff --git a/src/test/java/seedu/duke/finance/FinanceParserTest.java b/src/test/java/seedu/duke/finance/FinanceParserTest.java new file mode 100644 index 0000000000..a53f193a4a --- /dev/null +++ b/src/test/java/seedu/duke/finance/FinanceParserTest.java @@ -0,0 +1,40 @@ +package seedu.duke.finance; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FinanceParserTest { + + @Test + void addFinance_valid_success() { + FinanceList finances = new FinanceList(); + FinanceParser financeParser = new FinanceParser(); + String[] addCommand = "add-finance/2021-10-27/100".trim().split("/"); + financeParser.addFinance(addCommand, finances); + assertEquals(1, finances.financeList.size()); + } + + @Test + void deleteFinance_valid_success() { + FinanceList finances = new FinanceList(); + FinanceParser financeParser = new FinanceParser(); + String[] addCommand = "add-finance/2021-10-27/100".trim().split("/"); + String[] deleteCommand = "remove-finance/1".trim().split("/"); + financeParser.addFinance(addCommand, finances); + assertEquals(1, finances.financeList.size()); + financeParser.deleteFinance(deleteCommand, finances); + assertEquals(0, finances.financeList.size()); + } + + @Test + void editFinance_valid_success() { + FinanceList finances = new FinanceList(); + FinanceParser financeParser = new FinanceParser(); + String[] addCommand = "add-finance|2021-10-27|100".trim().split("\\|"); + String[] editCommand = "edit-dish|1|200".trim().split("\\|"); + financeParser.addFinance(addCommand, finances); + assertEquals(1, finances.financeList.size()); + financeParser.editFinance(editCommand, finances); + assertEquals(200, finances.financeList.get(0).getAccount()); + } +} diff --git a/src/test/java/seedu/duke/ingredient/IngredientParserTest.java b/src/test/java/seedu/duke/ingredient/IngredientParserTest.java new file mode 100644 index 0000000000..72b660c830 --- /dev/null +++ b/src/test/java/seedu/duke/ingredient/IngredientParserTest.java @@ -0,0 +1,31 @@ +//@@author leecheokfeng + +package seedu.duke.ingredient; + +import org.junit.jupiter.api.Test; +import seedu.duke.dish.DishParser; +import seedu.duke.dish.Menu; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class IngredientParserTest { + @Test + void addIngredient_success() { + IngredientList ingredients = new IngredientList(); + IngredientParser ingredientParser = new IngredientParser(); + String[] addCommand = "add-ingredient/Banana/30/1.50/2021-12-01".trim().split("/"); + ingredientParser.addIngredient(addCommand, ingredients); + assertEquals(1, ingredients.ingredientList.size()); + } + + @Test + void removeIngredient_success() { + IngredientList ingredients = new IngredientList(); + IngredientParser ingredientParser = new IngredientParser(); + String[] addCommand = "add-ingredient/Banana/30/1.50/2021-12-01".trim().split("/"); + String[] removeCommand = "remove-ingredient/1".trim().split("/"); + ingredientParser.addIngredient(addCommand, ingredients); + ingredientParser.deleteIngredient(removeCommand, ingredients); + assertEquals(0, ingredients.ingredientList.size()); + } +} diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..8b13789179 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| -What is your name? -Hello James Gosling diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..e69de29bb2 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +0,0 @@ -James Gosling \ No newline at end of file diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index 25ac7a2989..e69de29bb2 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -1,19 +0,0 @@ -@echo off -setlocal enableextensions -pushd %~dp0 - -cd .. -call gradlew clean shadowJar - -cd build\libs -for /f "tokens=*" %%a in ( - 'dir /b *.jar' -) do ( - set jarloc=%%a -) - -java -jar %jarloc% < ..\..\text-ui-test\input.txt > ..\..\text-ui-test\ACTUAL.TXT - -cd ..\..\text-ui-test - -FC ACTUAL.TXT EXPECTED.TXT >NUL && ECHO Test passed! || Echo Test failed! diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index 1dcbd12021..e69de29bb2 100755 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# change to script directory -cd "${0%/*}" - -cd .. -./gradlew clean shadowJar - -cd text-ui-test - -java -jar $(find ../build/libs/ -mindepth 1 -print -quit) < input.txt > ACTUAL.TXT - -cp EXPECTED.TXT EXPECTED-UNIX.TXT -dos2unix EXPECTED-UNIX.TXT ACTUAL.TXT -diff EXPECTED-UNIX.TXT ACTUAL.TXT -if [ $? -eq 0 ] -then - echo "Test passed!" - exit 0 -else - echo "Test failed!" - exit 1 -fi diff --git a/unused.txt b/unused.txt new file mode 100644 index 0000000000..631051b855 --- /dev/null +++ b/unused.txt @@ -0,0 +1,46 @@ +// Unused Content For CS2113T User Guide +// Use This For CS2101 User Guide + +## Introduction +Restaurant Buddy is a desktop application designed for restaurant managers to help **keep track of restaurant data** +such as its employees, dishes in the menu and ingredients in storage via a **Command Line Interface (CLI)**. +In particular, Restaurant Buddy was developed specifically for users who can type fast and prefer typing to other +means of input. + +## Purpose +This user guide is designed for managers (or employees undertaking managerial roles) who oversee operations +at a restaurant. This user guide provides the necessary information on how to utilise Restaurant Buddy +to its fullest potential. There is little to no prior technical knowledge needed, everything you need to get +started will be included in the next section under "How To Use". However, a simple understanding of how +a restaurant runs is assumed. + +## How To Use +Restaurant Buddy is a Command-Line-Interface (CLI) application. This means that the interaction between you +and the application is purely through a single line of words. In order to do a desired action, simply type in the +command according to a specified format and press enter on your keyboard. The format of inputs that you can type +into the application is specified in the document later on from Section 2: Features onwards. These are also highlighted +throughout the user guide. + +In this user guide, there are multiple references to terms like 'employee', 'dish', 'ingredient' and 'finance'. +These four terms are the key areas that Restaurant Buddy aims to help restaurant managers through. These four +terms are defined below: +- 'Employee' refers to any person working for the restaurant. +- 'Dish' refers to any individual food or beverage that is sold at the restaurant. Multiple 'dish' collated in +a single list makes up a 'menu'. +- 'Ingredient' refers to any materials that is used to create a 'dish' that is currently in storage at the restaurant. +- 'Finance' refers to the amount of money earned or spent, recorded at the end of the day or week. + +In addition, there are certain conventions throughout the user guide: +- highlighted words such as `add-employee/EMPLOYEE_NAME/PHONE_NUMBER` indicates a command that can be typed onto +the command line interface +- expected output is placed inside a box such as the box below +``` +--------------------------------------------- +This is an example of expected outputs. +Restaurant Buddy communicates with you this way! +--------------------------------------------- +``` +- hyperlinks (which brings you directly to the section of the user guide you are interested in) are words in the +colour blue - an example is the blue text in the contents section below + +## Contents \ No newline at end of file