diff --git a/.gitignore b/.gitignore index 5e59b862ba4..566cbda3e0a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ src/main/resources/docs/ # IDEA files /.idea/ /out/ -/*.iml +**/*.iml # Storage/log files /data/ @@ -19,3 +19,8 @@ src/test/data/sandbox/ # MacOS custom attributes files created by Finder .DS_Store + +# Custom Windows / Shell scripts +*.bat + + diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.adoc b/README.adoc old mode 100644 new mode 100755 index e36efe534bb..42d9afa20e8 --- a/README.adoc +++ b/README.adoc @@ -1,10 +1,9 @@ -= Address Book (Level 3) += Inventory Manager ifdef::env-github,env-browser[:relfileprefix: docs/] -https://travis-ci.org/se-edu/addressbook-level3[image:https://travis-ci.org/se-edu/addressbook-level3.svg?branch=master[Build Status]] -https://ci.appveyor.com/project/damithc/addressbook-level3[image:https://ci.appveyor.com/api/projects/status/3boko2x2vr5cc3w2?svg=true[Build status]] -https://coveralls.io/github/se-edu/addressbook-level3?branch=master[image:https://coveralls.io/repos/github/se-edu/addressbook-level3/badge.svg?branch=master[Coverage Status]] -https://www.codacy.com/app/damith/addressbook-level3?utm_source=github.com&utm_medium=referral&utm_content=se-edu/addressbook-level3&utm_campaign=Badge_Grade[image:https://api.codacy.com/project/badge/Grade/fc0b7775cf7f4fdeaf08776f3d8e364a[Codacy Badge]] +https://travis-ci.org/AY1920S2-CS2103-W14-2/main[image:https://travis-ci.org/AY1920S2-CS2103-W14-2/main.svg?branch=master[Build Status]] +https://ci.appveyor.com/project/CS2103-W14-2/main[image:https://ci.appveyor.com/api/projects/status/rlr0xji2vhij1016?svg=true[Build status]] +https://coveralls.io/github/AY1920S2-CS2103-W14-2/main?branch=master[image:https://coveralls.io/repos/github/AY1920S2-CS2103-W14-2/main/badge.svg?branch=master[Coverage Status]] ifdef::env-github[] @@ -15,15 +14,20 @@ ifndef::env-github[] image::images/Ui.png[width="600"] endif::[] -* This is a desktop Address Book application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). -* It is a Java sample application intended for students learning Software Engineering while using Java as the main programming language. -* It is *written in OOP fashion*. It provides a *reasonably well-written* code example that is *significantly bigger* (around 6 KLoC)than what students usually write in beginner-level SE modules. +* This is a desktop Inventory Manager application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). +* It facilitates easily management of stocks, which includes: + ** warning when supplies are + low + ** easy sourcing of suppliers for selected goods + ** expiry management + ** seamless updating of inventory upon procurement and sales transactions +* This application is optimized for fast-typists. If you are comfortable with the keyboard, +Inventory Manager will be a joy to use! == Site Map * <> * <> -* <> * <> * <> @@ -32,5 +36,6 @@ endif::[] * Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by _Marco Jakob_. * Libraries used: https://openjfx.io/[JavaFX], https://github.com/FasterXML/jackson[Jackson], https://github.com/junit-team/junit5[JUnit5] +* This project is an extension of AddressBook-Level3 project codebase created by https://se-education.org[SE-EDU initiative] == Licence : link:LICENSE[MIT] diff --git a/_config.yml b/_config.yml old mode 100644 new mode 100755 diff --git a/appveyor.yml b/appveyor.yml old mode 100644 new mode 100755 diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 index 93029ef8262..600e4db395a --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,7 @@ dependencies { } shadowJar { - archiveName = 'addressbook.jar' + archiveName = 'inventorymanager.jar' destinationDir = file("${buildDir}/jar/") } @@ -133,8 +133,8 @@ asciidoctor { idprefix: '', // for compatibility with GitHub preview idseparator: '-', 'site-root': "${sourceDir}", // must be the same as sourceDir, do not modify - 'site-name': 'AddressBook-Level3', - 'site-githuburl': 'https://github.com/se-edu/addressbook-level3', + 'site-name': 'InventoryManager', + 'site-githuburl': 'https://github.com/AY1920S2-CS2103-W14-2/main', 'site-seedu': true, // delete this line if your project is not a fork (not a SE-EDU project) ] diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml old mode 100644 new mode 100755 diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml old mode 100644 new mode 100755 diff --git a/copyright.txt b/copyright.txt old mode 100644 new mode 100755 index 93aa2a39ce2..2b62a7d55e0 --- a/copyright.txt +++ b/copyright.txt @@ -1,8 +1,7 @@ Some code adapted from http://code.makery.ch/library/javafx-8-tutorial/ by Marco Jakob -Copyright by Susumu Yoshida - http://www.mcdodesign.com/ -- address_book_32.png -- AddressApp.ico +Copyright by Iconfactory - https://iconfactory.com/ +- inventory_manager_32.png Copyright by Jan Jan Kovařík - http://glyphicons.com/ - calendar.png diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc old mode 100644 new mode 100755 index 458e6134f45..74b74f6a7e3 --- a/docs/AboutUs.adoc +++ b/docs/AboutUs.adoc @@ -4,53 +4,42 @@ :imagesDir: images :stylesDir: stylesheets -AddressBook - Level 3 was developed by the https://se-edu.github.io/docs/Team.html[se-edu] team. + -_{The dummy content given below serves as a placeholder to be used by future forks of the project.}_ + -{empty} + We are a team based in the http://www.comp.nus.edu.sg[School of Computing, National University of Singapore]. == Project Team -=== John Doe -image::damithc.jpg[width="150", align="left"] -{empty}[http://www.comp.nus.edu.sg/~damithch[homepage]] [https://github.com/damithc[github]] [<>] +=== Nicholas Cristian Fernando +image::nicholascf.png[width="150", align="left"] +{empty}[https://github.com/NicholasCF[github]] [<>] -Role: Project Advisor - -''' - -=== John Roe -image::lejolly.jpg[width="150", align="left"] -{empty}[http://github.com/lejolly[github]] [<>] - -Role: Team Lead + -Responsibilities: UI +Role: Developer + +Responsibilities: Suppliers ''' -=== Johnny Doe -image::yijinl.jpg[width="150", align="left"] -{empty}[http://github.com/yijinl[github]] [<>] +=== Pang Jia Da +image::pangjiada.png[width="150", align="left"] +{empty}[https://github.com/PangJiaDa[github]] [<>] Role: Developer + -Responsibilities: Data +Responsibilities: Transactions ''' -=== Johnny Roe -image::m133225.jpg[width="150", align="left"] -{empty}[http://github.com/m133225[github]] [<>] +=== Fang Shao Hua +image::fangshaohua94.png[width="150", align="left"] +{empty}[https://github.com/FangShaoHua94[github]] [<>] Role: Developer + -Responsibilities: Dev Ops + Threading +Responsibilities: Inventory ''' -=== Benson Meier -image::yl_coder.jpg[width="150", align="left"] -{empty}[http://github.com/yl-coder[github]] [<>] +=== Liu Chao +image::liuchao93.png[width="150", align="left"] +{empty}[https://github.com/LiuChao93[github]] [<>] Role: Developer + -Responsibilities: UI +Responsibilities: Suppliers ''' diff --git a/docs/ContactUs.adoc b/docs/ContactUs.adoc old mode 100644 new mode 100755 index 81be279ef6d..909c66b4da1 --- a/docs/ContactUs.adoc +++ b/docs/ContactUs.adoc @@ -2,6 +2,10 @@ :site-section: ContactUs :stylesDir: stylesheets -* *Bug reports, Suggestions* : Post in our https://github.com/se-edu/addressbook-level3/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. +* *Bug reports, Suggestions* : Post in our https://github.com/AY1920S2-CS2103-W14-2/main/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. * *Contributing* : We welcome pull requests. Follow the process described https://github.com/oss-generic/process[here] -* *Email us* : You can also reach us at `damith [at] comp.nus.edu.sg` +* *Email us* : You can also reach us at +** `liu.chao5693@gmail.com` +** `nicholas.fernando@u.nus.edu` +** `e0203379@u.nus.edu` +** `pangjiada@u.nus.edu` diff --git a/docs/DevOps.adoc b/docs/DevOps.adoc index 2aa5a6bc0c1..b0b94d8c554 100644 --- a/docs/DevOps.adoc +++ b/docs/DevOps.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Dev Ops += InventoryManager - Dev Ops :site-section: DeveloperGuide :toc: :toc-title: @@ -12,7 +12,7 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main/tree/master == Build Automation @@ -26,10 +26,6 @@ We use https://travis-ci.org/[Travis CI] and https://www.appveyor.com/[AppVeyor] We use https://coveralls.io/[Coveralls] to track the code coverage of our projects. See <> for more details. -== Documentation Previews - -When a pull request has changes to asciidoc files, you can use https://www.netlify.com/[Netlify] to see a preview of how the HTML version of those asciidoc files will look like when the pull request is merged. See <> for more details. - == Making a Release Here are the steps to create a new release. @@ -41,7 +37,7 @@ Here are the steps to create a new release. == Managing Dependencies -A project often depends on third-party libraries. For example, Address Book depends on the https://github.com/FasterXML/jackson[Jackson library] for JSON parsing. Managing these _dependencies_ can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives: +A project often depends on third-party libraries. For example, InventoryManager depends on the https://github.com/FasterXML/jackson[Jackson library] for JSON parsing. Managing these _dependencies_ can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives: [loweralpha] . Include those libraries in the repo (this bloats the repo size) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc old mode 100644 new mode 100755 index 3d65905a853..971a266143f --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Developer Guide += InventoryManager v1.4 - Developer Guide :site-section: DeveloperGuide :toc: :toc-title: @@ -12,9 +12,9 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main/tree/master -By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` +By: `AY1920S2-CS2103-W14-2`      Since: `Feb 2020`      Licence: `MIT` == Setting up @@ -30,9 +30,8 @@ image::ArchitectureDiagram.png[] The *_Architecture Diagram_* given above explains the high-level design of the App. Given below is a quick overview of each component. -[TIP] +[NOTE] The `.puml` files used to create diagrams in this document can be found in the link:{repoURL}/docs/diagrams/[diagrams] folder. -Refer to the <> to learn how to create and edit diagrams. `Main` has two classes called link:{repoURL}/src/main/java/seedu/address/Main.java[`Main`] and link:{repoURL}/src/main/java/seedu/address/MainApp.java[`MainApp`]. It is responsible for, @@ -62,24 +61,26 @@ For example, the `Logic` component (see the class diagram given below) defines i image::LogicClassDiagram.png[] [discrete] -==== How the architecture components interact with each other +==== How the architecture components interact with each other (By Pang Jia Da) -The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. +The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues the command `delete-s 1`. -.Component interactions for `delete 1` command +.Component interactions for `delete-s 1` command +//tag::ArchitectureSequenceDiagram[] image::ArchitectureSequenceDiagram.png[] +//end::ArchitectureSequenceDiagram[] The sections below give more details of each component. [[Design-Ui]] -=== UI component +=== UI component (by Fang Shao Hua) .Structure of the UI Component image::UiClassDiagram.png[] *API* : link:{repoURL}/src/main/java/seedu/address/ui/Ui.java[`Ui.java`] -The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. +The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `SupplierListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the link:{repoURL}/src/main/java/seedu/address/ui/MainWindow.java[`MainWindow`] is specified in link:{repoURL}/src/main/resources/view/MainWindow.fxml[`MainWindow.fxml`] @@ -89,7 +90,7 @@ The `UI` component, * Listens for changes to `Model` data so that the UI can be updated with the modified data. [[Design-Logic]] -=== Logic component +=== Logic component (by Fang Shao Hua) [[fig-LogicClassDiagram]] .Structure of the Logic Component @@ -98,41 +99,81 @@ image::LogicClassDiagram.png[] *API* : link:{repoURL}/src/main/java/seedu/address/logic/Logic.java[`Logic.java`] -. `Logic` uses the `AddressBookParser` class to parse the user command. +. `Logic` uses the `InventoryManagerParser` class to parse the user command. . This results in a `Command` object which is executed by the `LogicManager`. -. The command execution can affect the `Model` (e.g. adding a person). +. The command execution can affect the `Model` (e.g. adding a supplier). . The result of the command execution is encapsulated as a `CommandResult` object which is passed back to the `Ui`. . In addition, the `CommandResult` object can also instruct the `Ui` to perform certain actions, such as displaying help to the user. -Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` API call. +:numbered!: +=== (By Pang Jia Da) +:numbered: -.Interactions Inside the Logic Component for the `delete 1` Command -image::DeleteSequenceDiagram.png[] +Given below is the Sequence Diagram for interactions within the `Logic` +component for the `execute("buy 1 g/Apple q/50")` API call. -NOTE: The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +.Interactions Inside the Logic Component for the `buy 1 g/Apple q/50` Command +//tag::buysequencediagram[] +image::BuySequenceDiagram.png[] +//end::buysequencediagram[] -[[Design-Model]] -=== Model component +NOTE: The lifeline for `BuyCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. -.Structure of the Model Component -image::ModelClassDiagram.png[] +//tag::model[] + +[[Design-Model]] +=== Model component (by Nicholas Cristian Fernando) *API* : link:{repoURL}/src/main/java/seedu/address/model/Model.java[`Model.java`] The `Model`, * stores a `UserPref` object that represents the user's preferences. -* stores the Address Book data. -* exposes an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. +* stores three sets of versioned data: `VersionedAddressBook`, `VersionedInventory` and `VersionedTransactionHistory`, +which inherit features from their non-versioned counterparts +* exposes three unmodifiable lists: `ObservableList`, `ObservableList` and `ObservableList` +to be observed and displayed by the UI. * does not depend on any of the other three components. -[NOTE] -As a more OOP model, we can store a `Tag` list in `Address Book`, which `Person` can reference. This would allow `Address Book` to only require one `Tag` object per unique `Tag`, instead of each `Person` needing their own `Tag` object. An example of how such a model may look like is given below. + - + -image:BetterModelClassDiagram.png[] +.Structure of the Model Component +image::ModelClassDiagram.png[] + +The `AddressBook` stores a list of `Supplier` objects, which each: + +* stores details of a supplier: `Name`, `Phone`, `Address`, `Email` and `Offer`. +* can have variable number of `Offer` objects, representing an offer to sell a specific good at a specific price. +* links to a `GoodName` and a `Price` via each of its `Offer` objects + +.Structure of the AddressBook +image::SupplierModelClassDiagram.png[] + +The `Inventory` stores a list of `Good` objects, which each stores details of a good: + +* its name `GoodName`, +* two quantities represented by two `GoodQuantity` objects, one indicating the current quantity and the other the +minimum threshold quantity + +.Structure of the Inventory +image::GoodModelClassDiagram.png[] + +The `TransactionHistory` stores a list of `Transaction` objects. Each `Transaction` stores common details of a transaction: + +* `TransactionId` for unique identification, +* `GoodName` for the transaction good, and +* `GoodQuantity` for the transaction quantity. + +A `Transaction` can be either `SellTransaction` or `BuyTransaction`: + +* `SellTransaction` has a `Price` to indicate the price at which the goods is sold. +* `BuyTransaction` has a `Supplier` and a `Price` to indicate the supplier and the price the goods is bought at respectively. + +.Structure of the TransactionHistory +image::TransactionModelClassDiagram.png[] + +//end::model[] [[Design-Storage]] -=== Storage component +=== Storage component (by Fang Shao Hua) .Structure of the Storage Component image::StorageClassDiagram.png[] @@ -142,105 +183,632 @@ image::StorageClassDiagram.png[] The `Storage` component, * can save `UserPref` objects in json format and read it back. -* can save the Address Book data in json format and read it back. +* can save 3 sets of data: `AddressBook`, `Inventory` and `TransactionHistory` in json format, save them in separate json file and read the data back. [[Design-Commons]] === Common classes -Classes used by multiple components are in the `seedu.addressbook.commons` package. +Classes used by multiple components are in the `cs2103_w14_2.inventory.commons` package. == Implementation -This section describes some noteworthy details on how certain features are implemented. +This section describes some noteworthy details on how certain features +are implemented and pitfalls to avoid when making modifications. + +//tag::buyandsellcommand[] +=== Buy and Sell Commands (By Pang Jia Da) + +The `buy` and `sell` commands are the main ways a user is expected to +interact with the Inventory Manager, and encompasses the bulk of the commands a +user is going to enter into Inventory Manager. + +==== Commonalities in Implementation of `buy` and `sell` + + +Both `buy` and `sell` commands are required to accomplish 3 things: + +. Update the quantity in the inventory, subject to their respective validity +checks. +. Create a transaction record of itself to be added to the transaction history. +. Commit the mutated model to facilitate proper functioning of `undo` and `redo` +commands + +The API that `Model` exposes has been structured to mirror the requirements +of the commands. The above 3 requirements can be satisfied by calls to: + +. `Model#setGood()` +. `Model#addTransaction()` +. `Model#commit()`. + +==== Specifics of `buy` Command +The two ways `buy` executes successfully depends on whether the good +already exists in the inventory or not. + +* If the good does not already exist, then a new Good +entry has to be created with the quantity bought. + +* If it does exist, then the +existing good entry has to be retrieved, and the quantity updated. + +[CAUTION] +Developers modifying existing `Good` related information must be aware that +Goods are immutable. In updating only the `quantity` field, all other fields +must be correctly duplicated to the updated `Good` entry created. Common mistakes +are to omit those fields, resulting in loss of persistent Good related +information. To make explicit this requirement to future Developers, multiple +constructors have been created with their respective purposes documented: +`Good()`, `Good.newGoodEntry()`, `Good.goodWithName()`. + + +===== Buy Command Input Constraints +The following constraints have been put on `buy` command inputs. Their reasons +are discussed in the following section. Users will not be allowed to: + +. Purchase from a supplier that is not in the supplier list +. Purchase a good that the supplier does not offer. +. Purchase a quantity of good that would cause the total quantity of any +individual good in the inventory to exceed the `Good` limit. + +[NOTE] +The maximum `Good` limit is 999,999. + +Developers seeking to modify the `buy` command must respect +the above 3 input validations as they form the basis of future features. + +[NOTE] +The `buy` command format is: `buy SUPPLIER_DISPLAYED_INDEX g/GOODNAME q/QUANTITY` + +The current implementation of `buy` performs validation of the above +respectively as follows: + +. The `SUPPLIER_DISPLAYED_INDEX` must be within the length of list of suppliers +returned by `Model#getFilteredSupplierList()`. +. Get the offers of the supplier through `Supplier#getOffers()`. +Iterate through the `Set` of the selected supplier to find +existence of an `Offer` with `GOODNAME`. +. Reuse the inbuilt quantity validation in the `Good` constructor to test +if the resulting inventory quantity is valid. A `Good` with the new quantity +is constructed. If the quantity is invalid, an error is thrown and the +relevant feedback to the user returned. + +==== Design Considerations + +===== Aspect: Format of `buy` command + +* **Alternative 1 (current choice):** `buy SUPPLIER_DISPLAYED_INDEX g/GOODNAME + q/QUANTITY`. +** Pros: +*** Users would not have to type out the entire Supplier's name in full and +case sensitive. This increases command input speed and further optimizes usage +for fast typists. Wasted time from typos in minimized. +*** Verification that a supplier exists in the supplier list is trivial. The +supplier at the given index only needs to be retrieved. + +** Cons: +*** We lose the flexibility of having input parameters being unordered. +All inputs with a prefix flag, e.g. `g/`, can be input in any order, but now +the ``SUPPLIER_DISPLAYED_INDEX`` has to be the first parameter. +*** Additional cognitive burden on users to remember the `buy` command format's +first parameter. + + +* **Alternative 2:** `buy n/SUPPLIER_NAME g/GOODNAME q/QUANTITY`. +** Pros: Flexibility of having unordered input is maintained. +** Cons: Testing revealed that command entry was tedious and error prone, +especially since supplier names tended to be long and a mix of upper- and lower- +case alphabets, reducing user-friendliness. + +===== Aspect: `buy` Input Constraints: +* **Alternative 1 (current choice):** Supplier has to exist in supplier list +before purchase. + +** Pros: +*** Supports future data analytics commands. We can save all relevant +transaction information with every particular supplier at the point of +transaction because the supplier will have to exist in the supplier list. +The feasible future features include: cost analysis and +ranking of suppliers by certain parameters. +*** Users do not have to enter an additional parameter: purchase price, +since this can be extracted from the Supplier's offer under the hood. + +** Cons: If user has making a new purchase, he or she has to first perform data entry +for the supplier and all it's relevant information before the `buy` command +can be executed. + +* **Alternative 2:** Supplier would be an optional parameter to the buy command. + +** Pros: Command usage is more fluid and user-friendly. + +** Cons: Cost and supplier related data would be incomplete, reducing +comprehensiveness of data analytics commands. + + +==== Specifics of `sell` Command + +===== Sell Command Input Constraints +The following constraints have been put on `sell` command inputs. Their reasons +are discussed in the following section. Users will not be allowed to: + +. Sell a good they do not currently have in inventory. +. Sell a quantity a larger quantity of a good than they currently +have in inventory. + +[NOTE] +The minimum `Good` limit is 0. + +Developers seeking to modify the `sell` command must respect +the above 2 input validations as they form the basis of future features. + +[NOTE] +The `sell` command format is: `sell GOOD_DISPLAYED_INDEX p/PRICE q/QUANTITY` + +The current implementation of `sell` performs validation as follows: + +. The `GOOD_DISPLAYED_INDEX` must be within the length of list of Goods +returned by `Model#getFilteredGoodList()`. +. Reuse the inbuilt quantity validation in the `Good` constructor to test +if the resulting inventory quantity is valid. A `Good` with the new quantity +is constructed. If the quantity is invalid, an error is thrown and the +relevant feedback to the user returned. + +==== Design Considerations + +===== Aspect: Format of `sell` command + +* **Alternative 1 (current choice):** `sell GOOD_DISPLAYED_INDEX p/PRICE + q/QUANTITY`. +** Pros: +*** Users would not have to type out the entire Good's name in full and +case sensitive. This increases command input speed and further optimizes usage +for fast typists. Wasted time from typos in minimized. +*** Verification that a good exists in the inventory is trivial. The +good at the given index only needs to be retrieved. + +** Cons: +*** We lose the flexibility of having input parameters being unordered. +All inputs with a prefix flag, e.g. `g/`, can be input in any order, but now +the ``GOOD_DISPLAYED_INDEX`` has to be the first parameter. +*** Additional cognitive burden on users to remember the `sell` command format's +first parameter. + + +* **Alternative 2:** `sell g/GOOD_NAME p/PRICE q/QUANTITY`. +** Pros: Flexibility of having unordered input is maintained. +** Cons: Testing revealed that command entry was tedious and error prone, +especially since Good names tended to be long and a mix of upper- and lower- +case alphabets, reducing user-friendliness. + +//end::buyandsellcommand[] // tag::undoredo[] -=== [Proposed] Undo/Redo feature -==== Proposed Implementation -The undo/redo mechanism is facilitated by `VersionedAddressBook`. -It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. -Additionally, it implements the following operations: +=== Undo/Redo feature (by Nicholas Cristian Fernando) +==== Implementation -* `VersionedAddressBook#commit()` -- Saves the current address book state in its history. -* `VersionedAddressBook#undo()` -- Restores the previous address book state from its history. -* `VersionedAddressBook#redo()` -- Restores a previously undone address book state from its history. +The undo/redo mechanism is facilitated by three versioned databases `VersionedInventory`, `VersionedAddressBook` and `VersionedTransactionHistory` +for `Good`, `Supplier` and `Transaction` data respectively. These versioned classes extend their non-versioned +counterparts. These classes also implement the `Versionable` interface, which has these methods: -These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively. +* `Versionable#commit()` -- Adds the current state to the tracked states. +* `Versionable#undo()` -- Restores the previous database state. +* `Versionable#redo()` -- Restores the most recently undone database state. + +These operations are exposed in the `Model` interface, which extends `Versionable` as well. +Each call of these methods will call the respective methods of each of the versioned classes. + +The class diagram below shows how the classes are related to each other. + +image::VersionClassDiagram.png[] + +The three versioned classes use the same logic for versioning, so only `VersionedInventory` will be mentioned in +subsequent examples and diagrams. + +The sequence diagram below illustrates the events that occur when a user calls the undo command assuming that there is +a state to return to. `VersionedAddressBook#undo()` and `VersionedTransactionHistory#undo()` are called as well, but +omitted for brevity. + +image::UndoSequenceDiagram.png[] + +Currently, `VersionedInventory` uses `LinearHistory` for versioning, and delegates all `Versionable` methods +to it. `LinearHistory` can store objects of `Inventory` class, which has implemented the `Copyable` interface to allow +creation of independent copies for storage. On the other hand, `LinearHistory` implements the interface +`Version`, which extends from `Versionable` and has the following additional method: + +* `Version#getCurrentState()` -- Returns the current state of the stored object + +The class diagram below shows how the classes are connected such that `VersionedInventory` is able to use +`LinearHistory`. + +image::LinearHistoryClassDiagram.png[] + +NOTE: The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the +lifeline reaches the end of diagram. Given below is an example usage scenario and how the undo/redo mechanism behaves at each step. +For simplicity, goods are each represented with strings containing their name and quantity. -Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state. +Step 1. The user launches the application for the first time. The `VersionedInventory` will be created with a list +of `Good` objects from storage, while creating a `LinearHistory` that stores a copy of this state, +and also stores another copy in its history. Using `copy()` method from `Copyable` ensures +`currentState` and `saved0` are independent `Inventory` objects. image::UndoRedoState0.png[] -Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state. +Step 2. The user executes `delete-g 3` command to delete the 3rd good in the inventory list. The `delete-g` command +first deletes the 3rd good in the `currentState` of the `LinearHistory`, exposed by `VersionedInventory`. +Then, the command calls `Model#commit()` since it modifies the data. `LinearHistory` then +makes a copy of the modified `currentState` and stores it in the history, moving the statePointer up. image::UndoRedoState1.png[] -Step 3. The user executes `add n/David ...` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. +Step 3. The user executes `buy 1 g/apple q/5` to buy 5 apples from the first supplier. Let us assume that the first +supplier sells apples. The `buy` command also calls `Model#commit()` as it modifies the data, +causing `LinearHistory` to save a copy of the modified `currentState`. image::UndoRedoState2.png[] [NOTE] -If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`. +If a command fails its execution, it will not call `Model#commit()`, so the `currentState` will not be saved +into the history. -Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state. +Step 4. The user now decides that buying the apples was a mistake, and decides to undo that action by executing the +`undo` command. The `undo` command will call `Model#undo()`, which will shift the `statePointer` one step backward, +pointing it to the previous saved state `saved1`, and updates `currentState` with `saved1`. image::UndoRedoState3.png[] [NOTE] -If the `currentStatePointer` is at index 0, pointing to the initial address book state, then there are no previous address book states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo. - -The following sequence diagram shows how the undo operation works: - -image::UndoSequenceDiagram.png[] +If the `currentStatePointer` is pointing to the first state `saved0`, then there is no state to return to. +In this case, it will return an error to the user rather than attempting to perform the undo. -NOTE: The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. - -The `redo` command does the opposite -- it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state. +The `redo` command does the opposite -- it calls `Model#redo()`, which shifts the `currentStatePointer` one step forward, +pointing to the previously undone state, and restores the `currentState` to that state. [NOTE] -If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone address book states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo. +If the `currentStatePointer` is pointing to the latest state, then there are no states to go to. +Thus, it will return an error to the user rather than attempting to perform the redo. -Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged. +Step 5. The user then decides to execute the command `list-t`. Commands that do not modify the data, such as `list-t`, +will not call `Model#commit()`. Thus, the history and `currentState` in `LinearHistory` remains unchanged. image::UndoRedoState4.png[] -Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. We designed it this way because it no longer makes sense to redo the `add n/David ...` command. This is the behavior that most modern desktop applications follow. +Step 6. The user executes `sell 2 q/1 p/5` to sell 1 of the second goods in the list, banana. This calls `Model#commit()`. +Since there is a branching in history, all states after the state pointed by `statePointer` will be purged. +Many mainstream editing software exhibit this behaviour, which would condition the user to expect this +behavior. image::UndoRedoState5.png[] -The following activity diagram summarizes what happens when a user executes a new command: +The activity diagram below shows the conditions under which `Model#commit()` is called by a command, and its effects. +As shown, only undoable commands that are successfully executed will call `Model#commit()` and purge the "future" states. +This behavior in command execution guards against unwanted states being saved during invalid commands and confusing the +user. In addition, the guard against invalid execution at the start helps to keep the `currentState` free of changes +when the command will be invalid. Thus, the correctness of the `commit()` behavior is tied to the correct command +execution protocol. -image::CommitActivityDiagram.png[] +image::CommitActivityDiagram.png[width=50%] ==== Design Considerations ===== Aspect: How undo & redo executes -* **Alternative 1 (current choice):** Saves the entire address book. -** Pros: Easy to implement. -** Cons: May have performance issues in terms of memory usage. +* **Alternative 1 (current choice):** Saves the entire state of the database. +** Pros: Trivial implementation. +** Cons: May encounter performance issues due to memory load, especially with three different databases. * **Alternative 2:** Individual command knows how to undo/redo by itself. -** Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). +** Pros: Will use less memory (e.g. for `delete-s`, just save the supplier being deleted). ** Cons: We must ensure that the implementation of each individual command are correct. -===== Aspect: Data structure to support the undo/redo commands +===== Aspect: When to save history -* **Alternative 1 (current choice):** Use a list to store the history of address book states. -** Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project. -** Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both `HistoryManager` and `VersionedAddressBook`. -* **Alternative 2:** Use `HistoryManager` for undo/redo -** Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase. -** Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as `HistoryManager` now needs to do two different things. +* **Alternative 1 (current choice) :** Save all three databases even when only one database is modified. +** Pros: Easy to implement. +** Cons: Inefficient memory usage, especially when only one database is being modified in each action. +* **Alternative 2:** Save a database only when that database is modified. +** Pros: Saves memory usage that could be used for performance. +** Cons: Requires information on which databases are affected by a command, which breaks abstraction on both the +versioned databases and commands. + +===== Aspect: How storage of states is implemented + +* **Alternative 1 (current choice) :** Store states as objects during Java runtime +** Pros: Simple implementation and automatic cleanup. +** Cons: Segmentation fault may occur for very long sessions and large databases. +* **Alternative 2:** Store states in an external file +** Pros: Less memory usage, leading to better performance. +** Cons: File I/O may incur comparable overhead, and abrupt termination of the application may +result in temporary files being left behind and cluttering space. // end::undoredo[] -// tag::dataencryption[] -=== [Proposed] Data Encryption -_{Explain here how the data encryption feature will be implemented}_ +=== Supplier Feature (By Liu Chao) +InventoryManager allows users (store managers) to record the `suppliers` whom they buy goods from. Users could add and +store the information of `suppliers` such as company name, company address, registered phone number, official email +address and goods that company is selling. + +A `supplier` can be stored as a `supplier` object in the InventoryManager. The main components are 1) company name, +2) company address, 3) registered phone number, 4) official email address and 5) good-price pairs of goods that company +is selling. Company name is used to identify the company since every company needs to have an unique name which is +registered legally with Accounting and Corporate Regulatory Authority. A Good-price pair of good is a combination of records +of a good’s name and a selling price. Good-price pairs are stored as an offer object in the InventoryManager. The following is a class diagram of Supplier feature. + +.Class diagram of `Supplier` Feature, displaying only directly related classes +image::SupplierModelClassDiagram.jpg[] + +==== Edit Supplier Feature +Users could edit and update the information of registered supplier should there be any changes in InventoryManager by +using the EditSupplierCommand. +The edit supplier command format: `edit-s INDEX (must be a positive integer) [n/NAME] [c/PHONE] [e/EMAIL] [a/ADDRESS] [gp/GOOD_PRICE_PAIR]…` + +===== Implementation + +The following sequence diagram shows how the information of existing suppliers (`supplierToEdit`) could be updated by the `EditSupplierCommand`. +`EditSupplierCommandParser` creates a `EditSupplierDescriptor` object to store all the information that needs to be updated to a supplier. +Then both `index` of the supplier that aims to be edited and the `EditSupplierDescriptor` object are passed to the `EditSupplierCommand` where +a new supplier object (`editedSupplier`) will be created by combining the information of the `supplierToEdit`, which has gotten by searching through the address book by using `index`, +and the new information stored in the `EditSupplierDescriptor` object. The original supplier (`supplierToEdit`) is replaced by the newly created supplier object (`editedSupplier`) by using the `model.setSupplier`. + +.Sequence diagram of Edit Supplier Feature +image::SequentialDiagramEditSupplier.png[] + +[NOTE] +The sequence diagram is generated using PowerPoint. There may be some formatting issues and drawings may not be to scale. + + +The detailed activity diagram of editing a supplier is shown below. + +.Activity Diagram of Edit Supplier Feature +image::ActivityDiagramEditSupplier.jpg[] + +[NOTE] +The activity diagram is generated using PowerPoint. There may be some formatting issues and drawings may not be to scale. + + +===== Design Considerations +Users could involve any number of fields that is a positive number to edit the existing supplier. Fields include 1) company name, +2) company address, 3) registered phone number, 4) official email address and 5) good-price pairs of goods that company is selling. +If the good is not present in the existing supplier’s list, the good will be added into the supplier’s list as a new good price pair entry. +Otherwise, if the good is already present in the supplier’s list, then the good price pair of that good in the supplier’s list will be +edited and updated to the entered values. This feature is also used to add another good price pair for the supplier. + +We choose to allow users to edit any number of fields is to provide convenience for the users as the users could edit multiple +fields at once with flexibility. We choose to use this feature to add a new good price pair for the supplier is to prevent having +an additional command (e.g. include good price pair), which may confuse the users if there is too many commands involved in the +application. In addition, using this feature will prevent users from adding a new entry of the same good that is already +existed in the supplier’s list. Furthermore, we are using index to allocate suppliers (edit-s 1) instead of using company name +(edit-s NTUC) is to provide convenience for the users who could find it challenging to type full company name and could easily +allocate index of supplier from the supplier panel. + +==== Delete Good Price Pair from Supplier +The delete-gp command is the main way a user could delete an entry or entries of good price pair(s) in a supplier’s list. +The user could delete multiple entries of good price pairs by using multiple good names in one command. + +The delete good price pair command format: delete-gp INDEX (must be a positive integer) g/GOOD_NAME [g/MORE_GOOD_NAME]... + +The current implementation of delete good price pair command performs validation as follows: + +. INDEX must be within the length of list of suppliers returned by Model#getFilteredSupplierList(). +. Get the offers of the supplier through Supplier#getOffers(). Iterate through the Set of the selected supplier to +find existence of an Offer with GOODNAME to be deleted. +. Prefix of good name of good to be deleted is validated with GoodName class to check the validity of good name. +. If the user input contains good name. if users do not include good name, the command will throw exception that at least +one good name must be included. + +==== Commonalities in Implementation of delete-gp command +The delete-gp command is required to accomplish 5 things: + +. Allocate the supplier that is targeted by using the index subject to validity check. +. Find and allocate the good price pair(s) specific by the input good name(s). +. Delete the necessary good price pair(s) in the supplier’s list +. Inform users which goods are successfully deleted and which goods could not be found at the CommandResult. +. Commit the mutated model to facilitate proper functioning of undo and redo commands + +==== Design Considerations +Aspect: format of delete good price pair command + +* Alternative 1 (current choice): delete-gp INDEX (must be a positive integer) g/GOOD_NAME [g/MORE_GOOD_NAME]... +** Pros +*** It is able to check if the user includes good name in the command. +*** User will not accidently delete a supplier entry by omitting good name like alternative 2. +** Cons +*** Users need to remember another command + +* Alternative 2 (modifying delete supplier’s command): delete-s INDEX (must be a positive integer) g/GOOD_NAME [g/MORE_GOOD_NAME]... +(This is such a way that if user does not include good price pair, the command will delete the supplier entry. If the +user includes the good price pair, the command will not delete the supplier’s entry but rather edits the good price pairs +in the supplier’s list like alternative 1.) +** Pros +*** Users do not need to remember another command. +** Cons +*** Users could accidently delete a supplier entry by forgetting to input good name. + +Aspect: Ability to delete multiple good price pairs at one command + +* Alternative 1 (current choice): Users could delete multiple good price pairs by using one command +** Pros +*** Convenience for the Users +** Cons +*** Harder to implement than alternative 2 +*** More prone to errors and bugs. +*** Users may forget what the good price pairs are deleted and do not know what are the good price pairs that could not +be found if there is a large number of entries. +* Alternative 2: Users could only delete one good price pair by using one command. +** Pros +*** Easy to implement +*** Less prone to errors and bugs +*** At every command, users could know which good price pair entry is successfully deleted and which good price pair could +not be found. +** Cons +*** Inconvenience for the users. + +The current implementation will give a summary of all good price pairs that are successfully deleted and all good price +pairs that could not be found to assist the users. + +//tag::autoexpiry[] + +=== [Proposed] Automatic Batch Expiry and Warning (By Pang Jia Da) + +The primary aim of inventory management is to ensure that there is always +sufficient stock of goods. Out-of-stock situations +cost the company needless revenue losses. + +When stores sell fast moving consumer goods with short shelf lives, +this problem becomes hard to solve when every individual batch of purchases +have their respective expiry dates. + +This feature aims to augment every `buy` command with it's respective +`EXPIRY_DATE`. When the expiry date approaches, unsold goods from that batch +would automatically be removed from the inventory, the user would be notified +of the expiration and warned if that causes the good to fall below it's +stipulated threshold. The command to source for suppliers who sell that good can +also be triggered to facilitate restocking of that good. + +==== Proposed Implementation + +===== Proposed Changes to `Good` class +Inventory Manager v1.4 currently stores the name, current quantity, and +threshold quantity of every good in the inventory. An `expiryDates` field +will be added to store all distinct expiry dates, from closest to furthest, and +the number of units expiring on that date. Java's built-in `Date` class +will suffice. + +//tag::goodclassenhancement[] +image:GoodWithExpiryDate.png[] +//end::goodclassenhancement[] + +===== Proposed Changes to `buy` Command + +The `buy` command will include an expiry date for every purchase +goods. A possible format would be: `buy SUPPLIER_DISPLAYED_INDEX q/QUANTITY +g/GOOD_NAME x/EXPIRY_DATE`. This assigns the `EXPIRY_DATE` to all `QUANTITY` +units of `GOOD_NAME` bought. + +The correct `Good` entry can be retrieved from the `InventoryManager`. +If there is currently no expiry dates on `EXPIRY_DATE`, a new `Map.entry` +will be created indicating that `QUANTITY` many units will expire on +`EXPIRY_DATE`. Else, the current `Map.entry` will be updated. + +===== Proposed Changes to `sell` Command + +Under this implementation, the `sell` command must sell goods in a +First-In-First-Out (FIFO) manner. When any valid `sell` command is entered, +the earliest expiry dates are removed first. This is accomplished by reducing +the values that are mapped to the earliest expiry dates. + +===== Expiry Detection + +Upon Inventory Manager Program startup, the `expiryDates` of all `Good` s in the +inventory is checked with the current System Date. When any expiry date is found +to be earlier than the System date, the mapped number of goods will expire +and be removed from inventory. + +===== Possible Extensions +Possible extensions of usefulness are listed below: + +. Make any expiry event generate it's respective transaction record in the +transaction history. +. If goods fall below their warning threshold as a result of expiry, +have a notification to the user and display the list of suppliers that +sell that particular good, sorted by increasing price. + +==== Design Considerations + +===== Aspect: Data Structure for `expiryDates` + +* **Alternative 1 (current choice):** Use a `TreeMap` +** Pros: Memory efficient. +** Cons: +*** `TreeMap` navigation is more complex than a linear data structure. +*** Updating is more complex for `sell` commands, especially if goods with +multiple expiry dates are being sold. + +* **Alternative 2:** Maintain an ordered `LinkedList`. +** Pros: Simple to implement and update. +*** Buying `QUANTITY` of a good would correspond to inserting `QUANTITY` of +`EXPIRY_DATE` into the list and sorting it. +*** Selling `QUANTITY` of a good would correspond to removing the first +`QUANTITY` elements. +*** Finding all expired items can be done be traversing down the list until +the first non-expired item is found. Everything traversed has expired. + +** Cons: +*** Extremely memory inefficient, especially since each `Good` can contain +up to `999,999` quantity, and there will be 1 `Date` for each good stored. + +//end::autoexpiry[] + +// tag::findtransaction[] + +=== Find transaction (By Fang Shao Hua) + +Inventory Manager has a find transaction feature which allows the user to filter transactions, so that it +saves time for the user to look for specific transactions among the transaction history. + +User can provide 3 different types of filter, or combination of filters to filter the transaction list. +These 3 types of filter are `TransactionType`, `Name` and `GoodName`. + +To extract out these filter specifications, `ArgumentMultimap` is needed. +`TransactionType` will be stored in the `preamble`, `Name` will stored in the value under prefix `n/` +and `GoodName` will be stored in the value under prefix `g/`. + +`FindTransactionCommandParser` will called `ArgumentMultimap` to parse the user input into respective values. +These values will then set up filters in the `Predicate` for the model to filter the transaction list. + +If the user did not specify a particular type of filter, that particular type of filter will not be activated. +The feature requires at least one filter to be able to functional. + +For the `Name` and `GoodName` filters, these filters can take in multiple `Name` and `GoodName` respectively. +This means that there can be multiple `Name` keywords in the `Name` filter, and the transaction only need to match +any of the `Name` to pass the filter. Same goes for the `GoodName` filter. + +NOTE: The transaction has to fulfill all active filters to be added into the filtered list. + +Here is a sample activity diagram that shows the general flow: + +image::FindTransactionActivityDiagram.png[] + +This feature mainly involves within `Logic`, but also require interaction with `Model` to update the filter list. + +Here is a sample activity diagram that shows the flow when user inputs: `find-t buy n/alice g/apple`: + +image::FindTransactionSequenceDiagram.png[] + +==== Design Considerations + +===== Aspect: Multiple filters +* **Alternative 1 (current choice):** Enables multiple filters to filter the transaction list +** Pros: Enable easier and flexible search. +** Cons: More complex to implement, need to take care of multiple cases. +* **Alternative 2:** Decompose search function into multiple functions, each consist of single filter +** Pros: Easier to implement, less complexity +** Cons: More code need to be written, and the code will have high degree of duplication. Less flexible search. + +// end::findtransaction[] + +// tag::setthreshold[] + +=== Set threshold for good (By Fang Shao Hua) + +Inventory Manager has a set threshold feature which allows the user to set the threshold quantity for `goods` in `Inventory`, +so that it can alert the user when a particular good fall below its threshold quantity. + +The alert mechanism is to resort the goods in the inventory such that those fall below their their threshold will be display first, +and their current quantity will be display with red background. + +Every command that changes the quantity of good or set new threshold for the good in the inventory will trigger a check and update the filtered list accordingly. + +NOTE: By default, any newly added good in the inventory will be set with threshold quantity of zero. + +Here is a sample activity diagram that shows the flow when user inputs: `warn 5 q/100`: + +image::SetThresholdSequenceDiagram.png[] + +image::SetThresholdSequenceDiagram2.png[] + +// end::setthreshold[] + -// end::dataencryption[] === Logging @@ -279,13 +847,15 @@ Refer to the guide <>. *Target user profile*: -* has a need to manage a significant number of contacts +* has a need to manage a large number of <> which arrives in batches +* has a need to manage a large number of suppliers +* has a need to draw insights from analysing transactions with suppliers and customers * prefer desktop apps over other types * can type fast * prefers typing over mouse input * is reasonably comfortable using CLI apps -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app +*Value proposition*: manage an FMCG store faster than a typical mouse/GUI driven app [appendix] == User Stories @@ -295,35 +865,61 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un [width="59%",cols="22%,<23%,<25%,<30%",options="header",] |======================================================================= |Priority |As a ... |I want to ... |So that I can... -|`* * *` |new user |see usage instructions |refer to instructions when I forget how to use the App +|`* * *` |new user |see usage instructions |refer to instructions when I forget how to use InventoryManager -|`* * *` |user |add a new person | +|`* * *` |user |add a new supplier | -|`* * *` |user |delete a person |remove entries that I no longer need +|`* * *` |user |add a new goods to supplier| -|`* * *` |user |find a person by name |locate details of persons without having to go through the entire list +|`* * *` |user |delete a supplier |remove entries that I no longer need -|`* *` |user |hide <> by default |minimize chance of someone else seeing them by accident +|`* * *` |user |see goods that are low in stock |know what to buy -|`*` |user with many persons in the address book |sort persons by name |locate a person easily -|======================================================================= +|`* * *` |user |see goods that are low in stock |buy more before running out + +|`* * *` |user |update inventory with the <> |avoid keeping track of the inventory personally + +|`* * *` |user |update prices of goods offered by suppliers |account for changes in supply agreement or prices + +|`* * *` |clumsy user |undo previous actions |fix mistakes in inputs or spelling + +|`* * *` |user |be notified of goods falling below a set quantity threshold |buy expected goods in advance + +|`* * *` |user |be notified of goods that are above a set quantity threshold |avoid expiration of large number of goods + +|`* *` |user |create a set purchase order automatically on a regular basis |simulate supply contracts + +|`* *` |user |find a supplier by goods sold |locate the relevant suppliers without having to go through the entire list -_{More to be added}_ +|`* *` |user |find a goods by name |locate the relevant goods without having to go through the entire list + +|`* *` |user |hide transaction details by default |minimize chance of someone else seeing them by accident + +|`* *` |user |set expiry event for a batch of goods |account for expiration of goods + +|`* *` |user |change names of goods |avoid confusion when producers change the name of their products + +|`* *` |user |have a summary of the transactions throughout the day |determine performance of the day + +|`* *` |expanding user |see a performance tracker |find points of improvement in business activity + +|`*` |clumsy user |receive suggestion for the next words |avoid misspelling and be reminded of syntax + +|======================================================================= [appendix] == Use Cases -(For all use cases below, the *System* is the `AddressBook` and the *Actor* is the `user`, unless specified otherwise) +(For all use cases below, the *System* is the `InventoryManager` and the *Actor* is the `user`, unless specified otherwise) [discrete] -=== Use case: Delete person +:numbered!: +=== Use case: UC1 - listing all suppliers *MSS* -1. User requests to list persons -2. AddressBook shows a list of persons -3. User requests to delete a specific person in the list -4. AddressBook deletes the person +1. User requests to list suppliers. +2. InventoryManager shows a list of suppliers. + Use case ends. @@ -332,51 +928,445 @@ Use case ends. [none] * 2a. The list is empty. + +[none] +** 2a1. InventoryManager shows a message to inform that there are no suppliers. ++ Use case ends. -* 3a. The given index is invalid. +=== Use case: UC2 - listing all goods + +*MSS* + +1. User requests to list goods. +2. InventoryManager shows a list of goods. + +Use case ends. + +*Extensions* + [none] -** 3a1. AddressBook shows an error message. +* 2a. The list is empty. + -Use case resumes at step 2. +[none] +** 2a1. InventoryManager shows a message to inform that there are no goods. ++ +Use case ends. -_{More to be added}_ +=== Use case: UC3 - adding a supplier -[appendix] -== Non Functional Requirements +*MSS* -. Should work on any <> as long as it has Java `11` or above installed. -. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. -. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. +1. User requests to add a supplier with given details. +2. InventoryManager creates a supplier with the given details. ++ +Use case ends. -_{More to be added}_ +*Extensions* -[appendix] -== Glossary +[none] +* 1a. The given details of the supplier is incomplete. ++ +[none] +** 1a1. Inventory Manager shows an error message to indicate the incomplete details. ++ +Use case ends. -[[mainstream-os]] Mainstream OS:: -Windows, Linux, Unix, OS-X +[none] +* 1b. The given details of the supplier is invalid. ++ +[none] +** 1b1. Inventory Manager shows an error message to indicate the invalid details. ++ +Use case ends. -[[private-contact-detail]] Private contact detail:: -A contact detail that is not meant to be shared with others +[none] +* 1c. The given details contains a non-supported parameter e.g. age. ++ +[none] +** 1c1. Inventory Manager shows an error message to indicate the non-supported parameter. ++ +Use case ends. -[appendix] -== Product Survey +[none] +* 1d. The specified supplier already exists. ++ +[none] +** 1d1. Inventory Manager shows an error message to indicate that the supplier already exists. ++ +Use case ends. + +=== Use case: UC4 - deleting a supplier + +*MSS* + +1. User [.underline]#lists all suppliers (UC1).# +2. User selects a supplier from the list and requests to delete the supplier by the index shown on the list. +3. InventoryManager deletes the supplier. ++ +Use case ends. + +*Extensions* + +[none] +* 1a. The list is empty. ++ +[none] +** Use case ends. + +[none] +* 2a. The given index is invalid. ++ +[none] +** 2a1. InventoryManager shows an error message to indicate the invalid index. ++ +Use case ends. + +=== Use case: UC5 - deleting a good from supplier's list + +*MSS* + +1. User lists all suppliers (UC1). +2. User requests to delete a good from a supplier's list and give the good's name. +3. InventoryManager confirms the deletion. +4. InventoryManager deletes the good from the supplier's good list. ++ +Use case ends. + +*Extensions* + +1. The required good is not found. +** InventoryManager informs there is no such good found. ++ +Use case ends. + + +=== Use case: UC6 - editing a supplier + +*MSS* + +1. User lists all suppliers (UC1) +2. User requests to edit a supplier specified by the index and gives the new parameters +3. InventoryManager updates the details of the supplier. ++ +Use case ends. + +*Extensions* + +1. There is existing good in the list. +** The latest information of good will be updated. ++ +Use case ends. + +2. The given index is invalid. +** InventoryManager shows an error message to indicate the invalid index. ++ +Use case ends. + +3. The given details of the supplier is incomplete. +** Inventory Manager shows an error message to indicate the incomplete details. ++ +Use case ends. + +4. The given details of the supplier is invalid. +** Inventory Manager shows an error message to indicate the invalid details. ++ +Use case ends. + +5. The given details contains a non-supported parameter e.g. age. +** Inventory Manager shows an error message to indicate the non-supported parameter. ++ +Use case ends. + +6. The good is not found in the existing supplier's good list. +** Inventory Manager will include the good as a new good in the supplier's good list. ++ +Use case ends. + +=== Use case: UC7 - finding a supplier for a particular goods + +*MSS* + +1. User [.underline]#lists all goods (UC2).# +2. User requests to list the suppliers supplying the goods with a specified name. +3. InventoryManager shows a list of suppliers providing this goods. ++ +Use case ends. + +*Extensions* + +[none] +* 1a. The list is empty. ++ +[none] +** Use case ends. + +[none] +* 2a. The goods with the given name does not exist. ++ +[none] +** 2a1. InventoryManager shows an error message to indicate the goods does not exist. ++ +Use case ends. + +[none] +* 3a. The list is empty. ++ +[none] +** 3a1. InventoryManager informs the user that there are no suppliers providing this goods. ++ +Use case ends. + +=== Use case: UC8 - buying a particular goods + +*MSS* + +1. User [.underline]#lists all the suppliers for a particular good (UC7).# +2. User requests to make a buy order for a quantity of the particular goods from a supplier. +3. InventoryManager adds the order and adds the quantity to the total number of that particular goods. ++ +Use case ends. + +*Extensions* + +[none] +* 1a. The list is empty. ++ +[none] +** Use case ends. + +[none] +* 2a. The goods with the given name does not exist. ++ +[none] +** 2a1. InventoryManager shows an error message to indicate the goods does not exist. ++ +Use case ends. + +[none] +* 2b. The supplier with the given name does not exist. ++ +[none] +** 2b1. InventoryManager shows an error message to indicate the supplier does not exist. ++ +Use case ends. + +[none] +* 2c. The quantity given is invalid. ++ +[none] +** 2c1. InventoryManager shows an error message to indicate the quantity is invalid. ++ +Use case ends. + +[none] +* 2d. One or more parameters are missing. ++ +[none] +** 2d1. InventoryManager shows an error message to indicate the missing parameters. ++ +Use case ends. + +=== Use case: UC9 - selling a particular goods + +*MSS* + +1. User [.underline]#lists all goods (UC2).# +2. User requests to make a selling order of a quantity of a particular goods. +3. InventoryManager adds the sell order and deducts the quantity in the selling order to the total number of the particular goods. ++ +Use case ends. + +*Extensions* + +[none] +* 1a. The list is empty. ++ +[none] +** Use case ends. + +[none] +* 2a. The goods with the given name does not exist. ++ +[none] +** 2a1. InventoryManager shows an error message to indicate the goods does not exist. ++ +Use case ends. + +[none] +* 2b. The quantity given is invalid. ++ +[none] +** 2b1. InventoryManager shows an error message to indicate the quantity is invalid. ++ +Use case ends. -*Product Name* +[none] +* 2c. The quantity given exceeds current amount in inventory. ++ +[none] +** 2c1. InventoryManager shows an error message to indicate insufficient quantity. ++ +Use case ends. -Author: ... +[none] +* 2d. One or more parameters are missing. ++ +[none] +** 2d1. InventoryManager shows an error message to indicate the missing parameters. ++ +Use case ends. -Pros: +=== Use case: UC10 - set lower threshold quantity of goods -* ... -* ... +*MSS* -Cons: +1. User [.underline]#lists all goods (UC2).# +2. User sets a lower quantity threshold for a particular goods. ++ +Use case ends. + +*Extensions* + +[none] +* 1a. The list is empty. ++ +[none] +** Use case ends. -* ... -* ... +[none] +* 2a. The quantity is invalid. +[none] +** 2a1. InventoryManager shows an error message to indicate the quantity is invalid. ++ +Use case ends. + +[none] +* 2b. The quantity is above the upper threshold, if it exists. +[none] +** 2b1. InventoryManager shows an error message to indicate the quantity is above the upper threshold. ++ +Use case ends. + +[none] +* 2c. The given index is out of bounds. +[none] +** 2c1. InventoryManager shows an error message to indicate the index is out of bounds. ++ +Use case ends. + +=== Use case: UC11 - listing all past transactions + +*MSS* + +1. User requests to list all past transactions. +2. InventoryManager lists all past transactions. ++ +Use case ends. + +*Extensions* + +[none] +* 2a. The list is empty. ++ +[none] +** 2a1. InventoryManager informs the user that there are no past transactions. ++ +Use case ends. + +=== Use case: UC12 - search transactions with specific criteria + +*MSS* + +1. User requests to find transactions with the specific criteria. +2. InventoryManager lists all transactions fulfill the specific criteria. ++ +Use case ends. + +*Extensions* + +[none] +* 2a. The list is empty. ++ +[none] +** 2a1. InventoryManager informs the user that there are no transactions. ++ +Use case ends. + +[none] +* 2b. Any of the criteria is in invalid format +[none] +** 2b1. InventoryManager informs the user that the criteria input is invalid. ++ +Use case ends. + +// tag::undoredousecase[] + +=== Use case: UC13 - undoing a command + +*MSS* + +1. User enters the undo command through the command line. +2. InventoryManager moves to the state before the latest modifying command e.g. add supplier. +3. InventoryManager shows a message indicating success. ++ +Use case ends. + +*Extensions* + +[none] +* 2a. InventoryManager is at the oldest recorded state and thus is unable to move to a previous state. ++ +[none] +** 2a1. InventoryManager informs the user that it is unable to undo from the oldest recorded state. ++ +Use case ends. + +=== Use case: UC14 - redoing a command + +*MSS* + +1. User enters the redo command through the command line. +2. InventoryManager moves to the state before the latest undo command. +3. InventoryManager shows a message indicating success. ++ +Use case ends. + +*Extensions* + +[none] +* 2a. InventoryManager is unable to move to the next state as it is already at the latest state. ++ +[none] +** 2a1. InventoryManager informs the user that it is unable to redo from the latest state. ++ +Use case ends. + +// end::undoredousecase[] + +:numbered: + +[appendix] +== Non Functional Requirements + +. Should work on any <> as long as it has Java `11` or above installed. +. Should be able to hold up to 1000 suppliers and goods without a noticeable sluggishness in performance for typical usage. +. Should run without any internet connection. +. Should have a human-editable storage text file. +. Should not require a database. +. Should not require an installer to use. +. Should not exceed 100MB in application size. +. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. + +[appendix] +== Glossary +[[fast-moving-consumer-goods]] Fast-moving consumer goods:: +Goods that are characterised by large inventory quantities, high turnover rate, numerous suppliers and short shelf-life. + +[[transaction-record]] Transaction record:: +A record of an event that results in change in the quantity of goods i.e. buying/selling. + +[[mainstream-os]] Mainstream OS:: +Windows, Linux, Unix, OS-X. [appendix] == Instructions for Manual Testing @@ -392,7 +1382,8 @@ These instructions only provide a starting point for testers to work on; testers .. Download the jar file and copy into an empty folder .. Double-click the jar file + - Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. + Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. Mac OS users may need to + give permission to open JAR files initially. . Saving window preferences @@ -400,26 +1391,102 @@ These instructions only provide a starting point for testers to work on; testers .. Re-launch the app by double-clicking the jar file. + Expected: The most recent window size and location is retained. -_{ more test cases ... }_ +=== Deleting a supplier -=== Deleting a person +. Deleting a supplier while all suppliers are listed -. Deleting a person while all persons are listed - -.. Prerequisites: List all persons using the `list` command. Multiple persons in the list. +.. Prerequisites: List all suppliers using the `list` command. Multiple suppliers in the list. .. Test case: `delete 1` + Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. .. Test case: `delete 0` + - Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. + Expected: No supplier is deleted. Error details shown in the status message. Status bar remains the same. .. Other incorrect delete commands to try: `delete`, `delete x` (where x is larger than the list size) _{give more}_ + Expected: Similar to previous. -_{ more test cases ... }_ - -=== Saving data +=== Undo and Redo + +. Undo at initial state +.. Prerequisites: The application is newly opened i.e. no undoable commands has been done +.. Test case: `undo` + + Expected: An error is shown, indicating that undo cannot be done from initial state. +.. Test case: Add a valid supplier followed by `undo` + + Expected: The supplier is removed +.. Test case: `list-t` followed by `undo` + + Expected: An error is shown, indicating that undo cannot be done from initial state. + This is because `list-t` is not an undoable command + +. Redo from latest state +.. Prerequisites: One undoable command e.g. `add-s` has been successfully executed as the latest command +.. Test case: `redo` + + An error is shown, indicating that redo cannot be done from latest state. +.. Test case: `undo` followed by `redo` + + The changes done by the latest undoable command is removed, then reinstated. + +. Overwriting history +.. Prerequisites: None +.. Test case: Add a valid supplier, `undo`, add a different valid supplier, and finally `redo` + + An error is shown, indicating that redo cannot be done from latest state. + +=== Buying goods +. Prerequisites: +.. A supplier at displayed index 1 in the supplier list that sells a good named Rice. +.. There should either not be any Rice in the inventory or have an amount that +will be strictly less than 1 million after buying. +. Test case: `buy 1 g/Rice q/10` + +Expected: The quantity of Rice in the inventory should increase by 10. If Rice +was not previously present, a new entry would be created. + +=== Selling goods +. Prerequisites: +.. Have a good named Rice in the inventory with at least 10 quantity. +.. Rice should be at displayed index 1 in the inventory. +. Test case: `sell 1 q/3 p/3` + +Expected: The quantity of rice in the inventory should decrease by 3. + +=== Set threshold quantity for good + +.. Prerequisites: One buy command to add good into the inventory. Buy quantity set as 100. +.. Test case: `warn 1 q/10000` + + Expected: First good will be under alert with red colour background, as the quantity is lower than the threshold quantity. +.. Test case: `warn 1 q/99` + + Expected: No effect is shown, as the current quantity of good is greater than the threshold quantity. +.. Test case: `warn 1 q/99` followed by sell command to sell quantity of 10 + + Expected: First good will be under alert with red colour background, as the quantity is lower than the threshold quantity after selling. +.. Test case: `warn` + + Expected: An error is shown, indicating that the format of the command is wrong. +.. Other incorrect warn commands to try: `warn abc`, `warn x q/abc` (where x is larger than the list size) + + Expected: Similar to previous. -. Dealing with missing/corrupted data files +=== Find transaction + +.. Prerequisites: List transaction command. +.. Test case: `find-t buy` + + Expected: All buy transaction will be listed. +.. Test case: `find-t buy n/Alice` + + Expected: All buy transaction with Alice being the supplier will be listed. +.. Test case: `find-t buy n/Alice g/apple` + + Expected: All buy transaction with Alice being the supplier and the good bought being apple will be listed. +.. Test case: `find-t abc` + + Expected: An error is shown, indicating that the format of the command is wrong. +.. Other incorrect warn commands to try: `find-t`, `find-t x` (where x is not "buy" or "sell") + + Expected: Similar to previous. -.. _{explain how to simulate a missing/corrupted file and the expected behavior}_ +[appendix] +== Effort + +* *Difficulty Level*: 10 +* *Challenges*: +** This is an application with three different databases. In addition to having to + define operations for three different objects, many of the commands exhibit much interlinking between the components. + There is a need to take extra care to ensure that the interactions are clearly defined and avoid side effects. +** Many features are dependent on other features being developed compared to AB3, which makes it hard to concurrently arrange the interactions. + An API needed to be clearly defined before the start of the sprint in order to allow team members to start working immediately. +** There are many commands that needs to be tracked, which necessitates consideration whether it would affect the + implementation of other commands. +** There is significant amount of code duplication due to having three database classes. Refactoring is needed to make + the code easier to read. +* *Achievements*: +** Refactored some of the Model classes to allow custom extension by future developers and reduce code duplication. +** Implemented a search feature that navigates between two different databases. +** 79% code coverage as measured by Coveralls, an increase from the original 75%. -_{ more test cases ... }_ diff --git a/docs/Documentation.adoc b/docs/Documentation.adoc index ad90ac87bda..8057dc6f83e 100644 --- a/docs/Documentation.adoc +++ b/docs/Documentation.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Documentation += InventoryManager - Documentation :site-section: DeveloperGuide :toc: :toc-title: @@ -12,7 +12,7 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main/tree/master == Introduction @@ -71,11 +71,6 @@ If set, the name will be displayed near the top of the page. Setting this will add a "View on GitHub" link in the navigation bar. |_not set_ -|`site-seedu` -|Define this attribute if the project is an official SE-EDU project. -This will render the SE-EDU navigation bar at the top of the page, and add some SE-EDU-specific navigation items. -|_not set_ - |=== [[Docs-PerFileDocSettings]] @@ -98,9 +93,6 @@ Attributes left unset in `.adoc` files will use their *default value*, if any. This will cause the associated item in the navigation bar to be highlighted. One of: `UserGuide`, `DeveloperGuide`, ``LearningOutcomes``{asterisk}, `AboutUs`, `ContactUs` -_{asterisk} Official SE-EDU projects only_ -|_not set_ - |`no-site-header` |Set this attribute to remove the site navigation bar. |_not set_ @@ -119,5 +111,4 @@ These template files are written in a mixture of https://www.ruby-lang.org[Ruby] ==== Modifying the template files in link:{repoURL}/docs/templates[`docs/templates`] requires some knowledge and experience with Ruby and Asciidoctor's API. You should only modify them if you need greater control over the site's layout than what stylesheets can provide. -The SE-EDU team does not provide support for modified template files. ==== diff --git a/docs/LearningOutcomes.adoc b/docs/LearningOutcomes.adoc deleted file mode 100644 index 436c1777617..00000000000 --- a/docs/LearningOutcomes.adoc +++ /dev/null @@ -1,216 +0,0 @@ -= Learning Outcomes -:site-section: LearningOutcomes -:toc: macro -:toc-title: -:toclevels: 1 -:imagesDir: images -:stylesDir: stylesheets -ifdef::env-github[] -:note-caption: :information_source: -endif::[] - -After studying this code and completing the corresponding exercises, you should be able to, - -toc::[] - -== Utilize User Stories `[LO-UserStories]` - -=== References - -* https://se-edu.github.io/se-book/specifyingRequirements/userStories/[se-edu/se-book: Requirements: Specifying Requirements: User Stories] - -=== Exercise: Add more user stories - -* Assume you are planing to expand the functionality of the AddressBook (but keep it as a CLI application). -What other user stories do you think AddressBook should support? Add those user stories to the `DeveloperGuide.adoc`. - -== Utilize use cases `[LO-UseCases]` - -=== References - -* https://se-edu.github.io/se-book/specifyingRequirements/useCases/[se-edu/se-book: Requirements: Specifying Requirements: Use Cases] - -=== Exercise: Add a 'Rename tag' use case - -* Add a use case to the `DeveloperGuide.adoc` to cover the case of _renaming of an existing tag_. -e.g. rename the tag `friends` to `buddies` (i.e. all persons who had the `friends` tag will now have -a `buddies` tag instead) -Assume that AddressBook confirms the change with the user before carrying out the operation. - -== Use Non Functional Requirements `[LO-NFR]` - -=== References - -* https://se-edu.github.io/se-book/requirements/nonFunctionalRequirements/[se-edu/se-book: Requirements: Non-Functional Requirements] - -=== Exercise: Add more NFRs - -* Add some more NFRs to the `DeveloperGuide.adoc` - -== Use Polymorphism `[LO-Polymorphism]` - -Note how the `Command::execute()` method shows polymorphic behavior. - -=== References - -* https://se-edu.github.io/se-book/oop/polymorphism/[se-edu/se-book: Paradigms: OOP: Polymorphism] -* https://se-edu.github.io/se-book/cppToJava/inheritance/polymorphism/[se-edu/se-book: C++ to Java: OOP: Polymorphism] - -=== Exercise: Add a polymorphic `isMutating` method - -* Add a method `boolean isMutating()` to the `Command` class. This method will return `true` for -command types that mutate the data. e.g. `AddCommand` -* Currently, AddressBook data are saved to the file after every command. -Take advantage of the the new method you added to limit file saving to only for command types that mutate data. -i.e. `add` command should always save the data while `list` command should never save data to the file. - -[NOTE] -==== -There may be better ways to limit file saving to commands that mutate data. The above approach, while not -optimal, will give you chance to implement a polymorphic behavior. -==== - -== Use abstract classes/methods `[LO-Abstract]` - -=== References - -* https://se-edu.github.io/se-book/oop/inheritance/abstractClasses/[se-edu/se-book: Paradigms: OOP: Abstract Classes] -* https://se-edu.github.io/se-book/cppToJava/inheritance/abstractClassesAndMethods/[se-edu/se-book: C++ to Java: OOP: Abstract Classes] - -=== Exercise: Make `Command#execute()` method abstract - -* Make the `Command#execute()` method abstract (hint: refer to the comment given below the method) - -== Use interfaces `[LO-Interfaces]` - -Note how the `AddressBook` class implements the `ReadOnlyAddressBook` interface so that clients who don't need write access to the `AddressBook` can access the `AddressBook` through the `ReadOnlyAddressBook` interface instead. - -image::ReadOnlyAddressBookUsage.png[width=500] - -=== References - -* https://se-edu.github.io/se-book/oop/inheritance/interfaces/[se-edu/se-book: Paradigms: OOP: Abstract Interfaces] -* https://se-edu.github.io/se-book/cppToJava/inheritance/interfaces/[se-edu/se-book: C++ to Java: OOP: Abstract Interfaces] - -=== Exercise: Add a `Printable` interface - -* Add a `Printable` interface as follows. -+ -image::PrintableInterface.png[width=400] -* `Override` the `getPrintableString` in classes `Name`, `Phone`, `Email`, and `Address` so that each produces a printable string representation of the object. e.g. `Name: John Smith`, `Phone: 12349862` -* Add the following method in a suitable place of some other class. Note how the method depends on the Interface. -+ -[source,java] ----- -/** - * Returns a concatenated version of the printable strings of each object. - */ -String getPrintableString(Printable... printables) { ----- -+ -The above method can be used to get a printable string representing a bunch of person details. -For example, you should be able to call that method like this: -+ -[source,java] ----- -// p is a Person object -return getPrintableString(p.getPhone(), p.getEmail(), p.getAddress()); ----- - -== Follow Liskov Substitution Principle `[LO-LSP]` - -=== References - -* https://se-edu.github.io/se-book/principles/liskovSubstitutionPrinciple/[se-edu/se-book: Principles: Liskov Substitution Principle] - -=== Exercise: Add an exception to an overridden method - -* Add a `throws Exception` clause to the `AddCommand::execute` method. Notice how Java compiler will not allow it, -unless you add the same `throws` clause to the parent class method. This is because if a child class throws -an exception that is not specified by the Parent's contract, the child class is no longer substitutable in place of -the parent class. -* Also note that while in the above example the compiler enforces LSP, there are other situations where it is up to -the programmer to enforce it. For example, if the method in the parent class works for `null` input, the overridden -method in the child class should not reject `null` inputs. This will not be enforced by the compiler. - -== Use Java-FX for GUI programming `[LO-JavaFx]` - -=== References - -* https://se-edu.github.io/se-book/javaTools/javaFXBasic/[se-edu/se-book: Tools: Java: JavaFX: Basic] - -=== Exercise: Enhance GUI - -* Do some enhancements to the AddressBook GUI. e.g. add an application icon, change font size/style - -== Analyze Coupling and Cohesion of designs `[LO-CouplingCohesion]` - -* Notice how having a separate `ParserUtil` class to handle user input validation, space trimming etc. of model data (an application of the Single Responsibility Principle) improves the _cohesion_ of the model component (since it does not need to be concerned with handling user input) as well as the `ParserUtil` class. - -=== References - -* https://se-edu.github.io/se-book/designFundamentals/coupling/[se-edu/se-book: Design: Design Principles: Coupling] -* https://se-edu.github.io/se-book/designFundamentals/cohesion/[se-edu/se-book: Design: Design Principles: Cohesion] - -=== Exercise: Identify places to reduce coupling and increase cohesion - -* Where else in the design coupling can be reduced further, or cohesion can be increased further? - -[[apply-dependency-inversion-principle-lo-dip]] -== Apply Dependency Inversion Principle `[LO-DIP]` - -* Note how the `LogicManager` class doesn't depend on `StorageManager` directly, but rather the interface `Storage`. -This is an application of the Dependency Inversion Principle. -+ -image::LogicStorageDIP.png[width=300] -* Where else in the code do you notice the application of DIP? - -=== References - -* https://se-edu.github.io/se-book/principles/dependencyInversionPrinciple/[se-edu/se-book: Principles: Dependency Inversion Principle] - -== Use Dependency Injection `[LO-DI]` - -Notice how the `LogicManager` class does not depend on the `StorageManager` class, but depends on the `Storage` interface. -This allows us to use _Dependency Injection_ to test the `LogicManager` class without getting the `StorageManager` class involved. - -=== References - -* https://se-edu.github.io/se-book/testing/dependencyInjection/[se-edu/se-book: Quality Assurance: Testing: Dependency Injection] - -=== Exercise: Facilitate injecting a StorageStub - -* Notice how `LogicManagerTest` tests `LogicManager` by constructing a `StorageManager` object. -* Implement `StorageStub` such that calls to its `save*` methods do nothing (i.e. empty method body). -* Update `LogicManagerTest` to work with the `StorageStub` instead of the actual `StorageManager` object. -i.e. `LogicManagerTest` injects a `StorageStub` object when constructing a `LogicManager` before testing it. -+ -image::DependencyInjection.png[width=600] -* The example above uses <> as a means to achieve DI. -Note that there is another way to inject a `StorageStub` object, as shown below. -In this case we do not apply the DIP but we still achieve DI. -+ -image::DependencyInjectionWithoutDIP.png[width=250] - -== Apply Open-Closed Principle `[LO-OCP]` - -=== References - -* https://se-edu.github.io/se-book/principles/openClosedPrinciple/[se-edu/se-book: Principles: Open-Closed Principle] - -=== Exercise: Analyze OCP-compliance of the `LogicManager` class - -* Consider adding a new command to the Address Book. e.g. an `edit` command. Notice how little you need to change in the `LogicManager` class to extend its behavior so that it can execute the new command. -That is because `LogicManager` follows the OCP i.e. `LogicManager` is _open to be extended_ with more commands but _closed for modifications_. -* Is it possible to make the `AddressBookParser` class more OCP-compliant in terms of extending it to handle more -command types? -* In terms of how it saves data, is `LogicManager` more OCP-compliant -due to the application of DIP as given in <>? -How can you improve ``LogicManager``'s OCP-compliance further so that it can not only work with different types -of storages, but different number of storages (e.g. save to both a text file and a database). - -== Work in a 3KLoC code base `[LO-3KLoC]` - -=== Exercise: Enhance AddressBook - -* Enhance AddressBook in some way. e.g. add a new command diff --git a/docs/SettingUp.adoc b/docs/SettingUp.adoc index c0659782fab..9bc5efd1abe 100644 --- a/docs/SettingUp.adoc +++ b/docs/SettingUp.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Setting Up += InventoryManager - Setting Up :site-section: DeveloperGuide :toc: :toc-title: @@ -12,7 +12,7 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main/tree/master == Prerequisites @@ -55,16 +55,6 @@ This project follows https://github.com/oss-generic/process/blob/master/docs/Cod Optionally, you can follow the <> document to configure Intellij to check style-compliance as you write code. -=== Updating documentation to match your fork - -After forking the repo, the documentation will still have the SE-EDU branding and refer to the `se-edu/addressbook-level3` repo. - -If you plan to develop this fork as a separate product (i.e. instead of contributing to `se-edu/addressbook-level3`), you should do the following: - -. Configure the <> in link:{repoURL}/build.gradle[`build.gradle`], such as the `site-name`, to suit your own project. - -. Replace the URL in the attribute `repoURL` in link:{repoURL}/docs/DeveloperGuide.adoc[`DeveloperGuide.adoc`] and link:{repoURL}/docs/UserGuide.adoc[`UserGuide.adoc`] with the URL of your fork. - === Setting up CI Set up Travis to perform Continuous Integration (CI) for your fork. See <> to learn how to set it up. @@ -81,4 +71,4 @@ Having both Travis and AppVeyor ensures your App works on both Unix-based platfo === Getting started with coding -When you are ready to start coding, we recommend that you get some sense of the overall design by reading about <>. +When you are ready to start coding, we recommend that you get some sense of the overall design by reading about <>. diff --git a/docs/Testing.adoc b/docs/Testing.adoc index 5767b92912c..c110923ea5a 100644 --- a/docs/Testing.adoc +++ b/docs/Testing.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - Testing += InventoryManager - Testing :site-section: DeveloperGuide :toc: :toc-title: @@ -12,7 +12,7 @@ ifdef::env-github[] :note-caption: :information_source: :warning-caption: :warning: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3/tree/master +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main/tree/master == Running Tests diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc old mode 100644 new mode 100755 index 4e5d297a19f..005419249dc --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 3 - User Guide += InventoryManager - User Guide :site-section: UserGuide :toc: :toc-title: @@ -12,30 +12,31 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level3 +:repoURL: https://github.com/AY1920S2-CS2103-W14-2/main -By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` +By: `AY1920S2-CS2103-W14-2`      Since: `Feb 2020`      Licence: `MIT` == Introduction -AddressBook Level 3 (AB3) is for those who *prefer to use a desktop app for managing contacts*. More importantly, AB3 is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! +InventoryManager is for those who *prefer to use a desktop app for managing their inventory*. More importantly, InventoryManager is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, InventoryManager can get your inventory management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! == Quick Start . Ensure you have Java `11` or above installed in your Computer. -. Download the latest `addressbook.jar` link:{repoURL}/releases[here]. -. Copy the file to the folder you want to use as the home folder for your Address Book. -. Double-click the file to start the app. The GUI should appear in a few seconds. +. Download the latest `inventorymanager.jar` link:{repoURL}/releases[here]. +. Copy the file to the folder you want to use as the home folder for your InventoryManager. +. Double-click the file to start the app. The GUI should appear in a few seconds. For Mac OS users, permission may need to be granted to the file before usage. + +.GUI of Inventory Manager image::Ui.png[width="790"] + . Type the command in the command box and press kbd:[Enter] to execute it. + e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. . Some example commands you can try: -* *`list`* : lists all contacts -* **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : adds a contact named `John Doe` to the Address Book. -* **`delete`**`3` : deletes the 3rd contact shown in the current list +* *`list-s`* : lists all suppliers +* **`add`**`n/John Doe c/98765432 e/johnd@example.com a/John street, block 123, #01-01 gp/apple 4.50` : adds a supplier named `John Doe` selling apples at 4.50 each to the InventoryManager. +* **`delete-s 3`** : deletes the 3rd supplier shown in the current list * *`exit`* : exits the app . Refer to <> for details of each command. @@ -47,99 +48,378 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. *Command Format* * Words in `UPPER_CASE` are the parameters to be supplied by the user e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. -* Items in square brackets are optional e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. -* Items with `…`​ after them can be used multiple times including zero times e.g. `[t/TAG]...` can be used as `{nbsp}` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. -* Parameters can be in any order e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. +* Items in square brackets are optional e.g `n/NAME [gp/GOOD PRICE]` can be used as `n/John Doe gp/apple 4.50` or as `n/John Doe`. +* Items with `…`​ after them can be used multiple times including zero times e.g. `[gp/GOOD PRICE]...` can be used as `{nbsp}` (i.e. 0 times), `gp/apple 4.50`, `gp/orange 2.00 gp/pear 5.00` etc. +* Parameters can be in any order e.g. if the command specifies `n/NAME c/CONTACT_NUMBER`, `c/CONTACT_NUMBER n/NAME` is also acceptable. +* For parameters where only one value is expected, only the last specified value will be taken e.g. `c/12345 c/54321` will use only `c/54321`. +* All dates follow the format `yyyy-MM-dd` ==== === Viewing help : `help` +To view the command usage or the command format of this application. Format: `help` -=== Adding a person: `add` +An url link will be shown that linked to this page. -Adds a person to the address book + -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` +.Demo for `help` command +image::UG/help.png[width="790"] -[TIP] -A person can have any number of tags (including 0) +=== Listing all suppliers : `list-s` (By Liu Chao) -Examples: +Shows a list of all suppliers in the inventory manager. + +Format: `list-s` + +=== Clearing all supplier entries : `clear-s` (By Liu Chao) + +Clears all supplier entries from the address book. + +Format: `clear-s` -* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` -* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` +=== Adding a supplier: `add-s` (By Liu Chao) -=== Listing all persons : `list` +Adds a supplier to the inventory manager + +Format: `add-s n/NAME c/CONTACT_NUMBER e/EMAIL a/ADDRESS [gp/GOOD PRICE]...` + +[TIP] +* A supplier can have any number of good-price pairs (including 0) +* Must include name, phone number, email, address. +* Repeated supplier will cause exception. + +Examples: -Shows a list of all persons in the address book. + -Format: `list` +* `add-s n/NTUC Fairprice Macpherson Mall c/63521728 e/MacphersonMall@NTUC Fairprice.com a/401, #02-22 MacPherson Rd, Macpherson Mall, 368125 gp/banana 5 gp/tissue paper 0.55` -=== Editing a person : `edit` +=== Editing a supplier : `edit-s` (By Liu Chao) -Edits an existing person in the address book. + -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +Edits an existing supplier in the inventory manager. + +Format: `edit-s INDEX [n/NAME] [c/CONTACT_NUMBER] [e/EMAIL] [a/ADDRESS] [gp/GOOD PRICE]...` **** -* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index *must be a positive integer* 1, 2, 3, ... +* Edits the supplier at the specified `INDEX`. The index refers to the index number shown in the displayed supplier list. The index *must be a positive integer* 1, 2, 3, ... * At least one of the optional fields must be provided. * Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. -* You can remove all the person's tags by typing `t/` without specifying any tags after it. +* If the entered good-price pair is not in the existing supplier's list, the entered good price pair will be stored in the supplier's list as a new good price pair. + +[TIP] +You can add any number of good-price pairs to the existing suppliers at one time. **** Examples: -* `edit 1 p/91234567 e/johndoe@example.com` + -Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. -* `edit 2 n/Betsy Crower t/` + -Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +* `edit-s 1 c/91234567 e/ColdStorageAtOrchard@example.com` + +Edits the contact number and email address of the 1st supplier to be `91234567` and `ColdStorageAtOrchard@example.com` respectively. +* `edit-s 2 gp/apple 5 gp/banana 10` + +The existing second supplier only has `apple` priced at `1` dollar. Hence, this command will edit the price of `apple` to `5` dollar and add the good price pair of `banana` into the supplier's good list. -=== Locating persons by name: `find` +=== Locating suppliers by name: `find-s` (By Liu Chao) -Finds persons whose names contain any of the given keywords. + -Format: `find KEYWORD [MORE_KEYWORDS]` +Finds suppliers whose names contain any of the given keywords. + +Format: `find-s KEYWORD [MORE_KEYWORDS]` **** -* The search is case insensitive. e.g `hans` will match `Hans` -* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans` +* The search is case insensitive. e.g `ColdStorage` will match `coldstorage` +* The order of the keywords does not matter. e.g. `NTUC Fairprice` will match `Fairprice NTUC` * Only the name is searched. -* Only full words will be matched e.g. `Han` will not match `Hans` -* Persons matching at least one keyword will be returned (i.e. `OR` search). e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +* Only full words will be matched e.g. `ColdStorage` will not match `ColdStorages` +* Suppliers matching at least one keyword will be returned (i.e. `OR` search). e.g. `Fairprice NTUC` will return `Macpherson NTUC`, `Fairprice Value Store` **** +[TIP] +* You can find multiple suppliers by input multiple keywords. +* You could use keywords instead of full names. + Examples: -* `find John` + -Returns `john` and `John Doe` -* `find Betsy Tim John` + -Returns any person having names `Betsy`, `Tim`, or `John` +* `find-s NTUC ColdStorage` + +Returns `NTUC Fairprice` and `ColdStorage Orchard` + +=== Source supplier(s) for good(s): `source` (By Liu Chao) + +Source suppliers who sell goods with good names containing any of the given keywords. + +Format: `Source GOOD_NAME [MORE_GOOD_NAME]...` + +**** +* The search is case insensitive. e.g `apple` will match `APPLE` +* The keywords are referring to goods' names +* At least one good name must be included +* The order of the keywords does not matter. e.g. `Fuji Apple` will match `Apple Fuji` +* Only the good's name is searched. +* Only full words will be matched e.g. `apple` will not match `appl` +* Suppliers who sell goods with goods' names matching at least one keyword will be returned (i.e. `OR` search). e.g. `mango pie` will return suppliers selling `mango yogurt` and suppliers selling `apple pie` +**** + +[TIP] +* You can find multiple suppliers by input multiple goods' names. +* You could use keywords instead of full goods' names. +* You could source for suppliers selling different goods by using different keywords at one time. + +Examples: + +* `source banana apple` + +Returns `Cavendish banana` and `Fuji apple` // tag::delete[] -=== Deleting a person : `delete` +=== Deleting a supplier : `delete-s` (By Liu Chao) -Deletes the specified person from the address book. + -Format: `delete INDEX` +Deletes the specified supplier from the address book. + +Format: `delete-s INDEX` **** -* Deletes the person at the specified `INDEX`. -* The index refers to the index number shown in the displayed person list. +* The command will delete the supplier at the specified `INDEX`. +* The index refers to the index number shown in the displayed supplier list. * The index *must be a positive integer* 1, 2, 3, ... **** Examples: -* `list` + -`delete 2` + -Deletes the 2nd person in the address book. -* `find Betsy` + -`delete 1` + -Deletes the 1st person in the results of the `find` command. +* `list-s` + +`delete-s 2` + +Deletes the 2nd supplier in the inventory manager. +* `find-s NTUC` + +`delete-s 1` + +Deletes the 1st supplier with name containing `NTUC` in the inventory manager aftr filtering with the keyword `NTUC`. + +=== Deleting an entry or entries of good-price pair(s) in the supplier's list: `delete-gp` (By Liu Chao) + +Deletes the specified good price pair(s) from supplier's list of good price pairs. + +Format: `delete-gp INDEX (must be a positive integer) g/GOOD_NAME [g/MORE_GOOD_NAME]...` + +**** +* The command will delete the good price pair(s) of supplier's list of good price pairs at the specified `INDEX`. +* The index refers to the index number shown in the displayed supplier list. +* The `index` *must be a positive integer* 1, 2, 3, ... +* You must enter the full names of the goods which are case sensitive +* You could delete one or more price good pairs from the supplier’s list by input one or more good’s names +* You must include at least one good name. +**** + +[TIP] +The command will display all good price pairs that could not be found or are successfully deleted at the end of command. + +Examples: + +* `delete-gp 1 g/apple g/orange (to delete two different goods)` + +Deletes the good price pairs of apple and orange in the 1st supplier's list of good price pairs. + + +//tag::buycommand[] +=== Buying goods from supplier: `buy` (By Pang Jia Da) + +Buys a batch of goods from a supplier in the contact list who stocks that product. The inventory manager cannot buy products in the following cases: + +. The supplier has not been entered in the supplier list +. The supplier has not been registered to the good, as indicated by the "offers" section of each supplier + +Format: `buy SUPPLIER_DISPLAY_INDEX g/GOOD_NAME q/QUANTITY` + +Example: + +* `buy 1 g/Apple q/4` + +Buys 4 apples from supplier at displayed index 1 in the supplier list. + +[TIP] +If the good does not exist in the inventory, a new entry for that good will be created. + +[CAUTION] +The maximum quantity of any good in the inventory is 999,999. Users are not allowed to buy quantities of goods that would cause that limit to be exceeded. +//end::buycommand[] + +//tag::sellcommand[] +=== Selling goods: `sell` (By Pang Jia Da) + +Sells a particular goods from the inventory. + +The inventory manager cannot sell products in the following cases: + +. The good being sold does not exist in the inventory +. The quantity being sold is larger than the amount existing in the inventory + +Format: `sell GOOD_DISPLAYED_INDEX q/QUANTITY p/PRICE` + +Example: + +* `sell 1 q/4 p/3.5` + +Sells 4 units of good at displayed index 1 in the inventory at $3.50 each. + +[TIP] +The selling price can be specified to the nearest cent, or 2 decimal places maximum. + +[TIP] +When the quantity in inventory reaches 0, the name of the good is not deleted for future reference or restocking. +This entry can be deleted using the `delete-g` command. +//end::sellcommand[] + + +//tag::deletegood[] + +=== Delete good entry in inventory: `delete-g` (By Pang Jia Da) +Deletes an entry for a good in the inventory. +The good to be deleted is at the displayed index shown in the middle inventory panel. +All of the good's quantity will be removed in the process. + +Format: `delete-g INDEX` + +Example: + +* `delete-g 3` +The good entry at displayed index 3 will be removed, provided there is an entry at index 3. + +[TIP] +No transaction history will be recorded for `delete-g`. This command is +meant to recove goods with no quantity in the inventory when reference to them +is no longer required. If there are quantities being transacted, `buy` and `sell` +should be used instead. + +//end::deletegood[] + + +// tag::setthreshold[] +=== Setting minimum quantity for goods: `warn` (By Fang Shao Hua) + +Sets the minimum quantity threshold for a certain good. + +When the quantity of the good is below the threshold, the quantity of the good will be mark with red color background +and rank higher up in the inventory list. + +All goods under their threshold quantity will be shown before all goods above their threshold quantity. + +Format: `warn INDEX q/MIN_QUANTITY` + +Example: + +* `warn 5 q/100` + +This sets the minimum quantity threshold for good at index 5 with an quantity of 100. + +.Demo for `warn` command +image::UG/warn.png[width="790"] + +[NOTE] +When a new good is added into the inventory, its minimum quantity threshold is set at 0. + +// end::setthreshold[] + +// tag::findtransaction[] + +=== Locating transactions by search criteria: `find-t` (By Fang Shao Hua) + +Display list of transactions that fulfills the given search criteria. + +3 types of search criteria: + +. transaction type +. supplier's name +. good's name + +Format: `find-t [TRANSACTION TYPE] [n/NAME] [g/GOOD NAME]`; + +.GUI before demo +image::UG/original.png[width="790"] + +Example: + +* Search by transaction type: + +`find-t buy` + +display all `buy` transactions. + +NOTE: Currently, there are only two types of transaction: `buy` and `sell`. Type of transaction is case sensitive. + +.Demo for `find-t` command that uses only [TRANSACTION TYPE] criteria +image::UG/find-t buy.png[width="790"] + +* Search by `Name` of `Supplier`: + +`find-t n/alex bernice` + +display all transactions that related to `Alex` or `Bernice`. + +**** +* The search is case insensitive. e.g `bernice` will match `Bernice` +* The order of the keywords does not matter. e.g. `Bernice Yu` will match `Yu Bernice` +* Only the name is searched. +* Only full words will be matched e.g. `bernice` will not match `bernices` +* Supplier matching at least one keyword will be returned (i.e. `OR` search). e.g. `Alex Bernice` will return `Alex Yeoh`, `Bernice Yu` +**** + +.Demo for `find-t` command that uses only [NAME] criteria +image::UG/find-t name.png[width="790"] + +* Search by `Good Name` of `Good`: + +`find-t g/apple noodle` + +display all transactions that related to `Apple` or `Noodle`. + +.Demo for `find-t` command that uses only [GOOD NAME] criteria +image::UG/find-t good name.png[width="790"] + +`Combination of criteria` + +Criteria can be combined to give a more constraint search. + +Example: + +* Search by transaction type and `GoodName` of `Good: + +`find-t buy n/apple noodle` + +display all `buy` transactions that is related to `Apple` or `Noodle`. + +.Demo for `find-t` command that uses [TRANSACTION TYPE] and [GOOD NAME] criteria. +image::UG/combination.png[width="790"] + +NOTE: The transaction related to `Noodle` is no longer shown as compare to search only by +`Good Name`, as that transaction is a sell transaction and does not fulfill the transaction type. + +// end::findtransaction[] + +// tag::listtransaction[] + +=== Listing all transactions : `list-t` (By Fang Shao Hua) +Shows the list of transaction history in the inventory manager. + + +Format: `list-t` + +.Demo for `list-t` command +image::UG/list-t.png[width="790"] + +// end::listtransaction[] + +//tag::undoredo[] +=== Undoing a recently executed command: `undo` (By Nicholas Cristian Fernando) + +Removes changes from a recently executed command. Commands that only affect display e.g. find and list, and undo commands, will be ignored and the next command in line will be undone. + +Format: `undo` + +Examples (assuming all other commands are valid): + +* `clear-s` + + `list-t` + + `undo` (ignores `list-t` and reverses `clear-s`) + +* `clear-s` + + `delete-g 1` + + `undo` (reverses `delete-g 1`) + + `undo` (reverses `clear-s`) + +=== Redoing a previously undone command: `redo` + +Redoes changes undone by the most recent undo command. + +Format: `redo` + +Examples (assuming all other commands are valid): + +* `clear-s` + + `list-t` + + `undo` (ignores `list-t` and reverses `clear-s`) + + `redo` (repeats `clear-s`) + +* `clear-s` + + `delete-g 1` + + `undo` (reverses `delete-g 1`) + + `undo` (reverses `clear-s`) + + `redo` (repeats `clear-s`) + + `redo` (repeats `delete-g 1`) + -// end::delete[] -=== Clearing all entries : `clear` +* `clear-s` + + `undo` (reverses `clear-s`) + + `delete-g 1` + + `redo` + + The `redo` fails as `delete-g 1` will remove the undone states. -Clears all entries from the address book. + -Format: `clear` +//end::undoredo[] === Exiting the program : `exit` @@ -148,30 +428,56 @@ Format: `exit` === Saving the data -Address book data are saved in the hard disk automatically after any command that changes the data. + +Inventory manager data are saved in the hard disk automatically after any command that changes the data. + There is no need to save manually. // tag::dataencryption[] === Encrypting data files `[coming in v2.0]` -_{explain how the user can enable/disable data encryption}_ +For security concerns, all data will be encrypted by default. // end::dataencryption[] == FAQ *Q*: How do I transfer my data to another Computer? + -*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Address Book folder. +*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous InventoryManager folder. == Command Summary +(By Liu Chao) + +* *Adding a supplier* `add-s n/NAME c/PHONE e/EMAIL a/ADDRESS [gp/GOOD PRICE]…` + +e.g. `add-s n/NTUC Fairprice Macpherson Mall c/63521728 e/MacphersonMall@NTUC Fairprice.com a/401, #02-22 MacPherson Rd, Macpherson Mall, 368125 gp/banana 5 gp/tissue paper 0.55` +* *Listing all suppliers* : `list-s` +* *Clearing all supplier entries* : `clear-s` +* *Deleting a supplier* : `delete-s INDEX (must be a positive integer)` + +e.g. `delete-s 1` +* *Deleting an entry or entries of good-price pair(s) in the supplier’s list* : `delete-gp INDEX (must be a positive integer) g/GOOD_NAME [g/MORE_GOOD_NAME]...` + +e.g. `delete-gp 1 g/apple g/orange (to delete two different goods)` +* *Editing a supplier* : `edit-s INDEX (must be a positive integer) [n/NAME] [c/PHONE] [e/EMAIL] [a/ADDRESS] [gp/GOOD_PRICE_PAIR]…` + +e.g. `edit-s 1 c/63865586 gp/Watermelon 10` +* *Locating suppliers by name* : `find-s KEYWORD [MORE_KEYWORD]…` + +e.g. `find-s NTUC ColdStorage` +* *Source supplier(s) for good(s)*: `source GOOD_NAME [MORE_GOOD_NAME]...` + +e.g. `source banana apple` + +(By Pang Jia Da) + +* *Buy goods*: `buy SUPPLIER_DISPLAYED_INDEX g/GOOD_NAME q/QUANTITY` + +e.g. `buy 1 g/Apple q/4` +* *Sell goods*: `sell GOOD_DISPLAYED_INDEX q/QUANTITY p/PRICE` + +e.g. `sell 1 q/4 p/3` + +(By Fang Shao Hua) + +* *Set minimum threshold quantity for goods*: `warn INDEX q/MIN_QUANTITY` +* *List transaction history*: `list-t` +* *Find transaction*: `find-t [TRANSACTION TYPE][n/NAME][g/GOOD NAME]` + +//tag::undoredosummary[] +(By Nicholas Cristian Fernando) + +* *Undo*: `undo` +* *Redo*: `redo` +//end::undoredosummary[] -* *Add* `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` + -e.g. `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` -* *Clear* : `clear` -* *Delete* : `delete INDEX` + -e.g. `delete 3` -* *Edit* : `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]...` + -e.g. `edit 2 n/James Lee e/jameslee@example.com` -* *Find* : `find KEYWORD [MORE_KEYWORDS]` + -e.g. `find James Jake` -* *List* : `list` * *Help* : `help` diff --git a/docs/UsingAppVeyor.adoc b/docs/UsingAppVeyor.adoc index 12a7a89ac68..4ebb07357a7 100644 --- a/docs/UsingAppVeyor.adoc +++ b/docs/UsingAppVeyor.adoc @@ -9,7 +9,6 @@ endif::[] [NOTE] ==== This document was originally written for _AddressBook Level 4_ and hence its screenshots refer to `addressbook-level4`. -For use with _AddressBook Level 3_, wherever `addressbook-level4` is used in the screenshots, you should use *`addressbook-level3`*. ==== https://www.appveyor.com/[AppVeyor] is a _Continuous Integration_ platform for GitHub projects. It runs its builds on Windows virtual machines. @@ -88,7 +87,7 @@ Convert it to the asciidoc format as follows: The asciidoc code should look similar to: + ---- -https://ci.appveyor.com/project/damithc/addressbook-level3[image:https://ci.appveyor.com/api/projects/status/3boko2x2vr5cc3w2?svg=true[Build status]] +https://ci.appveyor.com/project/CS2103-W14-2/main[image:https://ci.appveyor.com/api/projects/status/rlr0xji2vhij1016?svg=true[Build status]] ---- + Copy and paste the asciidoc code to your `README.adoc` file. diff --git a/docs/UsingCheckstyle.adoc b/docs/UsingCheckstyle.adoc index a12ab09cc9c..021452fee18 100644 --- a/docs/UsingCheckstyle.adoc +++ b/docs/UsingCheckstyle.adoc @@ -11,7 +11,6 @@ endif::[] [NOTE] ==== This document was originally written for _AddressBook Level 4_ and hence its screenshots refer to `addressbook-level4`. -For use with _AddressBook Level 3_, wherever `addressbook-level4` is used in the screenshots, you should use *`addressbook-level3`*. ==== == Configuring Checkstyle-IDEA @@ -22,7 +21,7 @@ Restart the IDE to complete the installation. . Click `File` > `Settings...` > `Other Settings` > `Checkstyle` . Set `Scan Scope` to `Only Java sources (including tests)`, so that the plugin will run checkstyle for our test source codes as well . Ensure that the `Checkstyle version` is set to `8.1`. This is the same version that we are using inside Gradle, so that you won't get any errors due to version incompatibility - * If `Checkstyle version` is not set to `8.1`, set it to version `8.1` and click `Apply` +* If `Checkstyle version` is not set to `8.1`, set it to version `8.1` and click `Apply` + image::checkstyle-idea-scan-scope.png[width="500"] . Click the plus sign under `Configuration File` diff --git a/docs/UsingCoveralls.adoc b/docs/UsingCoveralls.adoc index 5191e47316c..015cc19c02c 100644 --- a/docs/UsingCoveralls.adoc +++ b/docs/UsingCoveralls.adoc @@ -9,7 +9,6 @@ endif::[] [NOTE] ==== This document was originally written for _AddressBook Level 4_ and hence its screenshots refer to `addressbook-level4`. -For use with _AddressBook Level 3_, wherever `addressbook-level4` is used in the screenshots, you should use *`addressbook-level3`*. ==== https://coveralls.io/[Coveralls] is a web service that tracks code coverage over time for GitHub projects. diff --git a/docs/UsingGradle.adoc b/docs/UsingGradle.adoc index cca9c6d1d12..1a2301d1cd8 100644 --- a/docs/UsingGradle.adoc +++ b/docs/UsingGradle.adoc @@ -13,7 +13,6 @@ https://gradle.org/[Gradle] is a build automation tool. It can automate build-re * Running tests * Managing library dependencies * Analyzing code for style compliance - The gradle configuration for this project is defined in the _build script_ link:../build.gradle[`build.gradle`]. [NOTE] diff --git a/docs/UsingNetlify.adoc b/docs/UsingNetlify.adoc index 2e108c936a3..9061407aaea 100644 --- a/docs/UsingNetlify.adoc +++ b/docs/UsingNetlify.adoc @@ -9,7 +9,6 @@ endif::[] [NOTE] ==== This document was originally written for _AddressBook Level 4_ and hence its screenshots refer to `addressbook-level4`. -For use with _AddressBook Level 3_, wherever `addressbook-level4` is used in the screenshots, you should use *`addressbook-level3`*. ==== https://www.netlify.com/[Netlify] is an automated hosting platform for deploying static websites. With the aid of build tools such as Gradle, Netlify provides a smoother experience for previewing documentation. This can be done by using Netlify's https://www.netlify.com/blog/2016/07/20/introducing-deploy-previews-in-netlify/[Deploy Previews] feature, which shows a preview of the updated documentation whenever a pull request is made. diff --git a/docs/UsingPlantUML.adoc b/docs/UsingPlantUML.adoc new file mode 100644 index 00000000000..4aead093b76 --- /dev/null +++ b/docs/UsingPlantUML.adoc @@ -0,0 +1,204 @@ += Using PlantUML +:site-section: DeveloperGuide +:imagesDir: images/plantuml +:stylesDir: stylesheets +:experimental: +ifdef::env-github[] +:tip-caption: :bulb: +:note-caption: :information_source: +endif::[] + +== Introduction to PlantUML + +PlantUML is a tool used in this project to create UML diagrams. +For more information about the basics of PlantUML, head over to http://plantuml.com/[its official website]. + +== Set up PlantUML + +=== Installing Graphviz + +Graphviz is a dependency that PlantUML requires to generate more advanced diagrams. +Head over to the https://www.graphviz.org/download/[downloads page] on the official Graphviz website and follow instructions to install Graphviz. + +=== Installing the `PlantUML integration` plugin for IntelliJ IDEA + +Go to `Settings` > `Plugins` > `Marketplace` and install the plugin `PlantUML integration`. + +Then go to `Settings` > `Other Settings` > `PlantUML` or search for PlantUML. +Configure the path to the `dot` executable. +This executable can be found in the `/bin` directory where you installed GraphViz. + +.Settings - Other Settings - PlantUML: input the path to your dot executable +image::ConfiguringGraphviz.png[] + +== Create/Edit PlantUML diagrams + +After installing the `PlantUML integration` plugin, simply create or open any `.puml` file to start editing it. + +.Editing `DeleteSequenceDiagram.puml` +image::EditingDeleteSequenceDiagram.png[] +Any changes you make in editor pane on the left will be reflected in the preview pane on the right. +However, do take note that these changes _will not_ be reflected in the developers guide until you export the diagram. +//TODO: Discussion about why we're not using asciidoctor-diagram + +== Export PlantUML diagrams + +The `PlantUML integration` plugin allows you to export individual diagrams to a location of your choosing. +Click the `Save Current Diagram Only` button and choose the location to export the image file. + +NOTE: You will have to `git add` any new diagrams generated! + +== Common tasks + +=== Applying consistent formatting to PlantUML diagrams + +It is highly recommended to consistently color your UML diagrams as an visual aid. +You can achieve this by creating a dictionary of colors and import it like CSS. + +For example, you can create a `Style.puml` with the contents: + +.Style.puml +[source] +---- +... +!define LOGIC_COLOR #3333C4 +!define LOGIC_COLOR_T1 #7777DB +!define LOGIC_COLOR_T2 #5252CE +!define LOGIC_COLOR_T3 #1616B0 +!define LOGIC_COLOR_T4 #101086 +... +---- + +Then you can use it in another PlantUML file like this: + +.UndoSequenceDiagram.puml +[source] +---- +!include Style.puml +box Logic LOGIC_COLOR_T2 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":UndoCommand" as UndoCommand LOGIC_COLOR +end box +---- + +You can fine-tune the formatting of PlantUML diagrams with the `skinparam` command. +For example, `skinparam backgroundColor transparent` turns the background of the diagram transparent. + +For a comprehensive list of ``skinparam``s head over to the https://plantuml-documentation.readthedocs.io/en/latest/[unofficial PlantUML skinparam documentation]. + +*** + +=== Repositioning elements in PlantUML diagrams + +While PlantUML's automatic layout engine usually produces satisfactory results, at times the result can be less than ideal, especially on larger diagrams. +Here is an example where the default layout generated by PlantUML has a lot of overlapping lines that are hard to decipher: + +.The UI class diagram without additional formatting +image::RawUiDiagram.png[] + +NOTE: In most cases, you should consider decomposing the diagram into smaller ones or focusing on a more specific portion of the diagram. + +Here are some of the techniques we used in this project to obtain a more palatable diagram. + +==== Link lengths +By default, a short link (`\->`) points to right and a long link (`-\->`) +points downwards. you can extend any link to make it longer (```--\->```). + +.Length of arrows and its effects +image::ArrowLength.png[] + +==== Link directions +Clever usage of arrow directions will resolve most layout issues. +For example, the table below shows how the way in which you specify arrows can results in drastically different layouts for the same diagram. + +.Link directions +[cols="40a,60a"] +|=== +|Source |Result + +|[source, puml] +---- +A --> Z +B --> Z +C --> Z +D --> Z +A --> 1 +B --> 2 +C --> 3 +D --> 4 +---- +|image::AllDown.png[] + +|[source, puml] +---- +'default is down +A --> Z +'specify down +B -down-> Z +'shorthand for down +C -d-> Z +'arrow lengths take priority +D -down> Z +A -up-> 1 +B -up-> 2 +C -up-> 3 +D -up-> 4 +---- +|image::UpAndDown.png[] + +|[source, puml] +---- +A -up-> Z +B -up-> Z +C -up-> Z +D -up-> Z +A --> 1 +B --> 2 +C --> 3 +D --> 4 +'Force A B C D +A -right[hidden]- B +B -right[hidden]- C +C -right[hidden]- D +---- +|image::HiddenArrows.png[] +|=== + +==== Reordering definitions +As a general rule of thumb, the layout engine will attempt to order objects in the order in which they are defined. +If there is no formal definition, the objects is taken to be declared upon its first usage. + +.Definition ordering and outcomes +[cols="70a,30a"] +|=== +|Source |Result + +|[source, puml] +---- +A --> B +C --> D +---- +|image::ABeforeC.png[] + +|[source, puml] +---- +'Class C is defined before A +Class C +A --> B +C --> D +---- +|image::CBeforeA.png[] + +|[source, puml] +---- +package "Rule Of Thumb"{ + Class C + A --> B + C --> D +} +---- +|image::PackagesAndConsistency.png[] +|=== + +TIP: Explicitly define all symbols to avoid any potential layout mishaps. diff --git a/docs/UsingPlantUml.adoc b/docs/UsingPlantUml.adoc index cfe2533ea84..4aead093b76 100644 --- a/docs/UsingPlantUml.adoc +++ b/docs/UsingPlantUml.adoc @@ -75,7 +75,6 @@ Then you can use it in another PlantUML file like this: [source] ---- !include Style.puml - box Logic LOGIC_COLOR_T2 participant ":LogicManager" as LogicManager LOGIC_COLOR participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR @@ -124,7 +123,6 @@ A --> Z B --> Z C --> Z D --> Z - A --> 1 B --> 2 C --> 3 @@ -142,12 +140,10 @@ B -down-> Z C -d-> Z 'arrow lengths take priority D -down> Z - A -up-> 1 B -up-> 2 C -up-> 3 D -up-> 4 - ---- |image::UpAndDown.png[] @@ -157,12 +153,10 @@ A -up-> Z B -up-> Z C -up-> Z D -up-> Z - A --> 1 B --> 2 C --> 3 D --> 4 - 'Force A B C D A -right[hidden]- B B -right[hidden]- C @@ -191,7 +185,6 @@ C --> D ---- 'Class C is defined before A Class C - A --> B C --> D ---- diff --git a/docs/UsingTravis.adoc b/docs/UsingTravis.adoc index 887c0b09068..56be8aad2a2 100644 --- a/docs/UsingTravis.adoc +++ b/docs/UsingTravis.adoc @@ -9,7 +9,6 @@ endif::[] [NOTE] ==== This document was originally written for _AddressBook Level 4_ and hence its screenshots refer to `addressbook-level4`. -For use with _AddressBook Level 3_, wherever `addressbook-level4` is used in the screenshots, you should use *`addressbook-level3`*. ==== https://travis-ci.org/[Travis CI] is a _Continuous Integration_ platform for GitHub projects. @@ -21,7 +20,6 @@ The current Travis CI set up performs the following things whenever someone push * Runs the `./gradlew clean test coverage coveralls -i` command (see <> for more details on what this command means). * Renders documentation from asciidoc to html and automatically publishes them using GitHub Pages. * Runs additional link:#repository-wide-checks[repository-wide checks]. - If you would like to customise your travis build further, you can learn more about Travis from https://docs.travis-ci.com/[Travis CI Documentation]. == Setting up Travis CI diff --git a/docs/diagrams/ActivityDiagramEditSupplier.jpg b/docs/diagrams/ActivityDiagramEditSupplier.jpg new file mode 100644 index 00000000000..a099a681cee Binary files /dev/null and b/docs/diagrams/ActivityDiagramEditSupplier.jpg differ diff --git a/docs/diagrams/ArchitectureDiagram.png b/docs/diagrams/ArchitectureDiagram.png new file mode 100644 index 00000000000..c16c398e916 Binary files /dev/null and b/docs/diagrams/ArchitectureDiagram.png differ diff --git a/docs/diagrams/ArchitectureDiagram.puml b/docs/diagrams/ArchitectureDiagram.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/ArchitectureSequenceDiagram.png b/docs/diagrams/ArchitectureSequenceDiagram.png new file mode 100644 index 00000000000..f81e35e3a17 Binary files /dev/null and b/docs/diagrams/ArchitectureSequenceDiagram.png differ diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml old mode 100644 new mode 100755 index d1e2ae93675..390b749ed6e --- a/docs/diagrams/ArchitectureSequenceDiagram.puml +++ b/docs/diagrams/ArchitectureSequenceDiagram.puml @@ -7,13 +7,13 @@ Participant ":Logic" as logic LOGIC_COLOR Participant ":Model" as model MODEL_COLOR Participant ":Storage" as storage STORAGE_COLOR -user -[USER_COLOR]> ui : "delete 1" +user -[USER_COLOR]> ui : "delete-s 1" activate ui UI_COLOR -ui -[UI_COLOR]> logic : execute("delete 1") +ui -[UI_COLOR]> logic : execute("delete-s 1") activate logic LOGIC_COLOR -logic -[LOGIC_COLOR]> model : deletePerson(p) +logic -[LOGIC_COLOR]> model : deleteSupplier(p) activate model MODEL_COLOR model -[MODEL_COLOR]-> logic @@ -34,4 +34,4 @@ deactivate logic ui--[UI_COLOR]> user deactivate ui -@enduml +@endumlreso diff --git a/docs/diagrams/BetterModelClassDiagram.puml b/docs/diagrams/BetterModelClassDiagram.puml deleted file mode 100644 index 7790472da52..00000000000 --- a/docs/diagrams/BetterModelClassDiagram.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam arrowThickness 1.1 -skinparam arrowColor MODEL_COLOR -skinparam classBackgroundColor MODEL_COLOR - -AddressBook *-right-> "1" UniquePersonList -AddressBook *-right-> "1" UniqueTagList -UniqueTagList -[hidden]down- UniquePersonList -UniqueTagList -[hidden]down- UniquePersonList - -UniqueTagList *-right-> "*" Tag -UniquePersonList o-right-> Person - -Person o-up-> "*" Tag - -Person *--> Name -Person *--> Phone -Person *--> Email -Person *--> Address -@enduml diff --git a/docs/diagrams/BuySequenceDiagram.png b/docs/diagrams/BuySequenceDiagram.png new file mode 100644 index 00000000000..a127a63a139 Binary files /dev/null and b/docs/diagrams/BuySequenceDiagram.png differ diff --git a/docs/diagrams/BuySequenceDiagram.puml b/docs/diagrams/BuySequenceDiagram.puml new file mode 100644 index 00000000000..61c70aabe0e --- /dev/null +++ b/docs/diagrams/BuySequenceDiagram.puml @@ -0,0 +1,78 @@ +@startuml +!include style.puml + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":InventoryManagerParser" as InventoryManagerParser LOGIC_COLOR +participant ":BuyCommandParser" as BuyCommandParser LOGIC_COLOR +participant "b:BuyCommand" as BuyCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +end box + +[-> LogicManager : execute("buy 1 g/Apple q/50") +activate LogicManager + +LogicManager -> InventoryManagerParser : parseCommand("buy 1 g/Apple q/50") +activate InventoryManagerParser + +create BuyCommandParser +InventoryManagerParser -> BuyCommandParser +activate BuyCommandParser + +BuyCommandParser --> InventoryManagerParser +deactivate BuyCommandParser + +InventoryManagerParser -> BuyCommandParser : parse("1 g/Apple q/50") +activate BuyCommandParser + +create BuyCommand +BuyCommandParser -> BuyCommand +activate BuyCommand + +BuyCommand --> BuyCommandParser : b +deactivate BuyCommand + +BuyCommandParser --> InventoryManagerParser : b +deactivate BuyCommandParser +'Hidden arrow to position the destroy marker below the end of the activation bar. +BuyCommandParser -[hidden]-> InventoryManagerParser +destroy BuyCommandParser + +InventoryManagerParser --> LogicManager : b +deactivate InventoryManagerParser + +LogicManager -> BuyCommand : execute() +activate BuyCommand + +BuyCommand -> Model : getFilteredSupplierList() +activate Model +Model --> BuyCommand + +BuyCommand -> Model : addGood(boughtGood) +Model --> BuyCommand + +BuyCommand -> Model : addTransaction(buyTransaction) +Model --> BuyCommand + +BuyCommand -> Model : commit() +Model --> BuyCommand + +deactivate Model + +create CommandResult +BuyCommand -> CommandResult +activate CommandResult + +CommandResult --> BuyCommand +deactivate CommandResult + +BuyCommand --> LogicManager : result +deactivate BuyCommand + +[<--LogicManager +deactivate LogicManager +@enduml diff --git a/docs/diagrams/CommitActivityDiagram.png b/docs/diagrams/CommitActivityDiagram.png new file mode 100644 index 00000000000..0fcf1166346 Binary files /dev/null and b/docs/diagrams/CommitActivityDiagram.png differ diff --git a/docs/diagrams/CommitActivityDiagram.puml b/docs/diagrams/CommitActivityDiagram.puml old mode 100644 new mode 100755 index 7f8fe407f89..5447d62b6b3 --- a/docs/diagrams/CommitActivityDiagram.puml +++ b/docs/diagrams/CommitActivityDiagram.puml @@ -5,10 +5,14 @@ start 'Since the beta syntax does not support placing the condition outside the 'diamond we place it as the true branch instead. -if () then ([command commits AddressBook]) - :Purge redunant states; - :Save AddressBook to - addressBookStateList; +if () then ([command execution will be valid]) + :Execute command; + if () then ([command is undoable]) + :Remove undone states; + :Save currentState to + history; + else ([else]) + endif else ([else]) endif stop diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml deleted file mode 100644 index 1dc2311b245..00000000000 --- a/docs/diagrams/DeleteSequenceDiagram.puml +++ /dev/null @@ -1,69 +0,0 @@ -@startuml -!include style.puml - -box Logic LOGIC_COLOR_T1 -participant ":LogicManager" as LogicManager LOGIC_COLOR -participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR -participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR -participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR -participant ":CommandResult" as CommandResult LOGIC_COLOR -end box - -box Model MODEL_COLOR_T1 -participant ":Model" as Model MODEL_COLOR -end box - -[-> LogicManager : execute("delete 1") -activate LogicManager - -LogicManager -> AddressBookParser : parseCommand("delete 1") -activate AddressBookParser - -create DeleteCommandParser -AddressBookParser -> DeleteCommandParser -activate DeleteCommandParser - -DeleteCommandParser --> AddressBookParser -deactivate DeleteCommandParser - -AddressBookParser -> DeleteCommandParser : parse("1") -activate DeleteCommandParser - -create DeleteCommand -DeleteCommandParser -> DeleteCommand -activate DeleteCommand - -DeleteCommand --> DeleteCommandParser : d -deactivate DeleteCommand - -DeleteCommandParser --> AddressBookParser : d -deactivate DeleteCommandParser -'Hidden arrow to position the destroy marker below the end of the activation bar. -DeleteCommandParser -[hidden]-> AddressBookParser -destroy DeleteCommandParser - -AddressBookParser --> LogicManager : d -deactivate AddressBookParser - -LogicManager -> DeleteCommand : execute() -activate DeleteCommand - -DeleteCommand -> Model : deletePerson(1) -activate Model - -Model --> DeleteCommand -deactivate Model - -create CommandResult -DeleteCommand -> CommandResult -activate CommandResult - -CommandResult --> DeleteCommand -deactivate CommandResult - -DeleteCommand --> LogicManager : result -deactivate DeleteCommand - -[<--LogicManager -deactivate LogicManager -@enduml diff --git a/docs/diagrams/FindTransactionActivityDiagram.png b/docs/diagrams/FindTransactionActivityDiagram.png new file mode 100644 index 00000000000..e3e4b71e357 Binary files /dev/null and b/docs/diagrams/FindTransactionActivityDiagram.png differ diff --git a/docs/diagrams/FindTransactionActivityDiagram.puml b/docs/diagrams/FindTransactionActivityDiagram.puml new file mode 100644 index 00000000000..4e82eeca175 --- /dev/null +++ b/docs/diagrams/FindTransactionActivityDiagram.puml @@ -0,0 +1,125 @@ +@startuml +start +:User executes FindTransactionCommand; + +'Since the beta syntax does not support placing the condition outside the +'diamond we place it as the true branch instead. +:parse user input; +fork +if () then ([transaction type +is present]) + if () then ([transaction type + is valid]) + :activate transaction + type filter as + the given keyword; + else ([else]) + :throw parse + exception; + stop + endif +else ([else]) + :deactivate + transaction + type filter; +endif +fork again +if () then ([supplier name keywords + are present]) + if () then ([all supplier name + keywords are valid]) + :activate + supplier name + filter based on + supplier name + keywords given; + else ([else]) + :throw parse + exception; + stop + endif +else ([else]) + :deactivate + supplier + name filter; +endif +fork again +if () then ([good name keywords + are present]) + if () then ([all good name keywords + are valid]) + :activate + good name + filter based on + good name + keywords given; + else ([else]) + :throw parse + exception; + stop + endif + else ([else]) + :deactivate + good name + filter; + endif +end fork +if () then ([all filters deactivated]) + :Display error message indicating + no filter is present; + stop +else ([else]) + :create predicate based on the active filters; + :filter every transaction in the transactions list; + fork + if () then ([transaction type + filter is active]) + if () then ([transaction type +matches the keyword]) + :passes filter; + else ([else]) + :does not + pass filter; + endif + else ([else]) + :passes filter; + endif + fork again + if () then ([supplier name + filter is active]) + if () then ([supplier name +matches the keyword]) + :passes filter; + else ([else]) + :does not + pass filter; + endif + else ([else]) + :passes filter; + endif + fork again + if () then ([good name + filter is active]) + if () then ([good name +matches the keyword]) + :passes filter; + else ([else]) + :does not + pass filter; + endif + else ([else]) + :passes filter; + endif + end fork + endif +if () then ([passes 3 filters]) + :adds transaction + into filtered list; + else ([else]) + :does not + add transaction + into filtered list; + endif +:display filtered list of transactions; +stop +@enduml diff --git a/docs/diagrams/FindTransactionSequenceDiagram.png b/docs/diagrams/FindTransactionSequenceDiagram.png new file mode 100644 index 00000000000..da2605c090d Binary files /dev/null and b/docs/diagrams/FindTransactionSequenceDiagram.png differ diff --git a/docs/diagrams/FindTransactionSequenceDiagram.puml b/docs/diagrams/FindTransactionSequenceDiagram.puml new file mode 100644 index 00000000000..9c774887ce7 --- /dev/null +++ b/docs/diagrams/FindTransactionSequenceDiagram.puml @@ -0,0 +1,76 @@ +@startuml +!include style.puml + +box Logic LOGIC_COLOR_T1 +Participant ":LogicManager" as logicManager LOGIC_COLOR +Participant ":InventoryManagerParser" as inventoryManagerParser LOGIC_COLOR +Participant ":FindTransactionCommandParser" as findTransactionCommandParser LOGIC_COLOR +Participant "command:FindTransactionCommand" as findTransactionCommand LOGIC_COLOR +Participant "commandResult:CommandResult" as commandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as model MODEL_COLOR +end box + +[-[MODEL_COLOR]> logicManager : execute("find-t buy n/alice g/apple") +activate logicManager + +logicManager -[MODEL_COLOR]> inventoryManagerParser : parse("find-t buy n/alice g/apple") +activate inventoryManagerParser + +create findTransactionCommandParser +inventoryManagerParser -[MODEL_COLOR]> findTransactionCommandParser +activate findTransactionCommandParser + +findTransactionCommandParser -[MODEL_COLOR]-> inventoryManagerParser +deactivate findTransactionCommandParser + +inventoryManagerParser -[MODEL_COLOR]> findTransactionCommandParser : parse("buy n/alice g/apple") +activate findTransactionCommandParser + +create findTransactionCommand +findTransactionCommandParser -[MODEL_COLOR]> findTransactionCommand : predicate +activate findTransactionCommand + +findTransactionCommand -[MODEL_COLOR]-> findTransactionCommandParser :command +deactivate findTransactionCommand + +findTransactionCommandParser -[MODEL_COLOR]-> inventoryManagerParser :command +deactivate findTransactionCommandParser + +inventoryManagerParser -[MODEL_COLOR]-> logicManager : command +deactivate inventoryManagerParser + +destroy findTransactionCommandParser + +logicManager -[MODEL_COLOR]> findTransactionCommand :execute() +activate findTransactionCommand + +findTransactionCommand -[MODEL_COLOR]> model : updateFilterTransactionList(predicate) +activate model + +model -[MODEL_COLOR]-> findTransactionCommand +deactivate model + +findTransactionCommand -[MODEL_COLOR]> model : getFilteredTransactionList().size() +activate model + +model -[MODEL_COLOR]-> findTransactionCommand : size +deactivate model + +create commandResult +findTransactionCommand -[MODEL_COLOR]> commandResult : size +activate commandResult + +commandResult -[MODEL_COLOR]-> findTransactionCommand :commandResult +deactivate commandResult + +findTransactionCommand -[MODEL_COLOR]-> logicManager :commandResult +deactivate findTransactionCommand + +[<--logicManager :commandResult +deactivate logicManager + +destroy findTransactionCommand +@endumlreso diff --git a/docs/diagrams/GoodModelClassDiagram.png b/docs/diagrams/GoodModelClassDiagram.png new file mode 100644 index 00000000000..b4710f340e3 Binary files /dev/null and b/docs/diagrams/GoodModelClassDiagram.png differ diff --git a/docs/diagrams/GoodModelClassDiagram.puml b/docs/diagrams/GoodModelClassDiagram.puml new file mode 100644 index 00000000000..2bef0d2611d --- /dev/null +++ b/docs/diagrams/GoodModelClassDiagram.puml @@ -0,0 +1,20 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR +skinparam classBackgroundColor MODEL_COLOR + +package Good { + class Good + class GoodName + class GoodQuantity + class UniqueGoodList +} + +Inventory *-right- "1" UniqueGoodList + +UniqueGoodList o-right- "*" Good + +Good *-- "1" GoodName +Good *-- "2" GoodQuantity +@enduml diff --git a/docs/diagrams/GoodWithExpiryDate.png b/docs/diagrams/GoodWithExpiryDate.png new file mode 100644 index 00000000000..d70b28ae812 Binary files /dev/null and b/docs/diagrams/GoodWithExpiryDate.png differ diff --git a/docs/diagrams/GoodWithExpiryDate.puml b/docs/diagrams/GoodWithExpiryDate.puml new file mode 100644 index 00000000000..5fc56427c1f --- /dev/null +++ b/docs/diagrams/GoodWithExpiryDate.puml @@ -0,0 +1,33 @@ +@startuml +'!include style.puml +show members +hide empty members +hide circle + +skinparam ClassFontColor #000000 +skinparam ClassBorderColor #000000 + +title Augmenting Good Class with Expiry Dates + +skinparam classAttributeIconSize 0 +class "Good" as currentGoodClass { +-goodname : GoodName +-goodquantity : GoodQuantity +-threshold : GoodQuantity +} + +class "Good" as proposedGoodClass{ +-goodname : GoodName +-goodquantity : GoodQuantity +-threshold : GoodQuantity +-expiryDates : TreeMap +} + +class "Current Good Class" as StatePointer0 #FFFFFF +StatePointer0 -[hidden]- currentGoodClass + +class "Proposed Good Class" as StatePointer1 #FFFFFF +StatePointer1 -[hidden]- proposedGoodClass + + +@enduml diff --git a/docs/diagrams/LinearHistoryClassDiagram.png b/docs/diagrams/LinearHistoryClassDiagram.png new file mode 100644 index 00000000000..f1d2ed304b6 Binary files /dev/null and b/docs/diagrams/LinearHistoryClassDiagram.png differ diff --git a/docs/diagrams/LinearHistoryClassDiagram.puml b/docs/diagrams/LinearHistoryClassDiagram.puml new file mode 100644 index 00000000000..55fa4d8620c --- /dev/null +++ b/docs/diagrams/LinearHistoryClassDiagram.puml @@ -0,0 +1,26 @@ +@startuml +!include style.puml +show members +hide empty members + +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR_T2 +skinparam classBackgroundColor MODEL_COLOR_T2 + +Interface Version << Interface >> +Interface Versionable << Interface >> +Interface Copyable << Interface >> +Class LinearHistory +Class VersionedInventory +Class Inventory + +Version : getCurrentState() +Copyable : copy() + +Versionable <|-- Version +Version <|.. LinearHistory +Copyable <|.. Inventory +Copyable <-- LinearHistory +LinearHistory <-- VersionedInventory +Inventory <.. VersionedInventory +@enduml diff --git a/docs/diagrams/LogicClassDiagram.png b/docs/diagrams/LogicClassDiagram.png new file mode 100644 index 00000000000..6f158568605 Binary files /dev/null and b/docs/diagrams/LogicClassDiagram.png differ diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml old mode 100644 new mode 100755 index 016ef33e2e2..fd58eecb4e1 --- a/docs/diagrams/LogicClassDiagram.puml +++ b/docs/diagrams/LogicClassDiagram.puml @@ -8,7 +8,7 @@ package Logic { package Parser { Interface Parser <> -Class AddressBookParser +Class InventoryManagerParser Class XYZCommandParser Class CliSyntax Class ParserUtil @@ -35,8 +35,8 @@ Class HiddenOutside #FFFFFF HiddenOutside ..> Logic LogicManager .up.|> Logic -LogicManager -->"1" AddressBookParser -AddressBookParser .left.> XYZCommandParser: creates > +LogicManager -->"1" InventoryManagerParser +InventoryManagerParser .left.> XYZCommandParser: creates > XYZCommandParser ..> XYZCommand : creates > XYZCommandParser ..|> Parser diff --git a/docs/diagrams/ModelClassDiagram.png b/docs/diagrams/ModelClassDiagram.png new file mode 100644 index 00000000000..110f107aeb7 Binary files /dev/null and b/docs/diagrams/ModelClassDiagram.png differ diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml index e85a00d4107..26dcd29ece0 100644 --- a/docs/diagrams/ModelClassDiagram.puml +++ b/docs/diagrams/ModelClassDiagram.puml @@ -4,53 +4,37 @@ skinparam arrowThickness 1.1 skinparam arrowColor MODEL_COLOR skinparam classBackgroundColor MODEL_COLOR +class HiddenOutside + Package Model <>{ -Interface ReadOnlyAddressBook <> Interface Model <> Interface ObservableList <> -Class AddressBook -Class ReadOnlyAddressBook +Interface ReadOnlyList<> +Class VersionedAddressBook +Class VersionedInventory +Class VersionedTransactionHistory Class Model Class ModelManager Class UserPrefs Class ReadOnlyUserPrefs -Package Person { -Class Person -Class Address -Class Email -Class Name -Class Phone -Class UniquePersonList -} - -Package Tag { -Class Tag -} -} - Class HiddenOutside #FFFFFF HiddenOutside ..> Model -AddressBook .up.|> ReadOnlyAddressBook +AddressBook .down.|> ReadOnlyList +Inventory .down.|> ReadOnlyList +TransactionHistory .down.|> ReadOnlyList ModelManager .up.|> Model -Model .right.> ObservableList -ModelManager o--> "1" AddressBook -ModelManager o-left-> "1" UserPrefs +Model .left.> ObservableList +ModelManager o-- "1" VersionedAddressBook +ModelManager o-- "1" VersionedInventory +ModelManager o-- "1" VersionedTransactionHistory +VersionedAddressBook --|> AddressBook +VersionedInventory --|> Inventory +VersionedTransactionHistory --|> TransactionHistory + +ModelManager o-left- "1" UserPrefs UserPrefs .up.|> ReadOnlyUserPrefs -AddressBook *--> "1" UniquePersonList -UniquePersonList o--> "*" Person -Person *--> Name -Person *--> Phone -Person *--> Email -Person *--> Address -Person *--> "*" Tag - -Name -[hidden]right-> Phone -Phone -[hidden]right-> Address -Address -[hidden]right-> Email - -ModelManager -->"1" Person : filtered list @enduml diff --git a/docs/diagrams/SequentialDiagramEditSupplier.png b/docs/diagrams/SequentialDiagramEditSupplier.png new file mode 100644 index 00000000000..1782fc942e8 Binary files /dev/null and b/docs/diagrams/SequentialDiagramEditSupplier.png differ diff --git a/docs/diagrams/SetThresholdSequenceDiagram.png b/docs/diagrams/SetThresholdSequenceDiagram.png new file mode 100644 index 00000000000..9ed93ce95b3 Binary files /dev/null and b/docs/diagrams/SetThresholdSequenceDiagram.png differ diff --git a/docs/diagrams/SetThresholdSequenceDiagram.puml b/docs/diagrams/SetThresholdSequenceDiagram.puml new file mode 100644 index 00000000000..f3d827791fb --- /dev/null +++ b/docs/diagrams/SetThresholdSequenceDiagram.puml @@ -0,0 +1,78 @@ +@startuml +!include style.puml + +box Ui UI_COLOR_T1 +Participant ":MainWindow" as mainWindow UI_COLOR +Participant ":GoodInformation" as goodInformation UI_COLOR +end box + +box Logic LOGIC_COLOR_T1 +Participant ":LogicManager" as logicManager LOGIC_COLOR +Participant ":InventoryManagerParser" as inventoryManagerParser LOGIC_COLOR +Participant ":setThresholdCommandParser" as setThresholdCommandParser LOGIC_COLOR +Participant "command:setThresholdCommand" as setThresholdCommand LOGIC_COLOR +Participant "commandResult:CommandResult" as commandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as model MODEL_COLOR +end box + +[-[MODEL_COLOR]> mainWindow : execute("warn 5 q/100") +activate mainWindow + +mainWindow -[MODEL_COLOR]> logicManager : execute("warn 5 q/100") +activate logicManager + +logicManager -[MODEL_COLOR]> inventoryManagerParser : parse("warn 5 q/100") +activate inventoryManagerParser + +create setThresholdCommandParser +inventoryManagerParser -[MODEL_COLOR]> setThresholdCommandParser +activate setThresholdCommandParser + +setThresholdCommandParser -[MODEL_COLOR]-> inventoryManagerParser +deactivate setThresholdCommandParser + +inventoryManagerParser -[MODEL_COLOR]> setThresholdCommandParser : parse("5 q/100") +activate setThresholdCommandParser + +create setThresholdCommand +setThresholdCommandParser -[MODEL_COLOR]> setThresholdCommand : index, threshold quantity +activate setThresholdCommand + +setThresholdCommand -[MODEL_COLOR]-> setThresholdCommandParser :command +deactivate setThresholdCommand + +setThresholdCommandParser -[MODEL_COLOR]-> inventoryManagerParser :command +deactivate setThresholdCommandParser + +inventoryManagerParser -[MODEL_COLOR]-> logicManager : command +deactivate inventoryManagerParser + +destroy setThresholdCommandParser + +logicManager -[MODEL_COLOR]> setThresholdCommand :execute() +activate setThresholdCommand + +ref over goodInformation, setThresholdCommand, model :interaction with model and goodInformation + +create commandResult +setThresholdCommand -[MODEL_COLOR]> commandResult : newGood +activate commandResult + +commandResult -[MODEL_COLOR]-> setThresholdCommand :commandResult +deactivate commandResult + +setThresholdCommand -[MODEL_COLOR]-> logicManager :commandResult +deactivate setThresholdCommand + +logicManager -[MODEL_COLOR]-> mainWindow :commandResult +deactivate logicManager + +destroy setThresholdCommand + +[<--mainWindow +deactivate mainWindow + +@endumlreso diff --git a/docs/diagrams/SetThresholdSequenceDiagram2.png b/docs/diagrams/SetThresholdSequenceDiagram2.png new file mode 100644 index 00000000000..c152e00044a Binary files /dev/null and b/docs/diagrams/SetThresholdSequenceDiagram2.png differ diff --git a/docs/diagrams/SetThresholdSequenceDiagram2.puml b/docs/diagrams/SetThresholdSequenceDiagram2.puml new file mode 100644 index 00000000000..07f5dc3c14f --- /dev/null +++ b/docs/diagrams/SetThresholdSequenceDiagram2.puml @@ -0,0 +1,81 @@ +@startuml +mainframe interaction with model +!include style.puml + +box Ui UI_COLOR_T1 +Participant ":GoodInformation" as goodInformation UI_COLOR +Participant "goodQuantity:Label" as goodQuantity UI_COLOR +end box + +box Logic LOGIC_COLOR_T1 +Participant "command:setThresholdCommand" as setThresholdCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as model MODEL_COLOR +participant "newGood:Good" as good MODEL_COLOR +end box + +[-[MODEL_COLOR]> setThresholdCommand: execute() +activate setThresholdCommand + +setThresholdCommand -[MODEL_COLOR]> model : getGood(index) +activate model + +model -[MODEL_COLOR]-> setThresholdCommand : good +deactivate model + +create good +setThresholdCommand -[MODEL_COLOR]> good : good, threshold quantity +activate good + +good -[MODEL_COLOR]-> setThresholdCommand : newGood +deactivate good + +setThresholdCommand -[MODEL_COLOR]> model : setGood(good, threshold quantity) +activate model + +model -[MODEL_COLOR]> model : sort() +activate model + +model -[MODEL_COLOR]> model +deactivate model + +model -[MODEL_COLOR]> setThresholdCommand +deactivate model + +setThresholdCommand -[MODEL_COLOR]> model : updateFilteredGoodList(predicate) +activate model + +model -[MODEL_COLOR]> goodInformation : warningLowQuantity() +activate goodInformation + +alt if lower than threshold quantity + goodInformation -[MODEL_COLOR]> goodQuantity: setStyle("-fx-background-color: red"); + activate goodQuantity + goodQuantity -[MODEL_COLOR]> goodInformation + deactivate goodQuantity +else + goodInformation -[MODEL_COLOR]> goodQuantity: setStyle(""); + activate goodQuantity + goodQuantity -[MODEL_COLOR]> goodInformation + deactivate goodQuantity +end + +goodInformation -[MODEL_COLOR]> model +deactivate goodInformation + + +model -[MODEL_COLOR]> setThresholdCommand +deactivate model + +setThresholdCommand -[MODEL_COLOR]> model : commit() +activate model + +model -[MODEL_COLOR]> setThresholdCommand +deactivate model + +[<--setThresholdCommand +deactivate setThresholdCommand + +@enduml diff --git a/docs/diagrams/StorageClassDiagram.png b/docs/diagrams/StorageClassDiagram.png new file mode 100644 index 00000000000..24004927aa7 Binary files /dev/null and b/docs/diagrams/StorageClassDiagram.png differ diff --git a/docs/diagrams/StorageClassDiagram.puml b/docs/diagrams/StorageClassDiagram.puml index 6adb2e156bf..82d1c1eee97 100644 --- a/docs/diagrams/StorageClassDiagram.puml +++ b/docs/diagrams/StorageClassDiagram.puml @@ -7,18 +7,37 @@ skinparam classBackgroundColor STORAGE_COLOR Interface Storage <> Interface UserPrefsStorage <> Interface AddressBookStorage <> +Interface InventoryStorage <> +Interface TransactionHistoryStorage <> Class StorageManager Class JsonUserPrefsStorage Class JsonAddressBookStorage +Class JsonInventoryStorage +Class JsonTransactionHistoryStorage + StorageManager .left.|> Storage StorageManager o-right-> UserPrefsStorage StorageManager o--> AddressBookStorage +StorageManager o--> InventoryStorage +StorageManager o--> TransactionHistoryStorage JsonUserPrefsStorage .left.|> UserPrefsStorage + JsonAddressBookStorage .left.|> AddressBookStorage JsonAddressBookStorage .down.> JsonSerializableAddressBookStorage -JsonSerializableAddressBookStorage .right.> JsonSerializablePerson -JsonSerializablePerson .right.> JsonAdaptedTag +JsonSerializableAddressBookStorage .down.> JsonSerializableSupplier +JsonSerializableSupplier .down.> JsonAdaptedOffer + +JsonInventoryStorage .left.|> InventoryStorage +JsonInventoryStorage .down.> JsonSerializableInventoryStorage +JsonSerializableInventoryStorage .down.> JsonSerializableGood + +JsonTransactionHistoryStorage .left.|> TransactionHistoryStorage +JsonTransactionHistoryStorage .down.> JsonSerializableTransactionHistoryStorage +JsonSerializableTransactionHistoryStorage .down.> JsonSerializableTransaction +JsonSerializableTransaction .down.> JsonSerializableGood +JsonSerializableTransaction .down.> JsonSerializableSupplier + @enduml diff --git a/docs/diagrams/SupplierModelClassDiagram.png b/docs/diagrams/SupplierModelClassDiagram.png new file mode 100644 index 00000000000..d16792c0615 Binary files /dev/null and b/docs/diagrams/SupplierModelClassDiagram.png differ diff --git a/docs/diagrams/SupplierModelClassDiagram.puml b/docs/diagrams/SupplierModelClassDiagram.puml new file mode 100644 index 00000000000..6487caa1ba9 --- /dev/null +++ b/docs/diagrams/SupplierModelClassDiagram.puml @@ -0,0 +1,38 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR +skinparam classBackgroundColor MODEL_COLOR + +package Supplier { + class UniqueSupplierList + class Supplier + class Name + class Phone + class Email + class Address +} + +package Offer { + class Offer + class Price +} + +package Good { + class GoodName +} + +AddressBook *-right- "1" UniqueSupplierList + +UniqueSupplierList o-right- "*" Supplier + +Supplier *-- "*" Offer +Supplier *--"1" Name +Supplier *--"1" Phone +Supplier *--"1" Email +Supplier *--"1" Address + +Offer *-- "1" GoodName +Offer *-- "1" Price + +@enduml diff --git a/docs/diagrams/TransactionModelClassDiagram.png b/docs/diagrams/TransactionModelClassDiagram.png new file mode 100644 index 00000000000..8a3f2a2b106 Binary files /dev/null and b/docs/diagrams/TransactionModelClassDiagram.png differ diff --git a/docs/diagrams/TransactionModelClassDiagram.puml b/docs/diagrams/TransactionModelClassDiagram.puml new file mode 100644 index 00000000000..6763127f854 --- /dev/null +++ b/docs/diagrams/TransactionModelClassDiagram.puml @@ -0,0 +1,45 @@ +@startuml +!include style.puml +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR +skinparam classBackgroundColor MODEL_COLOR + +package Transaction { + abstract Transaction <> + class BuyTransaction + class SellTransaction + class TransactionId + class UniqueTransactionList +} + +package Offer { + class Price +} + +package Good { + class GoodName + class GoodQuantity +} + +package Supplier { + class Supplier +} + +TransactionHistory *-right- "1" UniqueTransactionList + +UniqueTransactionList o-right- "*" Transaction + +Transaction *-up- "1" TransactionId +Transaction *-down- "1" GoodName +Transaction *-down- "1" GoodQuantity + +SellTransaction -up-|> Transaction +BuyTransaction -up-|> Transaction + +SellTransaction -[hidden]right- BuyTransaction + +BuyTransaction *-- "1" Supplier +BuyTransaction *-- "1" Price +SellTransaction *-- "1" Price + +@enduml diff --git a/docs/diagrams/UiClassDiagram.png b/docs/diagrams/UiClassDiagram.png new file mode 100644 index 00000000000..f7fac819e4f Binary files /dev/null and b/docs/diagrams/UiClassDiagram.png differ diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml old mode 100644 new mode 100755 index 92746f9fcf7..1e16a1890ff --- a/docs/diagrams/UiClassDiagram.puml +++ b/docs/diagrams/UiClassDiagram.puml @@ -11,8 +11,12 @@ Class UiManager Class MainWindow Class HelpWindow Class ResultDisplay -Class PersonListPanel -Class PersonCard +Class SupplierListPanel +Class SupplierCard +Class GoodListPanel +Class GoodCard +Class TransactionListPanel +Class TransactionCard Class StatusBarFooter Class CommandBox } @@ -33,25 +37,37 @@ UiManager -down-> MainWindow MainWindow --> HelpWindow MainWindow *-down-> CommandBox MainWindow *-down-> ResultDisplay -MainWindow *-down-> PersonListPanel +MainWindow *-down-> SupplierListPanel +MainWindow *-down-> GoodListPanel +MainWindow *-down-> TransactionListPanel MainWindow *-down-> StatusBarFooter -PersonListPanel -down-> PersonCard +SupplierListPanel -down-> SupplierCard +GoodListPanel -down-> GoodCard +TransactionListPanel -down-> TransactionCard MainWindow -left-|> UiPart ResultDisplay --|> UiPart CommandBox --|> UiPart -PersonListPanel --|> UiPart -PersonCard --|> UiPart +SupplierListPanel --|> UiPart +SupplierCard --|> UiPart +GoodListPanel --|> UiPart +GoodCard --|> UiPart +TransactionListPanel --|> UiPart +TransactionCard --|> UiPart StatusBarFooter --|> UiPart HelpWindow -down-|> UiPart -PersonCard ..> Model +SupplierCard ..> Model +GoodCard ..> Model +TransactionCard ..> Model UiManager -right-> Logic MainWindow -left-> Logic -PersonListPanel -[hidden]left- HelpWindow +SupplierListPanel -[hidden]left- HelpWindow +GoodListPanel -[hidden]left- HelpWindow +TransactionListPanel -[hidden]left- HelpWindow HelpWindow -[hidden]left- CommandBox CommandBox -[hidden]left- ResultDisplay ResultDisplay -[hidden]left- StatusBarFooter diff --git a/docs/diagrams/UndoRedoState0.png b/docs/diagrams/UndoRedoState0.png new file mode 100644 index 00000000000..05870a619fc Binary files /dev/null and b/docs/diagrams/UndoRedoState0.png differ diff --git a/docs/diagrams/UndoRedoState0.puml b/docs/diagrams/UndoRedoState0.puml old mode 100644 new mode 100755 index 96e30744d24..2cdded90532 --- a/docs/diagrams/UndoRedoState0.puml +++ b/docs/diagrams/UndoRedoState0.puml @@ -1,20 +1,24 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 title Initial state -package States { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab2:AddressBook__" +package LinearHistory { + package History { + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } + + object "__currentState:Inventory__" as curr + curr : goods = {"apple 1", "banana 2", "citrus 3"} + + class "statePointer" as StatePointer #FFFFFF + State0 <-- StatePointer } -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 -hide State2 -hide State3 -class Pointer as "Current State" #FFFFF -Pointer -up-> State1 @end diff --git a/docs/diagrams/UndoRedoState1.png b/docs/diagrams/UndoRedoState1.png new file mode 100644 index 00000000000..5fc9f9373f7 Binary files /dev/null and b/docs/diagrams/UndoRedoState1.png differ diff --git a/docs/diagrams/UndoRedoState1.puml b/docs/diagrams/UndoRedoState1.puml old mode 100644 new mode 100755 index 01fcb9b2b96..316c02a2301 --- a/docs/diagrams/UndoRedoState1.puml +++ b/docs/diagrams/UndoRedoState1.puml @@ -1,22 +1,27 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 -title After command "delete 5" +title After "delete-g 3" command -package States <> { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab2:AddressBook__" -} +package LinearHistory { + package History { + object "__saved1:Inventory__" as State1 + State1 : goods = {"apple 1", "banana 2"} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } -hide State3 + object "__currentState:Inventory__" as curr + curr : goods = {"apple 1", "banana 2"} -class Pointer as "Current State" #FFFFF + class "statePointer" as StatePointer #FFFFFF + State1 <-- StatePointer +} -Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState2.png b/docs/diagrams/UndoRedoState2.png new file mode 100644 index 00000000000..4600e73574e Binary files /dev/null and b/docs/diagrams/UndoRedoState2.png differ diff --git a/docs/diagrams/UndoRedoState2.puml b/docs/diagrams/UndoRedoState2.puml old mode 100644 new mode 100755 index bccc230a5d1..c9103d17561 --- a/docs/diagrams/UndoRedoState2.puml +++ b/docs/diagrams/UndoRedoState2.puml @@ -1,20 +1,30 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 -title After command "add n/David" +title After "buy 1 g/apple q/5" command -package States <> { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab2:AddressBook__" -} +package LinearHistory { + package History { + object "__saved2:Inventory__" as State2 + State2 : goods = {"apple 6", "banana 2"} + + object "__saved1:Inventory__" as State1 + State1 : goods = {"apple 1", "banana 2"} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } -class Pointer as "Current State" #FFFFF + object "__currentState:Inventory__" as curr + curr : goods = {"apple 6", "banana 2"} + + class "statePointer" as StatePointer #FFFFFF + State2 <-- StatePointer +} -Pointer -up-> State3 @end diff --git a/docs/diagrams/UndoRedoState3.png b/docs/diagrams/UndoRedoState3.png new file mode 100644 index 00000000000..e3a7baaf6cf Binary files /dev/null and b/docs/diagrams/UndoRedoState3.png differ diff --git a/docs/diagrams/UndoRedoState3.puml b/docs/diagrams/UndoRedoState3.puml old mode 100644 new mode 100755 index ea29c9483e4..961a9b82548 --- a/docs/diagrams/UndoRedoState3.puml +++ b/docs/diagrams/UndoRedoState3.puml @@ -1,20 +1,30 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 -title After command "undo" +title After "undo" command -package States <> { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab2:AddressBook__" -} +package LinearHistory { + package History { + object "__saved2:Inventory__" as State2 + State2 : goods = {"apple 6", "banana 2"} + + object "__saved1:Inventory__" as State1 + State1 : goods = {"apple 1", "banana 2"} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } -class Pointer as "Current State" #FFFFF + object "__currentState:Inventory__" as curr + curr : goods = {"apple 1", "banana 2"} + + class "statePointer" as StatePointer #FFFFFF + State1 <-- StatePointer +} -Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState4.png b/docs/diagrams/UndoRedoState4.png new file mode 100644 index 00000000000..39ba9e4ab7c Binary files /dev/null and b/docs/diagrams/UndoRedoState4.png differ diff --git a/docs/diagrams/UndoRedoState4.puml b/docs/diagrams/UndoRedoState4.puml old mode 100644 new mode 100755 index 1b784cece80..2012e0190f9 --- a/docs/diagrams/UndoRedoState4.puml +++ b/docs/diagrams/UndoRedoState4.puml @@ -1,20 +1,30 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 -title After command "list" +title After "list-t" command -package States <> { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab2:AddressBook__" -} +package LinearHistory { + package History { + object "__saved2:Inventory__" as State2 + State2 : goods = {"apple 6", "banana 2"} + + object "__saved1:Inventory__" as State1 + State1 : goods = {"apple 1", "banana 2"} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } -class Pointer as "Current State" #FFFFF + object "__currentState:Inventory__" as curr + curr : goods = {"apple 1", "banana 2"} + + class "statePointer" as StatePointer #FFFFFF + State1 <-- StatePointer +} -Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState5.png b/docs/diagrams/UndoRedoState5.png new file mode 100644 index 00000000000..ada31b8212e Binary files /dev/null and b/docs/diagrams/UndoRedoState5.png differ diff --git a/docs/diagrams/UndoRedoState5.puml b/docs/diagrams/UndoRedoState5.puml old mode 100644 new mode 100755 index 88927be32bc..cd127185af5 --- a/docs/diagrams/UndoRedoState5.puml +++ b/docs/diagrams/UndoRedoState5.puml @@ -1,21 +1,31 @@ @startuml !include style.puml +show members +hide empty members + skinparam ClassFontColor #000000 skinparam ClassBorderColor #000000 -title After command "clear" +title After "sell 2 q/1 p/5" command -package States <> { - class State1 as "__ab0:AddressBook__" - class State2 as "__ab1:AddressBook__" - class State3 as "__ab3:AddressBook__" -} +package LinearHistory { + package History { + object "__saved3:Inventory__" as State3 + State3 : goods = {"apple 1", "banana 1"} + + object "__saved1:Inventory__" as State1 + State1 : goods = {"apple 1", "banana 2"} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 + object "__saved0:Inventory__" as State0 + State0 : goods = {"apple 1", "banana 2", "citrus 3"} + } -class Pointer as "Current State" #FFFFF + object "__currentState:Inventory__" as curr + curr : goods = {"apple 1", "banana 1"} + + class "statePointer" as StatePointer #FFFFFF + State3 <-- StatePointer + note right on link: State saved2 deleted. +} -Pointer -up-> State3 -note right on link: State ab2 deleted. @end diff --git a/docs/diagrams/UndoSequenceDiagram.png b/docs/diagrams/UndoSequenceDiagram.png new file mode 100644 index 00000000000..fe4188790ec Binary files /dev/null and b/docs/diagrams/UndoSequenceDiagram.png differ diff --git a/docs/diagrams/UndoSequenceDiagram.puml b/docs/diagrams/UndoSequenceDiagram.puml old mode 100644 new mode 100755 index 410aab4e412..38f4dd7d0b6 --- a/docs/diagrams/UndoSequenceDiagram.puml +++ b/docs/diagrams/UndoSequenceDiagram.puml @@ -3,42 +3,41 @@ box Logic LOGIC_COLOR_T1 participant ":LogicManager" as LogicManager LOGIC_COLOR -participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":InventoryManagerParser" as InventoryManagerParser LOGIC_COLOR participant "u:UndoCommand" as UndoCommand LOGIC_COLOR end box box Model MODEL_COLOR_T1 participant ":Model" as Model MODEL_COLOR -participant ":VersionedAddressBook" as VersionedAddressBook MODEL_COLOR +participant ":VersionedInventory" as VersionedInventory MODEL_COLOR end box [-> LogicManager : execute(undo) activate LogicManager -LogicManager -> AddressBookParser : parseCommand(undo) -activate AddressBookParser +LogicManager -> InventoryManagerParser : parseCommand(undo) +activate InventoryManagerParser create UndoCommand -AddressBookParser -> UndoCommand +InventoryManagerParser -> UndoCommand activate UndoCommand -UndoCommand --> AddressBookParser +UndoCommand --> InventoryManagerParser deactivate UndoCommand -AddressBookParser --> LogicManager : u -deactivate AddressBookParser +InventoryManagerParser --> LogicManager : u +deactivate InventoryManagerParser LogicManager -> UndoCommand : execute() activate UndoCommand -UndoCommand -> Model : undoAddressBook() +UndoCommand -> Model : undo() activate Model -Model -> VersionedAddressBook : undo() -activate VersionedAddressBook +Model -> VersionedInventory : undo() +activate VersionedInventory -VersionedAddressBook -> VersionedAddressBook :resetData(ReadOnlyAddressBook) -VersionedAddressBook --> Model : -deactivate VersionedAddressBook +VersionedInventory --> Model : +deactivate VersionedInventory Model --> UndoCommand deactivate Model diff --git a/docs/diagrams/VersionClassDiagram.png b/docs/diagrams/VersionClassDiagram.png new file mode 100644 index 00000000000..1b0e5028ae8 Binary files /dev/null and b/docs/diagrams/VersionClassDiagram.png differ diff --git a/docs/diagrams/VersionClassDiagram.puml b/docs/diagrams/VersionClassDiagram.puml new file mode 100644 index 00000000000..0580503acf3 --- /dev/null +++ b/docs/diagrams/VersionClassDiagram.puml @@ -0,0 +1,28 @@ +@startuml +!include style.puml +show members +hide empty members + +skinparam arrowThickness 1.1 +skinparam arrowColor MODEL_COLOR_T2 +skinparam classBackgroundColor MODEL_COLOR_T2 + +Interface Versionable << Interface >> +Interface Model << Interface >> + +Model <|.. ModelManager + +ModelManager o-- VersionedAddressBook +ModelManager o-- VersionedInventory +ModelManager o-- VersionedTransactionHistory + +Versionable <|.down. Model +Versionable <|.. VersionedAddressBook +Versionable <|.. VersionedInventory +Versionable <|.. VersionedTransactionHistory + +Versionable : commit() +Versionable : undo() +Versionable : redo() + +@enduml diff --git a/docs/diagrams/add-remark/CommandInterface.puml b/docs/diagrams/add-remark/CommandInterface.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/add-remark/ParserInterface.puml b/docs/diagrams/add-remark/ParserInterface.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/AbeforeC.puml b/docs/diagrams/plantuml/AbeforeC.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/AllDown.puml b/docs/diagrams/plantuml/AllDown.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/ArrowLength.puml b/docs/diagrams/plantuml/ArrowLength.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/CbeforeA.puml b/docs/diagrams/plantuml/CbeforeA.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/HiddenArrows.puml b/docs/diagrams/plantuml/HiddenArrows.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/PackagesAndConsistency.puml b/docs/diagrams/plantuml/PackagesAndConsistency.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/plantuml/UpAndDown.puml b/docs/diagrams/plantuml/UpAndDown.puml old mode 100644 new mode 100755 diff --git a/docs/diagrams/style.puml b/docs/diagrams/style.puml old mode 100644 new mode 100755 index fad8b0adeaa..d017a90e64e --- a/docs/diagrams/style.puml +++ b/docs/diagrams/style.puml @@ -43,6 +43,8 @@ skinparam Class { BorderColor #FFFFFF StereotypeFontColor #FFFFFF FontName Arial + AttributeFontName Arial + AttributeFontColor #FFFFFF } skinparam Actor { diff --git a/docs/diagrams/tracing/LogicSequenceDiagram.puml b/docs/diagrams/tracing/LogicSequenceDiagram.puml old mode 100644 new mode 100755 diff --git a/docs/images/ActivityDiagramEditSupplier.jpg b/docs/images/ActivityDiagramEditSupplier.jpg new file mode 100644 index 00000000000..a099a681cee Binary files /dev/null and b/docs/images/ActivityDiagramEditSupplier.jpg differ diff --git a/docs/images/ArchitectureDiagram.png b/docs/images/ArchitectureDiagram.png old mode 100644 new mode 100755 diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png old mode 100644 new mode 100755 index aa198138f8f..f81e35e3a17 Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png deleted file mode 100644 index bc7ed18ae29..00000000000 Binary files a/docs/images/BetterModelClassDiagram.png and /dev/null differ diff --git a/docs/images/BuySequenceDiagram.png b/docs/images/BuySequenceDiagram.png new file mode 100644 index 00000000000..a127a63a139 Binary files /dev/null and b/docs/images/BuySequenceDiagram.png differ diff --git a/docs/images/CommitActivityDiagram.png b/docs/images/CommitActivityDiagram.png old mode 100644 new mode 100755 index 4de4fa4bf2b..0fcf1166346 Binary files a/docs/images/CommitActivityDiagram.png and b/docs/images/CommitActivityDiagram.png differ diff --git a/docs/images/DeleteSequenceDiagram.png b/docs/images/DeleteSequenceDiagram.png old mode 100644 new mode 100755 diff --git a/docs/images/DependencyInjection.png b/docs/images/DependencyInjection.png old mode 100644 new mode 100755 diff --git a/docs/images/DependencyInjectionWithoutDIP.png b/docs/images/DependencyInjectionWithoutDIP.png old mode 100644 new mode 100755 diff --git a/docs/images/FindTransactionActivityDiagram.png b/docs/images/FindTransactionActivityDiagram.png new file mode 100644 index 00000000000..e3e4b71e357 Binary files /dev/null and b/docs/images/FindTransactionActivityDiagram.png differ diff --git a/docs/images/FindTransactionSequenceDiagram.png b/docs/images/FindTransactionSequenceDiagram.png new file mode 100644 index 00000000000..da2605c090d Binary files /dev/null and b/docs/images/FindTransactionSequenceDiagram.png differ diff --git a/docs/images/GoodModelClassDiagram.png b/docs/images/GoodModelClassDiagram.png new file mode 100644 index 00000000000..b4710f340e3 Binary files /dev/null and b/docs/images/GoodModelClassDiagram.png differ diff --git a/docs/images/GoodWithExpiryDate.png b/docs/images/GoodWithExpiryDate.png new file mode 100644 index 00000000000..d70b28ae812 Binary files /dev/null and b/docs/images/GoodWithExpiryDate.png differ diff --git a/docs/images/LinearHistoryClassDiagram.png b/docs/images/LinearHistoryClassDiagram.png new file mode 100644 index 00000000000..f1d2ed304b6 Binary files /dev/null and b/docs/images/LinearHistoryClassDiagram.png differ diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png old mode 100644 new mode 100755 index b9e853cef12..6f158568605 Binary files a/docs/images/LogicClassDiagram.png and b/docs/images/LogicClassDiagram.png differ diff --git a/docs/images/LogicStorageDIP.png b/docs/images/LogicStorageDIP.png old mode 100644 new mode 100755 diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png old mode 100644 new mode 100755 index 280064118cf..110f107aeb7 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/OfferModelClassDiagram.png b/docs/images/OfferModelClassDiagram.png new file mode 100644 index 00000000000..12c37a0ef2c Binary files /dev/null and b/docs/images/OfferModelClassDiagram.png differ diff --git a/docs/images/PrintableInterface.png b/docs/images/PrintableInterface.png old mode 100644 new mode 100755 diff --git a/docs/images/ReadOnlyAddressBookUsage.png b/docs/images/ReadOnlyAddressBookUsage.png old mode 100644 new mode 100755 diff --git a/docs/images/SeEduLogo.png b/docs/images/SeEduLogo.png old mode 100644 new mode 100755 diff --git a/docs/images/SequentialDiagramEditSupplier.png b/docs/images/SequentialDiagramEditSupplier.png new file mode 100644 index 00000000000..1782fc942e8 Binary files /dev/null and b/docs/images/SequentialDiagramEditSupplier.png differ diff --git a/docs/images/SetThresholdSequenceDiagram.png b/docs/images/SetThresholdSequenceDiagram.png new file mode 100644 index 00000000000..9ed93ce95b3 Binary files /dev/null and b/docs/images/SetThresholdSequenceDiagram.png differ diff --git a/docs/images/SetThresholdSequenceDiagram2.png b/docs/images/SetThresholdSequenceDiagram2.png new file mode 100644 index 00000000000..c152e00044a Binary files /dev/null and b/docs/images/SetThresholdSequenceDiagram2.png differ diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png index d87c1216820..24004927aa7 100644 Binary files a/docs/images/StorageClassDiagram.png and b/docs/images/StorageClassDiagram.png differ diff --git a/docs/images/SupplierModelClassDiagram.jpg b/docs/images/SupplierModelClassDiagram.jpg new file mode 100644 index 00000000000..a4735a4656c Binary files /dev/null and b/docs/images/SupplierModelClassDiagram.jpg differ diff --git a/docs/images/TransactionModelClassDiagram.png b/docs/images/TransactionModelClassDiagram.png new file mode 100644 index 00000000000..8a3f2a2b106 Binary files /dev/null and b/docs/images/TransactionModelClassDiagram.png differ diff --git a/docs/images/UG/combination.png b/docs/images/UG/combination.png new file mode 100644 index 00000000000..ef52524cee2 Binary files /dev/null and b/docs/images/UG/combination.png differ diff --git a/docs/images/UG/find-t buy.png b/docs/images/UG/find-t buy.png new file mode 100644 index 00000000000..41ca7dd5716 Binary files /dev/null and b/docs/images/UG/find-t buy.png differ diff --git a/docs/images/UG/find-t good name.png b/docs/images/UG/find-t good name.png new file mode 100644 index 00000000000..972db12813e Binary files /dev/null and b/docs/images/UG/find-t good name.png differ diff --git a/docs/images/UG/find-t name.png b/docs/images/UG/find-t name.png new file mode 100644 index 00000000000..00099a74f71 Binary files /dev/null and b/docs/images/UG/find-t name.png differ diff --git a/docs/images/UG/help.png b/docs/images/UG/help.png new file mode 100644 index 00000000000..b59ab8e37b3 Binary files /dev/null and b/docs/images/UG/help.png differ diff --git a/docs/images/UG/list-t.png b/docs/images/UG/list-t.png new file mode 100644 index 00000000000..4c8fc8e6c1c Binary files /dev/null and b/docs/images/UG/list-t.png differ diff --git a/docs/images/UG/original.png b/docs/images/UG/original.png new file mode 100644 index 00000000000..b52c2c427b0 Binary files /dev/null and b/docs/images/UG/original.png differ diff --git a/docs/images/UG/warn.png b/docs/images/UG/warn.png new file mode 100644 index 00000000000..f6b7e51e824 Binary files /dev/null and b/docs/images/UG/warn.png differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png old mode 100644 new mode 100755 index 5bd77847aa2..f7b6421f5c4 Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png old mode 100644 new mode 100755 index 7b4b3dbea45..f7fac819e4f Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/UndoRedoState0.png b/docs/images/UndoRedoState0.png old mode 100644 new mode 100755 index 8f7538cd884..05870a619fc Binary files a/docs/images/UndoRedoState0.png and b/docs/images/UndoRedoState0.png differ diff --git a/docs/images/UndoRedoState1.png b/docs/images/UndoRedoState1.png old mode 100644 new mode 100755 index df9908d0948..5fc9f9373f7 Binary files a/docs/images/UndoRedoState1.png and b/docs/images/UndoRedoState1.png differ diff --git a/docs/images/UndoRedoState2.png b/docs/images/UndoRedoState2.png old mode 100644 new mode 100755 index 36519c1015b..4600e73574e Binary files a/docs/images/UndoRedoState2.png and b/docs/images/UndoRedoState2.png differ diff --git a/docs/images/UndoRedoState3.png b/docs/images/UndoRedoState3.png old mode 100644 new mode 100755 index 19959d01712..e3a7baaf6cf Binary files a/docs/images/UndoRedoState3.png and b/docs/images/UndoRedoState3.png differ diff --git a/docs/images/UndoRedoState4.png b/docs/images/UndoRedoState4.png old mode 100644 new mode 100755 index 4c623e4f2c5..39ba9e4ab7c Binary files a/docs/images/UndoRedoState4.png and b/docs/images/UndoRedoState4.png differ diff --git a/docs/images/UndoRedoState5.png b/docs/images/UndoRedoState5.png old mode 100644 new mode 100755 index 84ad2afa6bd..ada31b8212e Binary files a/docs/images/UndoRedoState5.png and b/docs/images/UndoRedoState5.png differ diff --git a/docs/images/UndoSequenceDiagram.png b/docs/images/UndoSequenceDiagram.png old mode 100644 new mode 100755 index 6addcd3a8d9..fe4188790ec Binary files a/docs/images/UndoSequenceDiagram.png and b/docs/images/UndoSequenceDiagram.png differ diff --git a/docs/images/VersionClassDiagram.png b/docs/images/VersionClassDiagram.png new file mode 100644 index 00000000000..1b0e5028ae8 Binary files /dev/null and b/docs/images/VersionClassDiagram.png differ diff --git a/docs/images/add-remark/$Remark.png b/docs/images/add-remark/$Remark.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/CommandInterface.png b/docs/images/add-remark/CommandInterface.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/ContextMenu.png b/docs/images/add-remark/ContextMenu.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/CreateTest.png b/docs/images/add-remark/CreateTest.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/GradleRun.png b/docs/images/add-remark/GradleRun.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/ParserInterface.png b/docs/images/add-remark/ParserInterface.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/RemarkBound.png b/docs/images/add-remark/RemarkBound.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/RemarkComplete.png b/docs/images/add-remark/RemarkComplete.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/RemarkFailureOutput.png b/docs/images/add-remark/RemarkFailureOutput.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/RemarkHello.png b/docs/images/add-remark/RemarkHello.png old mode 100644 new mode 100755 diff --git a/docs/images/add-remark/RemarkNotImplemented.png b/docs/images/add-remark/RemarkNotImplemented.png old mode 100644 new mode 100755 diff --git a/docs/images/appveyor/ci-log.png b/docs/images/appveyor/ci-log.png old mode 100644 new mode 100755 diff --git a/docs/images/appveyor/ci-pending.png b/docs/images/appveyor/ci-pending.png old mode 100644 new mode 100755 diff --git a/docs/images/build_pending.png b/docs/images/build_pending.png old mode 100644 new mode 100755 diff --git a/docs/images/checkstyle-idea-configuration.png b/docs/images/checkstyle-idea-configuration.png old mode 100644 new mode 100755 diff --git a/docs/images/checkstyle-idea-scan-scope.png b/docs/images/checkstyle-idea-scan-scope.png old mode 100644 new mode 100755 diff --git a/docs/images/chrome_save_as_pdf.png b/docs/images/chrome_save_as_pdf.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/badge_repo.png b/docs/images/coveralls/badge_repo.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/coverage_asciidoc_code.png b/docs/images/coveralls/coverage_asciidoc_code.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/coverage_report.png b/docs/images/coveralls/coverage_report.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/disable_comments.png b/docs/images/coveralls/disable_comments.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/flick_repository_switch.png b/docs/images/coveralls/flick_repository_switch.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/github_settings.png b/docs/images/coveralls/github_settings.png old mode 100644 new mode 100755 diff --git a/docs/images/coveralls/sync_repos.png b/docs/images/coveralls/sync_repos.png old mode 100644 new mode 100755 diff --git a/docs/images/damithc.jpg b/docs/images/damithc.jpg old mode 100644 new mode 100755 diff --git a/docs/images/fangshaohua94.png b/docs/images/fangshaohua94.png new file mode 100755 index 00000000000..5f0b356b0ea Binary files /dev/null and b/docs/images/fangshaohua94.png differ diff --git a/docs/images/flick_repository_switch.png b/docs/images/flick_repository_switch.png old mode 100644 new mode 100755 diff --git a/docs/images/generate_token.png b/docs/images/generate_token.png old mode 100644 new mode 100755 diff --git a/docs/images/github_repo_settings.png b/docs/images/github_repo_settings.png old mode 100644 new mode 100755 diff --git a/docs/images/grant_access.png b/docs/images/grant_access.png old mode 100644 new mode 100755 diff --git a/docs/images/lejolly.jpg b/docs/images/lejolly.jpg old mode 100644 new mode 100755 diff --git a/docs/images/liuchao93.png b/docs/images/liuchao93.png new file mode 100755 index 00000000000..40fdd58269f Binary files /dev/null and b/docs/images/liuchao93.png differ diff --git a/docs/images/m133225.jpg b/docs/images/m133225.jpg old mode 100644 new mode 100755 diff --git a/docs/images/netlify/change_site_name.png b/docs/images/netlify/change_site_name.png old mode 100644 new mode 100755 diff --git a/docs/images/netlify/grant_or_request_access.png b/docs/images/netlify/grant_or_request_access.png old mode 100644 new mode 100755 diff --git a/docs/images/netlify/netlify_details.png b/docs/images/netlify/netlify_details.png old mode 100644 new mode 100755 diff --git a/docs/images/netlify/temp_site_name.png b/docs/images/netlify/temp_site_name.png old mode 100644 new mode 100755 diff --git a/docs/images/nicholascf.png b/docs/images/nicholascf.png new file mode 100755 index 00000000000..b1c40324da4 Binary files /dev/null and b/docs/images/nicholascf.png differ diff --git a/docs/images/pangjiada.png b/docs/images/pangjiada.png new file mode 100755 index 00000000000..3c70b3535c7 Binary files /dev/null and b/docs/images/pangjiada.png differ diff --git a/docs/images/plantuml/ABeforeC.png b/docs/images/plantuml/ABeforeC.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/AllDown.png b/docs/images/plantuml/AllDown.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/ArrowLength.png b/docs/images/plantuml/ArrowLength.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/CBeforeA.png b/docs/images/plantuml/CBeforeA.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/ConfiguringGraphviz.png b/docs/images/plantuml/ConfiguringGraphviz.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/EditingDeleteSequenceDiagram.png b/docs/images/plantuml/EditingDeleteSequenceDiagram.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/HiddenArrows.png b/docs/images/plantuml/HiddenArrows.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/PackagesAndConsistency.png b/docs/images/plantuml/PackagesAndConsistency.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/RawUiDiagram.png b/docs/images/plantuml/RawUiDiagram.png old mode 100644 new mode 100755 diff --git a/docs/images/plantuml/UpAndDown.png b/docs/images/plantuml/UpAndDown.png old mode 100644 new mode 100755 diff --git a/docs/images/remove/$address.png b/docs/images/remove/$address.png old mode 100644 new mode 100755 diff --git a/docs/images/remove/SafeDeleteConflicts.png b/docs/images/remove/SafeDeleteConflicts.png old mode 100644 new mode 100755 diff --git a/docs/images/remove/UnsafeDelete.png b/docs/images/remove/UnsafeDelete.png old mode 100644 new mode 100755 diff --git a/docs/images/remove/UnsafeDeleteOnField.png b/docs/images/remove/UnsafeDeleteOnField.png old mode 100644 new mode 100755 diff --git a/docs/images/request_access.png b/docs/images/request_access.png old mode 100644 new mode 100755 diff --git a/docs/images/review_and_add.png b/docs/images/review_and_add.png old mode 100644 new mode 100755 diff --git a/docs/images/signing_in.png b/docs/images/signing_in.png old mode 100644 new mode 100755 diff --git a/docs/images/testfx-idea-accessibility-permissions.png b/docs/images/testfx-idea-accessibility-permissions.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/DebuggerStep1.png b/docs/images/tracing/DebuggerStep1.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/EditCommand.png b/docs/images/tracing/EditCommand.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/Execute.png b/docs/images/tracing/Execute.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/FindUsages.png b/docs/images/tracing/FindUsages.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/LeftGutter.png b/docs/images/tracing/LeftGutter.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/LogicSequenceDiagram.png b/docs/images/tracing/LogicSequenceDiagram.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/ShowExecutionPoint.png b/docs/images/tracing/ShowExecutionPoint.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/StepInto.png b/docs/images/tracing/StepInto.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/StepOver.png b/docs/images/tracing/StepOver.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/StructureToolWindow.png b/docs/images/tracing/StructureToolWindow.png old mode 100644 new mode 100755 diff --git a/docs/images/tracing/Variables.png b/docs/images/tracing/Variables.png old mode 100644 new mode 100755 diff --git a/docs/images/travis_add_token.png b/docs/images/travis_add_token.png old mode 100644 new mode 100755 diff --git a/docs/images/travis_build.png b/docs/images/travis_build.png old mode 100644 new mode 100755 diff --git a/docs/images/yijinl.jpg b/docs/images/yijinl.jpg old mode 100644 new mode 100755 diff --git a/docs/images/yl_coder.jpg b/docs/images/yl_coder.jpg old mode 100644 new mode 100755 diff --git a/docs/index.adoc b/docs/index.adoc index a65ae663288..ed10ce32aed 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -1,2 +1,3 @@ :stylesDir: stylesheets include::../README.adoc[] + diff --git a/docs/stylesheets/asciidoctor.css b/docs/stylesheets/asciidoctor.css old mode 100644 new mode 100755 diff --git a/docs/stylesheets/gh-pages.css b/docs/stylesheets/gh-pages.css old mode 100644 new mode 100755 diff --git a/docs/team/fangshaohua94.adoc b/docs/team/fangshaohua94.adoc new file mode 100755 index 00000000000..4423221f2d1 --- /dev/null +++ b/docs/team/fangshaohua94.adoc @@ -0,0 +1,63 @@ += Fang Shao Hua - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: InventoryManager + +--- + +== Overview + +InventoryManager is a desktop inventory manager application used for tracking quantity of goods, suppliers and transaction history. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. + +== Summary of contributions + +* *Major enhancement*: find transaction +** What it does: Filter the transaction list to find specific transactions. +** Justification: Enable user to quickly obtained information specific transactions +without spending time to scroll through large amount of data. +** Highlights: Multiple filters can be used together to enhance search range and search constraint. + +* *Major enhancement*: set warning threshold quantity for good +** What it does: Enable user to set the threshold quantity for goods in the inventory. +When a good is below its threshold quantity, it will be sorted with higher priority in the good's panel. +** Justification: This feature alert the user when a particular good is below its threshold quantity, +and remind the user to top up the good in the inventory. +** Highlights: Automatic alert due to any change in good's quantity. + +* *Minor enhancement*: establish models for good, inventory, transaction and transaction history. + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=fang&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false[Functional and Test code]] + +* *Other contributions*: +** Enhancements to existing features: +*** Updated the GUI to display 3 panels: supplier list panel, inventory panel and transaction history panel.(Pull requests https://github.com/AY1920S2-CS2103-W14-2/main/pull/63[#63], https://github.com/AY1920S2-CS2103-W14-2/main/pull/83[#83]) +** Documentation: +*** Did cosmetic tweaks to existing contents of the User Guide: https://github.com[#14] +** Community: +*** PRs reviewed (with non-trivial review comments): https://github.com/AY1920S2-CS2103-W14-2/main/pull/102[#102], https://github.com/AY1920S2-CS2103-W14-2/main/pull/103[#103] +*** Reported bugs and suggestions for other teams in the class (examples: https://github.com/AY1920S2-CS2103-W15-2/main/issues/159[1]) + + +== Contributions to the User Guide + +|=== +|_Given below are sections I contributed to the User Guide._ +|=== + +include::../UserGuide.adoc[tag=setthreshold] + +include::../UserGuide.adoc[tag=findtransaction] + +include::../UserGuide.adoc[tag=listtransaction] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide._ +|=== + +include::../DeveloperGuide.adoc[tag=findtransaction] + +include::../DeveloperGuide.adoc[tag=setthreshold] diff --git a/docs/team/johndoe.adoc b/docs/team/johndoe.adoc old mode 100644 new mode 100755 diff --git a/docs/team/liuchao93.adoc b/docs/team/liuchao93.adoc new file mode 100755 index 00000000000..a19a86af818 --- /dev/null +++ b/docs/team/liuchao93.adoc @@ -0,0 +1,61 @@ += Liu Chao - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: InventoryManager + +== Overview + +This desktop application titled “Inventory Manager” is aiming to assist store managers to manage their records of transactions +of goods 1) between managers and suppliers, and 2) between managers and customers. Managers could use this application to record +suppliers’ information and source suppliers to buy goods from. Each transaction of buying goods from suppliers or selling goods +to customers is recorded with this application. + +== Summary of contributions + +* *Major enhancement 1*: Edit Supplier +** What it does: The command allows users to edit the information of a supplier such as company name, company address, phone number, email address and good price pairs recorded in the supplier's goods list. Users could edit any field of these information and could edit multiple good price pairs at once. In addition, if the input good price pairs are not included in the original supplier's goods list, the input will be a new entry in the supplier's goods list. This provides an option for users to add new entries of price good pairs to the suppliers' goods list. +** Justification: users (store managers) need to consistently update information of suppliers in order to perform day to day tasks. In addition, users need an option to edit the information if there is error in the information. +** Highlights: AddressBook Level 3's edit function only allows users to edit the supplier's goods list by creating a fresh goods list in our project's context. For example, if a user wants to update an entry of good price pair such as for apple in a supplier's list, AddressBook Level 3's edit command will erase the whole supplier's goods list and include only the new entry of good price pair for apple. Hence, the user needs to retype all the already recorded good price pairs that are in the supplier's goods list in order to edit only the good price pair of apple. +The command of this application does not require users to retype all the good price pairs and only requires the users to type the new information for only the good price pairs they want to edit, e.g. only type command for apple. In addition, the command allows users to add new entries of good price pairs to the suppliers' goods list, unlike the edit command in AddressBook Level 3. +** Credits: The command builds on the edit command of https://github.com/nus-cs2103-AY1920S2/addressbook-level3[AddressBook Level 3] by SE Initiative. + +* *Major enhancement 2*: Delete GP from Supplier +** What it does: The command allows users to delete entries of good price pairs from a supplier goods list. Users could input multiple good names to delete multiple entries of good price pairs in one command. The command will inform users all of the goods successfully deleted and all of the goods that could not be found at the end of the command. +** Justification: Users (store managers) need to update the goods that are sold by the suppliers if the suppliers cease to sell certain goods. The difference between this command and edit command is that edit command could not take away entries of good price pairs. +** Highlights: This command's implementation is rarely difficult as it requires researching on Java stream's methods to search in set and delete entries from set by using a specific keywords. In addition, the implementation needs to tie well with undo and redo features, e.g. managing model comit well. Furthermore, multiple types of test need to be designed to prevent bugs. + +* *Major enhancement 3*: Source supplier for a good +** What it does: Users could use this command to find all existing suppliers who sell certain specific goods through the usage of keywords that are part of or all of good's name. For example, the command could find supplier selling fuji apple by just using keyword 'apple'. +Users could find multiple suppliers selling different goods by using keywords relating to those goods at one command. +** Justification: This feature is the core of the application which allows stock manager to find suppliers to buy specific goods from. +** Highlights: In order to provide the maximum convenience for the users, this command allows both using keywords instead of full names and having case insensitive keywords. This implementation is much more difficult than merely using specific full name of goods. In addition, multiple tests have to be designed to eliminate potential bugs. +** Credits: To https://github.com/nus-cs2103-AY1920S2/addressbook-level3[AddressBook Level 3] by SE Initiative for providing ways to find specific entries by keywords. + +* *Minor enhancement*: +** Add Supplier: Improvement on AddressBook Level 3's add command by implementing another class offer in the supplier object to record price and good's name. +** List Supplier: Adjusting AddressBook Level 3's list command to this application's context. +** Clear Supplier: Adjusting AddressBook Level 3's clear command to this application's context. +** Find Supplier: Adjusting AddressBook Level 3's find command to this application's context. +** Delete Supplier: Adjusting AddressBook Level 3's delete command to this application's context. + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=liuchao93&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false&tabOpen=true&tabType=authorship&tabAuthor=LiuChao93&tabRepo=AY1920S2-CS2103-W14-2%2Fmain%5Bmaster%5D[Code]] + +* *Documentation (User Guide)* +Added the user guide for the following commands: +. Adding a supplier +. Listing all suppliers +. Clearing all supplier entries +. Deleting a supplier +. Deleting an entry or entries of good-price pair(s) in the supplier’s list +. Editing a supplier +. Locating suppliers by name +. Source supplier(s) for good(s) + +* *Documentation (Developer Guide)* +** Added the developer guid for supplier feature with UMLs and design considerations in section 3.3 of the developer guide. +** The UMLs that I have added: +. Activity Diagram for Edit Supplier command (ActivityDiagramEditSupplier.jpg) +. class diagram of supplier (SupplierModelClassDiagram.jpg) +. Sequence Diagram of Edit Supplier command (SequentialDiagramEditSupplier.png) diff --git a/docs/team/nicholascf.adoc b/docs/team/nicholascf.adoc new file mode 100755 index 00000000000..e5763d5ff11 --- /dev/null +++ b/docs/team/nicholascf.adoc @@ -0,0 +1,91 @@ += Nicholas Cristian Fernando - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: InventoryManager + +== Overview + +InventoryManager is a desktop inventory manager application used for tracking quantity of goods, suppliers and +transaction history. The user interacts with it using a CLI, and it has a GUI created with JavaFX. +It is written in Java, and has about 10 kLoC. + +== Summary of contributions + +* *Major enhancement*: added the ability to undo/redo commands +** What it does: allows the user to undo a command, and redo the command after undoing it +** Justification: With an inventory of fast-moving consumer goods, there will be large amount of traffic of goods and +consequently, large number of commands that need to be inputted. This increases the probability of error in the user, +which, if irreversible, may discourage them from using the application. +** Highlights: This enhancement allows easy compatibility with future commands as the implementation is independent of +the details of the execution of command. Memory is used instead of storage to hold the previous states to avoid unwanted +cluttering by temporary files. Significant refactoring was done to avoid much of the code duplication due to the presence of +multiple databases. Interfaces are also extracted for possible future alternative implementations of versioning. +** Credits: To https://github.com/se-edu/addressbook-level4[AddressBook Level 4] by SE Initiative for describing the +general implementation idea of undo and redo + +* *Minor enhancement*: added a basic class to represent goods-price pairs + +* *Code contributed*: [https://tinyurl.com/nicholasCfCode[Code]] + +* *Other contributions*: +** Enhancement to existing features: +*** Fixed minor visual defect when application window is made significantly large (https://github.com/AY1920S2-CS2103-W14-2/main/pull/155[#155]) +*** Updated the application name and icon (https://github.com/AY1920S2-CS2103-W14-2/main/pull/150[#150]) + +** Documentation (Developer Guide): +*** Updated the section on Model for the developer guide (https://github.com/AY1920S2-CS2103-W14-2/main/pull/168[#168], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/172[#172]) +*** Rewrote the undo/redo feature section for the developer guide according to own implementation +(https://github.com/AY1920S2-CS2103-W14-2/main/pull/89[#89], https://github.com/AY1920S2-CS2103-W14-2/main/pull/111[#111], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/180[#180]) +*** Added the initial version of the developer guide (https://github.com/AY1920S2-CS2103-W14-2/main/pull/14[#14]) + +** Documentation (User Guide): +*** Added the user guide for undo and redo features (https://github.com/AY1920S2-CS2103-W14-2/main/pull/116[#116], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/183[#183]) +*** Added the initial version of the user guide (https://github.com/AY1920S2-CS2103-W14-2/main/pull/23[#23]) + +** Project management: +*** Managed releases v1.3 - v1.4 (2 releases) on GitHub + +** Team: +*** Reviewed PRs: +https://github.com/AY1920S2-CS2103-W14-2/main/pull/67[#67], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/83[#83], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/97[#97], +https://github.com/AY1920S2-CS2103-W14-2/main/pull/106[#106] + +** Tools: +*** Set up Travis and Appveyor for CI. +*** Set up Coveralls to report coverage changes for every new PR. +*** Set up branch protection rules for the master branch. + +== Contributions to User Guide + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=undoredo] + +--- + +include::../UserGuide.adoc[tag=undoredosummary] + +== Contributions to Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=model] + +--- + +include::../DeveloperGuide.adoc[tag=undoredo] + +--- + +include::../DeveloperGuide.adoc[tag=undoredousecase] diff --git a/docs/team/pangjiada.adoc b/docs/team/pangjiada.adoc new file mode 100755 index 00000000000..b7c617465a5 --- /dev/null +++ b/docs/team/pangjiada.adoc @@ -0,0 +1,113 @@ += Pang Jia Da - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: Inventory Manager + +== Overview +InventoryManager is for those who prefer to use a desktop app for managing their inventory. More importantly, InventoryManager is optimized for those who prefer to work with a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, InventoryManager can get your inventory management tasks done faster than traditional GUI apps. + +== Summary of contributions + +* *Major enhancement*: added *Buy and Sell commands* +** What it does: Allows users to `buy` and `sell` batches of goods. The commands orchestrate the +interaction between the Inventory, Supplier List, and Transaction History to +validate the input and update the model properly, or notify the user otherwise. + +** Justification: This is the main functionality of the Inventory Manager, which is +to keep stock, and manage all changes to, all goods currently in inventory. +`buy` and `sell` commands accomplish exactly that. + +** Highlights: This feature touched upon all aspects of the `Model`. It required +supplier information and inventory status to perform input validation to update +the inventory. Then it creates a new transaction history record. +*** Since the `buy` and `sell` commands are the main avenue that our program takes +input from the user, the required parameters would form the basis of other +commands, especially profit analytics and historical analysis extensions. +As such, it was a challenge to ensure that it was as extensible as possible +because it was expected to change frequently with additional commands. +*** A total of 3 extensions were needed to `buy` and `sell` commands and their related tests. + +*** As `buy` and `sell` commands needed to access all the models of persistent +storage, the development of this feature also shaped the storage design and API +of the underlying model to facilitate ease of access without violating +encapsulation principles. + +* *Minor enhancement*: Added ability to delete a good entry from inventory. + +* *Code contributed*: [https://nus-cs2103-ay1920s2.github.io/tp-dashboard/#search=pangjiada&sort=groupTitle&sortWithin=title&since=2020-02-14&timeframe=commit&mergegroup=false&groupSelect=groupByRepos&breakdown=false[RepoSense report]] + +* *Documentation*: Excerpts from my documentations is reproduced below. + +* *Other contributions*: + +** Project management: +*** Updates About Us, Contact Us, ReadMe page ( +https://github.com/AY1920S2-CS2103-W14-2/main/pull/45[#45] +) +*** Set up Appveyor CI + +** Enhancements to existing features: +*** Refactored `ModelStubs` used for easier model-related testing. + +** Community: +*** Participated in PRs reviews: +https://github.com/AY1920S2-CS2103-W14-2/main/pull/126[#126] +https://github.com/AY1920S2-CS2103-W14-2/main/pull/96[#96] +https://github.com/AY1920S2-CS2103-W14-2/main/pull/124[#124] +https://github.com/AY1920S2-CS2103-W14-2/main/pull/108[#108] +https://github.com/AY1920S2-CS2103-W14-2/main/pull/91[#91] +https://github.com/AY1920S2-CS2103-W14-2/main/pull/98[#98] +*** Reported bugs and suggestions for other teams in the class: +https://github.com/PangJiaDa/ped/issues[PE-D Issues Reported] + + +== Contributions to the User Guide + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +== User Guide: Buy Command section + +include::../UserGuide.adoc[tag=buycommand] + +== User Guide: Sell Command section + +include::../UserGuide.adoc[tag=sellcommand] + +== User Guide: Delete Good Command section + +include::../UserGuide.adoc[tag=deletegood] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +== UML Diagrams + +==== Sequence Diagrams + +include::../DeveloperGuide.adoc[tag=ArchitectureSequenceDiagram] + +include::../DeveloperGuide.adoc[tag=buysequencediagram] + +==== Class Diagrams +include::../DeveloperGuide.adoc[tag=goodclassenhancement] + +== Developer Guide: Buy and Sell Command + +include::../DeveloperGuide.adoc[tag=buyandsellcommand] + +== Developer Guide: Proposed Automatic Expiry Feature + +include::../DeveloperGuide.adoc[tag=autoexpiry] + +== PROJECT: PowerPointLabs + +--- + +_{Optionally, you may include other projects in your portfolio.}_ diff --git a/docs/templates/LICENSE b/docs/templates/LICENSE old mode 100644 new mode 100755 diff --git a/docs/templates/_footer.html.slim b/docs/templates/_footer.html.slim old mode 100644 new mode 100755 diff --git a/docs/templates/_footnotes.html.slim b/docs/templates/_footnotes.html.slim old mode 100644 new mode 100755 diff --git a/docs/templates/_header.html.slim b/docs/templates/_header.html.slim old mode 100644 new mode 100755 index 3c2d5aed43c..c596ecea643 --- a/docs/templates/_header.html.slim +++ b/docs/templates/_header.html.slim @@ -1,26 +1,4 @@ / NOTE: You must restart the gradle daemon after modifying any template file for the changes to take effect. -- if !(attr? 'no-site-header') && (attr? 'site-seedu') - #seedu-header - nav.navbar.navbar-lg.navbar-light.bg-lighter - .container - a.navbar-brand href='https://se-edu.github.io/' - img src=(site_url 'images/SeEduLogo.png') alt='SE-EDU' - ul.navbar-nav - li.nav-item - a.nav-link href='https://se-edu.github.io/addressbook-level1' AB-1 - li.nav-item - a.nav-link href='https://se-edu.github.io/addressbook-level2' AB-2 - li.nav-item - a.nav-link.active href=(site_url 'index.html') AB-3 - li.nav-item - a.nav-link href='https://se-edu.github.io/addressbook-level4' AB-4 - li.nav-item - a.nav-link href='https://se-edu.github.io/collate' Collate - li.nav-item - a.nav-link href='https://se-edu.github.io/se-book' Book - li.nav-item - a.nav-link href='https://se-edu.github.io/learningresources' Resources - - if !(attr? 'no-site-header') #site-header nav.navbar.navbar-light.bg-light @@ -32,9 +10,6 @@ =nav_link('UserGuide', 'UserGuide.html', 'User Guide') li.nav-item =nav_link('DeveloperGuide', 'DeveloperGuide.html', 'Developer Guide') - - if attr? 'site-seedu' - li.nav-item - =nav_link('LearningOutcomes', 'LearningOutcomes.html', 'LOs') li.nav-item =nav_link('AboutUs', 'AboutUs.html', 'About Us') li.nav-item diff --git a/docs/templates/_toc.html.slim b/docs/templates/_toc.html.slim old mode 100644 new mode 100755 diff --git a/docs/templates/document.html.slim b/docs/templates/document.html.slim old mode 100644 new mode 100755 diff --git a/docs/templates/helpers.rb b/docs/templates/helpers.rb old mode 100644 new mode 100755 index 7060efe223e..d1cdab5320d --- a/docs/templates/helpers.rb +++ b/docs/templates/helpers.rb @@ -45,7 +45,7 @@ module Slim::Helpers ## # Creates an HTML tag with the given name and optionally attributes. Can take - # a block that will run between the opening and closing tags. + # a block that will run between the opening and closing offers. # # @param name [#to_s] the name of the tag. # @param attributes [Hash] @@ -207,11 +207,11 @@ def html_meta_if(name, content) %() if content end - # Returns formatted style/link and script tags for header. + # Returns formatted style/link and script offers for header. def styles_and_scripts scripts = [] styles = [] - tags = [] + offers = [] stylesheet = attr :stylesheet stylesdir = attr :stylesdir, '' @@ -280,21 +280,21 @@ def styles_and_scripts styles.each do |item| if item.key?(:text) - tags << html_tag(:style, {}, item[:text]) + offers << html_tag(:style, {}, item[:text]) else - tags << html_tag(:link, rel: 'stylesheet', href: urlize(*item[:href])) + offers << html_tag(:link, rel: 'stylesheet', href: urlize(*item[:href])) end end scripts.each do |item| if item.key? :text - tags << html_tag(:script, {type: item[:type]}, item[:text]) + offers << html_tag(:script, {type: item[:type]}, item[:text]) else - tags << html_tag(:script, type: item[:type], src: urlize(*item[:src])) + offers << html_tag(:script, type: item[:type], src: urlize(*item[:src])) end end - tags.join "\n" + offers.join "\n" end end diff --git a/docs/tutorials/AddRemark.adoc b/docs/tutorials/AddRemark.adoc deleted file mode 100644 index 51044c36494..00000000000 --- a/docs/tutorials/AddRemark.adoc +++ /dev/null @@ -1,425 +0,0 @@ -= Tutorial - Adding a new Command -:toc: macro -:site-section: DeveloperGuide -:imagesDir: ../images/add-remark -:stylesDir: ../stylesheets -:xrefstyle: full -ifdef::env-github[] -:tip-caption: :bulb: -:note-caption: :information_source: -:warning-caption: :warning: -endif::[] - -toc::[] - -== Introduction - -In this tutorial, we'll walk you through the implementation of a new command -- `remark`. - -This command allows users of the AddressBook application to add optional remarks to people in their address book and edit it if required. -The command should have the format of `remark INDEX r/REMARK`. -An example of the command is `remark 2 r/Likes baseball`. - -We'll assume that you have already set up the development environment as outlined in the Developer's Guide. - -== Create a new `remark` command - -Looking in the `logic.command` package, you will notice that each existing command have their own class. -All the commands inherit from the abstract class `Command` which means that they must override `execute()`. -Each `Command` returns an instance of `CommandResult` upon success and `CommandResult#feedbackToUser` is printed to the `ResultDisplay`. - -Let's start by creating a new `RemarkCommand` class in the `src/main/java/seedu/address/logic/command` directory. - -For now, let's keep `RemarkCommand` as simple as possible and print some output. -We accomplish that by returning a `CommandResult` with an accompanying message. - -.RemarkCommand.java -[source, java] ----- -package seedu.address.logic.commands; - -import seedu.address.model.Model; - -/** - * Changes the remark of an existing person in the address book. - */ -public class RemarkCommand extends Command { - - public static final String COMMAND_WORD = "remark"; - - @Override - public CommandResult execute(Model model) { - return new CommandResult("Hello from remark"); - } -} ----- - -=== Hook `RemarkCommand` into the application - -Now that we have our `RemarkCommand` ready to be executed, we need to update `AddressBookParser#parseCommand()` to recognize the `remark` keyword. -Add the new command to the `switch` block by creating a new `case` that returns a new instance of `RemarkCommand`. - -You can refer to the changes in this link:https://github.com/nus-cs2103-AY1920S1/addressbook-level3/commit/7d04e49e364dad661cd88f462f01923fba972d2c#diff-5338391f3f6fbb4022c44add6590b74f[diff]. - -=== Run the application - -Run `Main#main` and try out your new `RemarkCommand`. -If everything went well, you should see something like this: - -.Output displayed -image::RemarkHello.png[] - -== Change `RemarkCommand` to throw an exception - -While we have successfully printed a message to `ResultDisplay`, the command does not do what it is supposed to do. -Let's change the command to throw an `CommandException` to accurately reflect that our command is still a work in progress. - -.The relationship between RemarkCommand and Command -image::CommandInterface.png[] - -Following the convention in other commands, we add relevant messages as constants and use them. - -.RemarkCommand.java -[source, java] ----- - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the remark of the person identified " - + "by the index number used in the last person listing. " - + "Existing remark will be overwritten by the input.\n" - + "Parameters: INDEX (must be a positive integer) " - + "r/ [REMARK]\n" - + "Example: " + COMMAND_WORD + " 1 " - + "r/ Likes to swim."; - - public static final String MESSAGE_NOT_IMPLEMENTED_YET = "Remark command not implemented yet"; - - @Override - public CommandResult execute(Model model) throws CommandException { - throw new CommandException(MESSAGE_NOT_IMPLEMENTED_YET); - } ----- - -== Enhancing `RemarkCommand` - -Let's change `RemarkCommand` to parse input from the user. - -=== Make the command accept parameters - -We start by modifying the constructor of `RemarkCommand` to accept an `Index` and a `String`. -While we are at it, let's change the error message to echo the values. -While this is not a replacement for tests, it is an obvious way to tell if our code is functioning as intended. - -[source, java] ----- -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -//... -public class RemarkCommand extends Command { - //... - public static final String MESSAGE_ARGUMENTS = "Index: %1$d, Remark: %2$s"; - - private final Index index; - private final String remark; - - /** - * @param index of the person in the filtered person list to edit the remark - * @param remark of the person to be updated to - */ - public RemarkCommand(Index index, String remark) { - requireAllNonNull(index, remark); - - this.index = index; - this.remark = remark; - } - @Override - public CommandResult execute(Model model) throws CommandException { - throw new CommandException(String.format(MESSAGE_ARGUMENTS, index.getOneBased(), remark)); - } - - @Override - public boolean equals(Object other) { - // short circuit if same object - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof RemarkCommand)) { - return false; - } - - // state check - RemarkCommand e = (RemarkCommand) other; - return index.equals(e.index) - && remark.equals(e.remark); - } -} ----- - -Your code should look something like link:https://github.com/nus-cs2103-AY1920S1/addressbook-level3/commit/83dd9e6b03d6b83199ceb6f3b66166483155abed#diff-34ace715a8a8d2e5a66e71289f017b47[this] after you are done. - -=== Parse user input - -Now let's move on to writing a parser that will extract the index and remark from the input provided by the user. - -Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. -The class must extend the `Parser` interface. - -.The relationship between Parser and RemarkCommandParser -image::ParserInterface.png[] - -Thankfully, `ArgumentTokenizer#tokenize()` makes it trivial to parse user input. -Let's take a look at the JavaDoc provided for the function to understand what it does. - -[source, java] -.ArgumentTokenizer.java ----- -/** - * Tokenizes an arguments string and returns an {@code ArgumentMultimap} - * object that maps prefixes to their respective argument values. Only the - * given prefixes will be recognized in the arguments string. - * - * @param argsString Arguments string of the form: - * {@code preamble value value ...} - * @param prefixes Prefixes to tokenize the arguments string with - * @return ArgumentMultimap object that maps prefixes to their - * arguments - */ ----- - -We can tell `ArgumentTokenizer#tokenize()` to look out for our new prefix `r/` and it will return us an instance of `ArgumentMultimap`. -Now let's find out what we need to do in order to obtain the Index and String that we need. -Let's look through `ArgumentMultimap` : - -[source, java] -.ArgumentMultimap.java ----- -/** - * Returns the last value of {@code prefix}. - */ -public Optional getValue(Prefix prefix) { - List values = getAllValues(prefix); - return values.isEmpty() ? Optional.empty() : - Optional.of(values.get(values.size() - 1)); -} ----- - -This appears to be what we need to get a String of the remark. -But what about the Index? Taking a quick peek at existing an `Command`... - -[source, java] -.DeleteCommandParser.java ----- -Index index = ParserUtil.parseIndex(args); -return new DeleteCommand(index); ----- - -There appears to be another utility class that obtains an `Index` from the input provided by the user. - -Now that we have the know-how to extract the data that we need from the user's input, we can create a new instance of `RemarkCommand`. - -[source, java] -.RemarkCommandParser.java ----- -public RemarkCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, - PREFIX_REMARK); - - Index index; - try { - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (IllegalValueException ive) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - RemarkCommand.MESSAGE_USAGE), ive); - } - - String remark = argMultimap.getValue(PREFIX_REMARK).orElse(""); - - return new RemarkCommand(index, remark); -} ----- - -NOTE: Don't forget to update `AddressBookParser` to use our new `RemarkCommandParser`! - -If you are stuck, check out the sample link:https://github.com/nus-cs2103-AY1920S1/addressbook-level3/commit/efdcdf0e80cec9489f7b47e3f65824f4688ad8f7#diff-fc19ecee89c3732a62fbc8c840250508[here]. - -== Add `Remark` to the model - -Now that we have all the information that we need, let's lay the groundwork for some _persistent_ changes. -We achieve that by working with the `Person` model. -Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the person's name). -That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a person. - -=== Add a new `Remark` class - -Create a new `Remark` in `seedu.address.model.person`. Since a `Remark` is a field that is similar to `Address`, we can reuse a significant bit of code. - -A copy-paste and search-replace later, you should have something like link:https://github.com/nus-cs2103-AY1920S1/addressbook-level3/commit/b7a47c50c8e5f0430d343a23d2863446b6ce9298#diff-af2f075d24dfcd333876f0fbce321f25[this]. -Note how `Remark` has no constrains and thus does not require input validation. - -=== Make use of `Remark` - -Let's change `RemarkCommand` and `RemarkCommandParser` to use the new `Remark` class instead of plain `String`. -These should be relatively simple changes. - -== Add a placeholder element for remark to the UI - -Without getting too deep into `fxml`, let's go on a 5 minute adventure to get some placeholder text to show up for each person. - -Simply add -[source, java] -.PersonCard.java -``` -@FXML -private Label remark; -``` - -to link:https://github.com/nus-cs2103-AY1920S1/addressbook-level3/commit/2758455583f0101ed918a318fc75679270843a0d#diff-0c6b6abcfac8c205e075294f25e851fe[`seedu.address.ui.PersonCard`]. -`@FXML` is an annotation that marks a private or protected field and makes it accessible to FXML. -It might sound like Greek to you right now, don't worry -- we will get back to it later. - -Then insert - -``` -