- Acknowledgements
- Setting up, getting started
- Design
- Features
- Logging
- Product scope
- User Stories
- Non-Functional Requirements
- Glossary
- Instructions for manual testing
- Ensure you have Java
11and above. If you do not have the required version, you can install the Java11JDK from this link. - Fork the BinBash repository here.
- Clone the fork into your computer.
Note: It is recommended to use
IntelliJ IDEAfor the remaining steps.
If you are using IntelliJ IDEA,
- Set up the correct JDK version for IntelliJ. To do this, kindly refer to the official documentation from JetBrains here.
- Ensure that you are using JDK version 11.
- Import the project as a Gradle project.:q
- Click Open or Import in IntelliJ.
- Locate the
build.gradlefile in the repository. Select it, and click OK. - If prompted, choose to Open as Project.
- Click OK to accept the default settings.
- Wait for the import process to finish. This could take a few minutes.
- Once the importing process has completed, you should see the
Gradle Toolbarin the IDEA interface (look for the elephant icon on the right side of your screen).
- Verify that the Gradle project has been set up correctly.
- Run
seedu.binbash.BinBashand ensure you see the following output.
------------------------------------------------------------- ____ _ ____ _ | __ )(_)_ __ | __ ) __ _ ___| |__ | _ \| | '_ \| _ \ / _` / __| '_ \ | |_) | | | | | |_) | (_| \__ \ | | | |____/|_|_| |_|____/ \__,_|___/_| |_| Welcome to BinBash! ------------------------------------------------------------- ------------------------------------------------------------- Here are your metrics: Total Cost: 0.00 Total Revenue: 0.00 Net Profit: 0.00 ------------------------------------------------------------- - Click on the Gradle icon.
- Run the tests (click on
tp/Tasks/verification/test) and ensure that all tests have passed.
- Run
The Architecture Diagram given above explains the high-level design of the application. Given below is a quick overview of the main components and how they interact with each other.
BinBash serves as the entry-point of the application.
During application startup, BinBash initializes the other components and connects them with each other.
The bulk of the app's work is done by the following five components:
Ui: The UI of the App.Storage: Reads data from, and writes data to anitems.txtfile.Parser: Makes sense of the user input to return the appropriate command.Command: Executes the command requested by the user.Data: Handles the data created by the user.
The Logger component handles the logging of events, and writes logs to a logs.txt log file.
The user primarily interacts with the Ui component.
In turn, the Parser interprets the user's input and creates the appropriate Command.
The Data component then manages all data created by the user upon Command execution.
The Storage component handles the storage and loading of saved user data.
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command list.
BinBashinvokesUi'sreadUserCommand()method to read in the user input, which in this case is alistcommand.Uireturns thelistcommand as auserInputString.BinBashpasses the String toParserthrough the methodparseCommand('list').Parserreturns a newCommandobject. (In this specific case, it would be aListCommandobject)BinBashcalls theexecute()method ofCommand.Commandthen interacts withItemList, and calls the relevant method.ItemListreturns theexecutionUiOutput, in the form of a String object.BinBashcalls thegetExecutionUiOutput()method inCommand.Commandreturns theoutputString, in the form of a String object.BinBashcalls thetalk()method inUi, and passes theoutputString.Uiprints thisoutputStringto the user.- If the
Commandexecuted modifies the database,BinBashwill call thesaveToStorage()method ofStorage
API: Ui.java
The UI component
- loops over user inputs until a non-empty input to pass to
Main - keeps track of a boolean variable that is false if and only if
ByeCommandorUserInterruptExceptionis received - depends on the
Parserhaving set all command option descriptions inCommandOptionAdder - completes commands based on command and option descriptions in
CommandCompleter
This is enabled by the externally provided Java JLine library. Namely, it makes use of the LineReader object and extends an AggregateCompleter to read and complete user inputs respectively.
The Storage class is responsible for managing storage operations for the BinBash application. It performs critical
functions such as loading and saving item data, handling corrupted files, and maintaining the integrity of the
application's persistent data.
- Loading Data: The
loadData()method reads fromitems.txtand constructs a list ofItemobjects. - Saving Data: The
saveToStorage(List<Item> itemList)method writes the current state ofItemobjects toitems.txt. - Corruption Handling: If data corruption is detected,
handleCorruptedFile()attempts to recover by renaming the corrupted file and creating a new one. - Data Parsing: The class contains methods for parsing data from and to the storage format, specifically
parseLinesToItemList(ArrayList<String>)andgenerateStorageRepresentationOfSingleItem(Item).
API: Parser.java
The Parser component
- delegates parsing to an appropriate command parser based on the first word found
- provides common methods for sub-parsers to parse their option values
- rethrows
ParseExceptionfrom sub-parsers asInvalidCommandExceptionwith appropriate error messages
The Parser utilizes parsing functionalities provided by the Apache Commons CLI library.
In particular, the XYZCommandParser classes (e.g., AddCommandParser, DeleteCommandParser) extend the DefaultParser class provided by the library,
where input-parsing tasks are delegated to the methods provided by the library.
For instance, the Options class handles command-specific flags, and in turn, parsed user arguments are retrieved from the CommandLine class.
Below shows the sequence diagram of a Parser parsing user input, to return the corresponding Command.
Here, it is assumed that the user has already provided their input to the Ui.
Then, BinBash retrieves this input and passes it to Parser.
The Parser will then process the user input to determine the type of command to be created.
From here, Parser will self-call its corresponding parseXYZCommand() method.
Upon calling parseXYZCommand(), the parse() method of an internal XYZCommandParser is invoked, to create the appropriate Command (an XYZCommand in this case).
In some instances, if the command that needs to be created is simple enough (e.g., a
ByeCommand), thenParserwill directly create theCommandwithout the need of anXYZCommandParser.
The XYZCommand is then subsequently returned back to BinBash for code execution.
The command classes within the seedu.binbash.command package form the command pattern that encapsulates all user
commands. Each command represents a single operation or action that can be performed by the BinBash application.
Commandis an abstract class that serves as a template for all other command classes.- It declares the method
execute(ItemList itemList)that must be implemented by all subclasses to carry out the command-specific logic. - It provides common fields such as
itemList,commandLogger,executionUiOutput, andhasToSavewhich facilitate logging, output generation, and indicating if the application state needs to be saved post-execution.
AddCommand: Handles the addition of new items to the inventory.ByeCommand: Signals the application to shut down.DeleteCommand: Removes items from the inventory by index or name.ListCommand: Lists all items currently in the inventory.ProfitCommand: Calculates and displays the total profit.RestockCommand: Adds stock to an existing item in the inventory.SearchCommand: Searches for items in the inventory based on specified criteria.SellCommand: Records the sale of items and adjusts the inventory accordingly.UpdateCommand: Updates the details of an existing item in the inventory.
BinBashmain class receives user input.Parserinterprets the input and creates an instance of the appropriateCommandsubclass.- The
executemethod of the createdCommandobject is called byBinBash. - If
hasToSaveis true post-execution,BinBashtriggers theStorageclass to save the current state.
The Data component is responsible for the management of user data during application runtime.
At its core, an ItemList will store, and operate on different types of Item.
The operations that are done on Item are dictated by their associated Command.
For instance, the execution of AddCommand will entail the creation and storage of a new Item object in ItemList.
If SearchCommand is executed to search through the ItemList, the search task will be delegated to the SearchAssistant.
Within this component, there are also multiple types of Item that can be created, stored and modified.
The four primary types of Item are RetailItem, OperationalItem, PerishableRetailItem, and PerishableOperationalItem.
API: AddCommand.java
The add command adds an Item to the ItemList object. A formatted executionUiOutput message which states the name, description,
quantity, expiration date, sale price, and cost price entered for the newly created item, will also be printed out upon successful
command execution.
When the execute() method from AddCommand class is called, the addItem() method is called in turn. A new Item object
will firstly be created based off the user's input. For instance, the user can choose to create a RetailItem, PerishableRetailItem,
OperationalItem or PerishableOperationalItem, depending on their needs. This new Item object is then added to the
ItemList, and the formatted executionUiOutput will be returned to the AddCommand.
BinBash will then retrieve the executionUiOutput from the AddCommand, and call the Ui class to print out this
message using the talk() method.
Separation of Concerns is applied to ensure the Ui is only responsible for printing the messages to output, while the
ItemList class deals with the logic of creating and adding an item to the list. This implementation also encapsulates the details
of adding an item and displaying messages. This way, only classes relevant to the logic of adding an item will have
access to ItemList.
API: ListCommand.java
The ListCommand class is designed to handle the operation of listing all items in the inventory. When the execute()
method is called, it retrieves the complete list of items from the ItemList
and assigns it to executionUiOutput.
A sorting functionality is implemented within the list command. Depending on which flag is set, the list of
Items retrieved will be sorted in a certain order based on the specified flags.
listretrieves the list ofItemwithout sorting.list -cretrieves the list ofItemsorted based onitemCostPricevalue.list -eretrieves the list ofItemsorted based onitemExpirationDatevalue. Only items of thePerishableOperationlItemandPerishableRetailItemclasses are retrieved.list -pretrieves the list ofItemsorted based ontotaRevenue - totalCostvalue. Only items with of theRetailItemclass are retrieved.list -sretrieves the list ofItemsorted based onitemSalePricevalue. Only items of theRetailItemclass are retrieved.
The ListCommand has two constructors, ListCommand() and ListCommand(SortOptionEnum), the former is used when no sorting
is specified, the latter is used when the list is to be sorted where SortOptionEnum will be the type of sorting used.
The ListCommand() constructor will set the sortOption variable to SortOptionEnum.NONE while the ListCommand(SortOptionEnum)
will set sortOption based on the SortOptionEnum value passed into hte constructor.
The enum SortOptionEnum contains four values NONE, EXPIRY, SALE, COST, PROFIT
NONEList not to be sortedEXPIRYList sorted based onitemExpirationDatevalue.SALEList sorted based onitemSalePricevalue.COSTList sorted based onitemSalePricevalue.PROFITList sorted based ontotaRevenue - totalCostvalue.
When the execute(ItemList) method is called, it first retrieves a List from the ItemList object passed that will
contain all Item objects in the inventory. The execution will then defer depending on the sortOption value, which
can be referenced in the sequence diagram provided above.
To ensure that the index of items in the printed list can be used as ITEM_INDEX values for the update, delete,
sell and restock commands, an ArrayList<Integer> called sortedOrder will be used to map the indexes of the
items printed to their indexes in itemList. sortedOrder will be updated on startup, adding of items, deleting of
items, and listing of items to ensure that the mapping is always accurate when it is referenced.
The ListCommand is concerned only with the execution of the listing operation. It follows a straightforward process that relies on the ItemList to format the list of items, ensuring separation of concerns between command execution and UI presentation.
API: SellCommand.java
The sell command allows users to decrement the quantity of their item as they are being sold off. This is done by
specifying wither the name or index to identify the item they want to sell, as well as the quantity that they want
to sell.
The constructor of the SellCommand class is overloaded and its behavior differs based on what identifier is
entered. The two constructors are as follows:
SellCommand(int index): This constructor is used if the identifier is anint. TheisIndexvariable will be set to true, which indicates that an item should be identified by matching itsindexbefore updating its data.SellCommand(String itemName): This constructor is used if the identifier is aString. TheisIndexvariable will remain false, which indicates that an item should be removed by matching itsitemName.
When the execute() method from the SellCommand class is called, it first checks whether the update identifier is
an index of type int or a name of type String with the isIndex attribute. It will then call the
sellOrRestockItem() of the ItemList class. This method is also overloaded to take in either an index of type
int or a name of type String.
The sellOrRestockItem() method then calls the sellOrRestock() helper method, which either increments or decrements
the item quantity, depending on what command is supplied to it. The method checks whether a valid quantity is supplied
before applying the decrement in the event that the supplied command is sell. This means that users will not be able
to sell more than the current quantity. These methods return a String to update users of the successful operation and
display the new data of the item.
Upon completion of the update operation, the execute() method sets the hasToSave flag to true,
signaling the need to persist changes to storage.
API: RestockCommand.java
The restock command allows users to increment the quantity of their item as they are being restocked. This is done by
specifying wither the name or index to identify the item they want to restock, as well as the quantity that they
to restock by.
The implementation of the restock feature as well as the RestockCommand class is identical to the sell feature and
calls the same methods from the ItemList class to perform the restocking operations.
API: UpdateCommand.java
The update command allows users to modify the details of an item in the inventory. Users can update the item's,
description, quantity, cost price, sale price, expiry date, and threshold by specifying the corresponding flags.
The constructor of the UpdateCommand class is overloaded and its behavior differs based on what identifier is
entered. The two constructors are as follows:
UpdateCommand(int index): This constructor is used if the identifier is anint. TheisIndexvariable will be set to true, which indicates that an item should be identified by matching itsindexbefore updating its data.UpdateCommand(String itemName): This constructor is used if the identifier is aString. TheisIndexvariable will remain false, which indicates that an item should be removed by matching itsitemName.
When the execute() method from the UpdateCommand class is called, it first checks whether the update identifier is
an index of type int or a name of type String with the isIndex attribute.
- If it is an index, it calls the
updateItemDataByIndexmethod from theItemListclass. - If it is a name, it calls the
updateItemDataByNamemethod instead.
These methods in the ItemList class then call the updateItemData helper method, which applies the updates to the
specified item. The updateItemData method checks whether each attribute has a new value and updates the attribute
if necessary by calling the respective setters. For perishable items, it ensures that the expiry date is only updated
if the item is a PerishableOperationalItem or a PerishableRetailItem.
Upon completion of the update operation, the execute() method sets the hasToSave flag to true,
signaling the need to persist changes to storage.
Similar to other commands, the UpdateCommand class is designed to encapsulate the update operation, ensuring a clear
separation of concerns. It handles the update logic internally and interacts with the ItemList class without revealing
the details of the item's data structure. This modular approach streamlines the roles of the Parser and BinBash
(main) components, which do not need to be concerned with the details of the update operation, thus adhering to the
principles of high cohesion and low coupling.
The incorporation of a helper method updateItemData in the ItemList class enhances code reusability and
maintainability by centralizing the logic for updating item attributes. This method can be readily adjusted or expanded
to include new attributes or validation rules in the future.
API: DeleteCommand.java
The delete command deletes an object of the Item class or any of its subclasses from the inventory list and
prints a formatted message stating the details of the items that was deleted.
The constructor of the DeleteCommand class is overloaded and its behavior differs based on what search parameter is
entered. The possible constructors are:
DeleteCommand(int index): This constructor is used if the search parameter is anInteger. TheisIndexvariable will be set to true, which indicates that an item should be removed by matching itsindex.DeleteCommand(String keyword): This constructor is used if the search parameter is aString. Conversely, theisIndexvariable will be set to false, which indicates that an item should be removed by matching itsname. Note that the keyword specified is case-sensitive
When the execute() method from DeleteCommand class is called, it first checks whether the search parameter entered
is an Integer or a String using the isIndex variable. Once the search parameter is checked, it calls the
deleteItem method of the ItemList object passed as a parameter to the execute() method.
Similar to the DeleteCommand constructor, the deleteItem method of the ItemList class has different behaviors
based on the data type of the parameter passed. The implementation is done by overloading the deleteItem method and
having one deleteItem method take in an Integer and another taking in a String.
- If the parameter is an
Integer, thedeleteItem(int index)method will call theremovemethod of theArrayListclass to remove the item from the inventory list. - If the parameter is a
String, thedeleteItem(String keyword)method will run aforloop to iterate through theArrayListuntil it finds aItemobject whose nameequalsto that of the search parameter. If anItemobject has matching names with the search parameter, it will store the index in thetargetIndexvariable. ThisdeleteItem(String keyword)method will then call anotherdeleteItem(int index)method, but this time, the parameter passed is an integer. The execution after this will be exactly the same as passing anIntegerto thedeleteItem(int index)method mentions above.
Furthermore, the deleteItem(int index) method will be accessing a ArrayList<Integer> called sortedOrder which contains
the index mapping between the Item objects stored in itemList and the index of Item printed to the user. This
functionality is implemented to ensure that the indexes of the sorted list shown to the user can be used as references
for the deletion of items using ITME_INDEX.
Example:
- For itemList = {item1, item2, item3, item4}
- If sortedList = {item2, item4, item1, item3}
- then sortedOrder = {1, 3, 0, 2}
Upon completion of either operation, the execute() method sets the hasToSave flag to true, signaling the need to persist changes to storage. This entire process is logged at various levels, providing a trail for audit and debugging purposes.
The design of DeleteCommand is such that it encapsulates the delete operation, separating concerns by handling the logic of deletion internally and interacting with ItemList without exposing the details of the list's data structure. This modular approach simplifies the responsibilities of the Parser and BinBash (main) components, which do not need to understand the internals of the delete operation, thereby adhering to the principles of high cohesion and low coupling.
Additionally, the decision to use two constructors promotes the Single Responsibility Principle, as each constructor's logic is tailored to the type of deletion it handles.
The search command calls on methods in the SearchAssistant class to perform queries.
Each method searches through a corresponding field. If the argument to this method is found to be a certain default value (MIN/MAX values for numerical arguments and empty strings for string arguments), searching through this field is skipped.
Note that search relies on the SearchAssistant having the full item list to produce correct results. This is guaranteed in this case by ItemList's setFoundItems() call.
After obtaining the list of found items, it then uses printList to convert this list into a user-friendly string.
Logging plays a crucial role in providing insights into the runtime behavior of the application and diagnosing issues. In this project, we utilize the java.util.logging package for comprehensive logging functionality.
The BinBashLogger class serves as the central component for managing all logging-related operations within the application. It encapsulates the functionality provided by the java.util.logging package, offering a streamlined interface for logging operations.
To integrate logging into a class, developers can obtain a Logger instance by constructing a BinBashLogger object and assigning it as a class-level variable. This allows for consistent and centralized logging across the entire codebase.
By default, log messages are directed to a logs.txt file located in the /logs/ directory. This structured approach ensures that log data is organized and easily accessible for analysis and troubleshooting purposes.
In cases where issues arise with the logs.txt file and no logs are being written, warning logs are automatically redirected to the console for immediate visibility. This fallback mechanism ensures that critical information is not lost and allows developers to promptly address any logging-related issues.
Overall, effective logging implementation enhances the maintainability, reliability, and diagnosability of the application, facilitating smooth operation and efficient issue resolution.
- Retail Shop Owners: Individuals who operate retail businesses and require efficient inventory management solutions.
- Preference for Desktop Apps: Users who prefer desktop applications over other software types due to reliability and familiarity.
- Proficient Typists: Individuals who can type quickly and accurately, facilitating efficient interaction with the application.
- Preference for Typing: Users who prefer typing to mouse interactions for increased speed and productivity.
- Comfortable with CLI Apps: Users who are reasonably comfortable using command-line interfaces (CLI) for software interaction.
- Efficient Inventory Management: Our solution enables retail shop owners to manage their inventory more efficiently compared to manual methods and traditional GUI-driven apps, reducing time and errors.
- Cross-Platform Portability: Our application runs seamlessly on various operating systems such as Windows, Linux, and macOS, providing flexibility and accessibility across different platforms.
- Lightweight and Resource-Efficient: Designed to be lightweight, our application requires only entry-level hardware to operate efficiently, ensuring minimal system resource usage and optimal performance.
| Version | As a ... | I want to ... | So that I can ... |
|---|---|---|---|
| v1.0 | shop owner | add new items to my inventory | track them in the application |
| v1.0 | shop owner | delete items from my inventory | remove items that I no longer sell, and keep the inventory list current |
| v1.0 | shop owner | search for items in my inventory by name | find these items quickly |
| v1.0 | shop owner | see a list of all my items | get a better understanding of my current inventory status |
| v1.0 | shop owner | record the cost and sale prices of items | track my investment and calculate profit margins |
| v1.0 | shop owner | receive visible feedback when I execute commands | know whether my command was executed successfully or not |
| v1.0 | shop owner | save my inventory list to my local storage | exit the program without loss of data, and continue working on it at a later time |
| v2.0 | shop owner | update the quantity of existing items when I restock | ensure that inventory levels are accurate |
| v2.0 | shop owner | reduce the quantity of items when they are sold | keep my inventory levels updated |
| v2.0 | shop owner | categorize items in my inventory by type | organize my stock better, and know which item is which |
| v2.0 | shop owner | view my overall lifetime profit margins | analyze my sales volumes and know if I am profiting or incurring a loss |
| v2.0 | shop owner | set a minimum stock level for items | be alerted when stock is low |
| v2.0 | shop owner | receive notifications when an item's stock level falls below its minimum | restock in time |
| v2.0 | shop owner | have ease of command input (autocompletion, view command history etc.) | quickly and efficiently type in my commands |
| v2.0 | shop owner | search through my inventory using more fields and search terms | effectively review the items in my inventory, using more specific search terms |
| v3.0+ | shop owner | access inventory reports | analyze stock levels over time |
| v3.0+ | shop owner | view the history of stock adjustments for an item | track its sales and restocking events |
| v3.0+ | shop owner | see which items are most frequently restocked or sold | identify popular products |
-
Command Auto-Suggestion: The application shall provide auto-suggestions for commands as users type, enhancing the command entry process and speeding up user interaction.
-
Out-of-Order Command Entry: Users shall be allowed to enter commands out-of-order, while still ensuring that all required arguments are provided. This flexibility in command entry improves user experience and accommodates different usage patterns.
-
Offline Functionality: The application shall seamlessly function offline without any dependency on external services or internet connectivity. Users can continue to use all core features and functionalities even when disconnected from the internet, ensuring uninterrupted operation and productivity.
-
Desktop Application: A software program designed to run on a personal computer or workstation, providing functionality and features tailored to desktop computing environments.
-
CLI (Command-Line Interface): A text-based user interface used to interact with software applications by entering commands into a terminal or command prompt.
-
Cross-Platform Compatibility: The ability of software applications to run seamlessly on multiple operating systems without requiring modification or adaptation.
-
GUI (Graphical User Interface): A visual interface that allows users to interact with software applications using graphical elements such as windows, icons, buttons, and menus.
-
Portability: The ability of software applications to be easily transferred and deployed across different computing environments or platforms.
-
Command Interpretation: The process of analyzing user input to identify and execute corresponding commands or actions within a software application.
-
Error Handling: The mechanism employed by software applications to detect, report, and manage errors or exceptional conditions that may arise during execution.
-
Logging: The practice of recording events, actions, or messages generated by software applications for debugging, monitoring, and auditing purposes.
-
Integration: The process of combining or linking different software systems, components, or functionalities to work together seamlessly.
-
Modularity: The design principle that advocates breaking down software systems into smaller, independent components or modules that can be developed, tested, and maintained separately.
Testers are encouraged to do more exploratory testing with the following commands. Testers can also directly read/write data and log files for testing.
- Launch:
- Instructions for Launching:
- Download the jar file and place it in an accessible location.
- Double-click the jar file to execute it.
- Expected Output:
------------------------------------------------------------- ____ _ ____ _ | __ )(_)_ __ | __ ) __ _ ___| |__ | _ \| | '_ \| _ \ / _` / __| '_ \ | |_) | | | | | |_) | (_| \__ \ | | | |____/|_|_| |_|____/ \__,_|___/_| |_| Welcome to BinBash! ------------------------------------------------------------- ------------------------------------------------------------- Here are your metrics: Total Cost: 0.00 Total Revenue: 0.00 Net Profit: 0.00 -------------------------------------------------------------
- Instructions for Launching:
- To exit the application, enter
byeinto the input.
- From an empty text interface, press
TAB. This should present you with a list of commands and descriptions. - Start typing, this list should filter based on every matching letter you type.
- Pressing
TABshould cycle through all matching commands. - Within each command, typing
-followed byTABshould present you with a list of options. Expected: no option in this list should be an already specified option. That is, when you've already typed-cin the same line, the list should not recommend the-coption again.
- Enter this command to create a new
RetailItem:
add -re -n New Retail Item -d A new retail item. -s 10.00 -c 5.00 - Expected Output:
------------------------------------------------------------- Noted! I have added the following item into your inventory: [R] New Retail Item description: A new retail item. quantity: 0 cost price: $5.00 sale price: $10.00 threshold: 1 ------------------------------------------------------------- - Exit the application using
bye. - Open
data/items.txtand ensure the newly added item can be found.
- Enter this command to create a new
OperationalItem:
add -op -n New Operational Item -d Item to be deleted. -c 5.00 - Expected Output:
------------------------------------------------------------- Noted! I have added the following item into your inventory: [O] New Operational Item description: Item to be deleted. quantity: 0 cost price: $5.00 ------------------------------------------------------------- - List out the items using
list. Ensure that the newly added item can be found. - Enter this command to delete the item:
delete New Operational Item - List out the items using
list. Ensure that the item can no longer be found. - Open
data/items.txtand ensure the deleted item does not exist in this file.
- Invalid range searches
- Prerequisite: inventory with pre-populated item list.
- Test case 1:
search -q -2..10Expected: No results found. Error message "quantity lower bound cannot be negative" shown. - Test case 2:
search -s 5.50..4.15Expected: No results found. Error message "sale price lower bound is more than upper bound" shown. - Test case 3:
search -e ..04-13-2024Expected: No results found. Error message "expiry date upper bound is invalid. Required format: dd-mm-yyyy" shown.
- Case insensitive name and description searches
- Prerequisite: inventory with pre-populated item list.
- Test case 1:
search -n itemfollowed bysearch -n IteMExpected: Both searches give same results. - Test case 2:
search -d used in warehousefollowed bysearch -d uSed iN WAreHOuSeExpected: Both searches give same results.
- Enter this command to create a new
RetailItem:
add -re -n New Retail Item -d Retail Item to be updated. -s 10.00 -c 5.00 - Expected Output:
------------------------------------------------------------- Noted! I have added the following item into your inventory: [R] New Retail Item description: A new retail item. quantity: 0 cost price: $5.00 sale price: $10.00 threshold: 1 ------------------------------------------------------------- - Enter this command to increase the quantity (restock) of the item:
restock -n New Retail Item -q 15 - List out the items using
list. Ensure that the quantity of the newly restocked item has changed to15. - Enter this command to reduce the quantity (sell) of the item:
sell -n New Retail Item -q 5 - List out the items using
list. Ensure that the quantity of the newly sold item has changed to10.

















