The Busyness Manager is a command-line business management application designed for small business owners to manage their inventory, sales, and revenue tracking efficiently.
- The project follows an Object-Oriented Programming (OOP) approach, with separate classes handling different aspects of business management.
- The Command Parser is responsible for processing user input and calling the appropriate methods.
- The InventoryManager manages the addition, removal, and modification of products.
- The SalesManager keeps track of product sales and revenue.
- The RevenueCalculator computes total revenue and sales reports.
- The Credentials class stores business authentication details, ensuring security.
- The BusynessManager acts as the central controller, orchestrating interactions between components.
Below is a UML Class Diagram of the Classes present in the application.

- Data Persistence: Business credentials and inventory data are stored in a text file within the
data/directory, ensuring persistence across application restarts. - Authentication: The application verifies business credentials at startup using stored authentication data.
- User Commands: The application accepts structured user input through a command-line interface, with validation for incorrect formats.
The purpose of this application was to help businesses account for their sales and revenue.
Hence, we required multiple different classes to manage various different aspects of a business owner, such as:
- Product and Inventory
- Sales
- Revenue
- An appropriate and usable UI for the business to keep track of the above factors
The inventory of each business is therefore handled by a InventoryManager class, which contains a hashmap of various key-value pairs of String ID and Product objects.
Each Product object contains various useful attributes, such as:
- String ID
- String name (of the product)
- Current stock quantity
- Quantity sold
- Price of each instance of the product
InventoryManager (IM), while holding onto these objects in a data structure, has various methods to modify and display every product that is present in the business.
To utilise these functionalities present in IM, SalesManager and SearchManager each has an instance of the same InventoryManager object. For example, SalesManager will be in charge of recording the quantity sold of each item while the SearchManager helps business owners to search and keep track of each product.
To calculate the revenue of the business (or each sales item), the RevenueCalculator class has an instance of SalesManager to calculate the revenue using the "Price" and "Quantity sold" of each Product object.
To have an appropriate and usable interface for the users, we have the UI class, that handles printing of the different output to its users, while the CommandParser class receives inputs and commands from its users.
All of these features are contained under the main BusynessManager class to provide its users a smooth experience in taking care of the different needs of businesses.
The BusynessManager class is the class with the main() method, it holds and takes care of all relevant classes to run
the program
Member Variables
Credentials credentials- Credentials of the logged in BusinessInventoryManager inventoryManager- Inventory of the logged in BusinessCommandParser commandParser- Instance of CommandParser to run commands based on user inputs
BusynessManager Class Methods
BusynessManager()- Instantiates InventoryManager and CommandParser (and other required classes)
main(String[] args)- Starting point of the program, creates and new instance of BusynessManager and calls start()
start()- Receives input of the Business Name from the user
- If Business exists in the database, calls:
- loadBusinessData(String businessName)
- login(Scanner scanner, String businessName)
- If Business does not exist in the data base, calls: (After prompt)
- firstTimeSetup(Scanner scanner)
- Calls run(Scanner scanner) if the login/setup process is successful
login(Scanner scanner, String businessName)- Allows user to proceed if the input Business ID and password matches that in the credentials,
- credentials is loaded in from loadBusinessData(String businessName)
firstTimeSetup(Scanner scanner)- Sets up a new Business(user) by extracting relevant information
- The following private methods are used within this method:
- extractID(Scanner scanner)
- extractName(Scanner scanner)
- extractPassword(Scanner scanner)
- extractBusinessType(Scanner scanner)
run(Scanner scanner)- Receives input from user and passes it to CommandParser to run the actual commands
saveBusinessData(String businessName)- Saves relevant data into a txt file present in ./data folder
- If business name is "Milk Corp", a text file names "Milk Corp.txt" is created in the data folder
- Relevant data includes:
- Business ID
- Business Name
- Password
- Business type
- Inventory (Every Product instance and relevant attributes)
- Saves relevant data into a txt file present in ./data folder
loadBusinessData(String businessName)- Loads in business data, based on the data saved by saveBusinessData(String businessName)
getBusinessDetails()- Used by CommandParser
getInventoryManager()- Used by CommandParser
Interactions with Other Components
Credentials-BusynessManagerhas an instance ofCredentialsfor authorizing loginsInventoryManager- Used to save and load data betweenInventoryManagerand data folderCommandParser- Used to execute various commands
The Product class represents an individual item in the business inventory. It contains the following attributes:
Member Variables
String id- A unique identifier for the product.String name- The name of the product.int quantity- The current quantity available for sale.int quantitySold- The number of units sold.double price- The price of each unit of the product.double revenue- The revenue earned from of each product.
Product Class Methods
Product(String name, int quantity, double price)- Constructor to initialize a new product.
getId()- Returns the product ID.
getName()- Returns the product name.
getQuantity()- Returns the available stock quantity.
getQuantitySold()- Returns the total quantity sold.
getPrice()- Returns the product price.
getRevenue()- Returns the revenue earned from the product so far.
The InventoryManager class manages all Product objects in the inventory. It maintains a HashMap where the key is
the product ID, and the value is the corresponding Product object.
Member Variables
HashMap<String, Product> inventory- Stores product details using a key-value structure.
InventoryManager Class Methods
addProduct(String name, int qty, double price)- Adds a new product to the inventory.
deleteProduct(String id)- Removes a product from the inventory.
printProducts()- Displays all products in the inventory.
updateProduct(String id, String name, int qty, double price)- Updates the details of an existing product.
-
To update attributes 1 by 1, there are also:
- updateName(String id, String name)
- updateQty(String id, int qty)
- updatePrice(String id, double price)
updateProductQuantity(String id, int qtySold)- Update attributes quantity and quantitySold of the specified product (given by the String id parameter)
resetProductSales(String id)- Resets attribute quantitySold to 0
**returnProductList()**- Returns the HashMap containing the ID and Product key-value pairs
**updateRevenue(String id, int qtySold)**- Updates revenue of Product
**getInventoryData()**- Returns a String containing the different attributes of all present Product instanes in the HashMap
**loadInventory(BufferedReader reader)**- Loads a previous saved state into an instance of InventoryManager
Interactions with Other Components
SalesManager- UsesInventoryManagerto update stock and record sales.SearchManager- UsesInventoryManagerto search for products.RevenueCalculator- Fetches product price and revenue fromInventoryManagerto calculate total revenue.CommandParser- CallsInventoryManagermethods based on user input.BusynessManager- CallsInventoryManagermethods to load and save business data.
The SalesManager class manages sales transactions, updating inventory levels and tracking quantities sold. It acts as
an intermediary between the user interface and the InventoryManager, ensuring that sales are recorded accurately and
inventory is adjusted accordingly.
Member Variables
InventoryManager inventory- Stores a reference to theInventoryManagerclass, allowing theSalesManagerto interact with the inventory data.
SalesManager Class Methods
SalesManager(InventoryManager inventory)- Constructs a
SalesManagerclass with a givenInventoryManager.
- Constructs a
recordSale(String id, int qty Sold)- Records a sale of a specified quantity of a product with the given ID.
- Private method checkIfInvalidQuantity(int qtySold), checks if the provide qtySold value is a positive value.
- Calls updateRevenue() from InventoryManager to save the updated revenue value from the sale.
clearSales(String id)- Resets the sales data for a product with the given ID.
getInventory()- Returns the
InventoryManagerclass used by theSalesManager.
- Returns the
Interactions with Other Components
InventoryManager-SalesManagerrelies on theInventoryManagerto update product quantities and reset sales data.RevenueCalculator- UsesSalesManagerto compute total sales to compute total and individual product revenue.CommandParser- CallsSalesManagerto execute sales-related commands entered by the user.
The RevenueCalculator calculates and displays revenue generated from various transactions.
Member Variables
SalesManager sm- Stores a reference to theSalesManagerclass, theSalesManagerinteracts with the inventory data and fetches/updates relevant revenue data.
RevenueCalculator Class Methods
RevenueCalculator(SalesManager sm)- Constructs a
RevenueCalculatorclass with a givenSalesManager.
- Constructs a
computeTotalRevenue()- Computes the total revenue generated from all Product instances present in InventoryManager (present in SalesManager)
computeProductRevenue(String id)- Computes the revenue generated from the specified Product instance
computeIndividualRevenue(Product product)- A private method that returns the revenue attribute of the given product.
- Used by both computeTotalRevenue() and computeProductRevenue(String id)
returnProductList()- Returns the HashMap containing ID and Product key-value pairs (taken from InventoryManager inside SalesManager)
printProductRevenue(Product product, double individualRevenue)- A private method that prints out the revenue generated from the given Product instance
Interactions with Other Components
SalesManager-RevenueCalculatorrelies on theSalesManagerto update product quantities and reset sales data.CommandParser- CallsRevenueCalculatorto execute revenue-related commands entered by the user.
The SearchManager searches for different Product instances, given the Product's name or ID.
Member Variables
InventoryManager Inventory- Stores a reference to theInventoryManagerclass, theSearchManagerinteracts with the inventory data and fetches relevant data to display to the user as a search result.
SearchManager Class Methods
SearchManager(InventoryManager inventory)- Constructs a
SalesManagerclass with a givenInventoryManager.
- Constructs a
searchByName(String name)- Searches for a Product with the given String name
searchById(String id)- Searches for a Product with the given String ID
checkForProductByName(String name, Set<Map.Entry<String, Product>> mapSet)- A private method that returns true if given String name is present in the Set.
- Used by searchByName(String name)
checkForProductById(String id, HashMap<String, Product> currentProductList)- A private method that returns true if given String ID is present in the HashMap.
- Used by searchById(String id)
Interactions with Other Components
InventoryManager-SearchManagerrelies on theInventoryManagerto search for products.CommandParser- CallsSearchManagerto execute search-related commands entered by the user.
The CommandParser class connects the main BusynessManager class with the other Manager classes, and is called when the BusynessManager class detects user input. It takes in the user input as a String, and undergoes 3 steps to execute the user input, before giving back control to the user by returning to the BusynessManager class.
The 3 steps is as follows:
- Splitting the user input String
- Executing the command
- Manipulating the information
Splitting the user input String
parseCommand()in the CommandParser class is called, taking in the user input as a String.- The user input is split into the "command" and the "information" portions.
- "command": A one-word String defines what task the user wants Busyness Manager to do,
- "information": Contains the relevant information for that task. (e.g. product ID / name / quantity / price)
- To split the user input String,
parseCommand()calls 3 sub-methods.getCommandSeparatorIndex(): Returns the index of the first space of the user input String.- The first space will be returned, as the "command" is a one-word String, which will be the first word of the user input.
splitCommand()andsplitInfo(): Returns the "command" and the "information" respectively.- Both sub-methods utilise
.substring()from Java's String class.
- Both sub-methods utilise
Executing the command
parseCommand()callsexecuteCommand(), with the "command" and the "information" as parameters.- The "command" is passed into a switch statement that determines what command method the parser should execute.
- For example, in the sequence diagram above, if the "command" is the one-word String
update, the switch statement will callupdateProduct()with the "information" as a parameter.
- For example, in the sequence diagram above, if the "command" is the one-word String
Manipulating the information
Note: from here on, it is assumed that update is the "command".
- The command method extracts the relevant attributes from the "information" String.
- This is done using
.split()from Java's String class, which outputs an array of Strings.
- This is done using
- The product name is extracted directly from the index immediately after the "command".
- However, only one-word Strings can be extracted as the product name using this method. Hence, the name of products in the program are restricted to one-word Strings. This limitation will be addressed in later versions.
- The product ID is extracted from the index immediately after the product name.
- Since the product ID needs to be of type
intand notStringfor formatting purposes, the attribute undergoes parsing to an integer type, - The product ID is then formatted to the ID format (ID_XXXX) and converted back to a String.
- Since the product ID needs to be of type
- The product quantity and price is extracted from the subsequent indexes.
- Since the product quantity and price need to be of type
intand notString, the attribute undergoes parsing to an integer type.
- Since the product quantity and price need to be of type
- When the attributes have been extracted, the command method will call its counterpart in the relevant Manager class.
- After this counterpart has finished executing, the command method will return, followed by
executeCommand()andparseCommand().
- After this counterpart has finished executing, the command method will return, followed by
- CommandParser returns to the BusynessManager class, giving input control back to the user.
Note: This concept of attribute extraction applies to most command execution methods. However, for printing of the product list and computation of total revenue, since there is no "information" required for their command methods, they will not require attribute extraction.
Member Variables
String businessID- String ID for BusinessString businessName- String ID of BusinessString businessPassword- String password of BusinessBusynessManager.BusinessType businessType- Enum inBusynessManagerthat contains the different Business types
Credentials Class Methods
- All methods in Credentials are getters for their respective attributes (Member Variables).
getBusinessID()getBusinessName()getBusinessPassword()getBusinessType()
Interactions with Other Components
BusynessManager- Used by BusynessManager to load and verify user(business) credentials during login, as well as during saving of data
Constants class is used to hold static constants used during printing of messages using UI class or Magic Literals
required during the execution of the program
Member Variables
- Contains static constants used for printing messages in the UI class
Constants Class Methods
- None
Interactions with Other Components
UIUses values from the Constants class to print output to the user- Almost all classes uses Magic Literals from this class
UI class is used to print outputs to user (Abstraction of printing output)
Member Variables
- None
UI Class Methods
- printMessageWithoutNewline(String message)
- printMessage(String message)
- printErrorMessage(String message)
- printFormattedMessage(String message, Object... args) All methods in UI Class is static (class level)
Interactions with Other Components
Constants- Constant variable from this class is used byUIfor printing- Almost all classes uses UI class for printing
- Involved in a business that sells goods (i.e. physical products).
- This business is a for-profit business.
- This business sells a variety of goods.
- This business is not a large business with a single outlet. (e.g. mini-mart / cafe)
- Prefer desktop applications over other types.
- Prefer typing over using a mouse to navigate menus.
- Has the ability to type reasonably fast and accurately.
- Is used to handling CLI applications.
Busyness Manager can manage the inventory of a business in a faster and more organised way than a typical GUI-driven application. Moreover, it is cheaper to run and maintain, compared to other inventory management applications in the market.
| Version | As a ... | I want to ... | So that I can ... |
|---|---|---|---|
| v1.0 | business owner | adapt my configuration according to my business type | manage my business based on its needs |
| v1.0 | business owner with new products to sell | add products to my database | indicate that these products are to be sold |
| v1.0 | business owner with outdated products | remove products from my database | indicate that my business is not selling these products anymore |
| v1.0 | forgetful business owner | see all my products in one list | find out what products my business sells |
| v1.0 | curious business owner | see the data of the products in my database | find out more about the performance of that product |
| v1.0 | business owner | modify the data of a product in my database | keep the information about my product up-to-date |
| v1.0 | business owner with many products | search for a product in my database | find out if that product is sold by my business |
| v1.0 | for-profit business owner | track my sales | manage my business in a profitable manner |
| v2.0 | forgetful business owner | have a list of possible commands and formats | recall what commands I can use |
| v2.0 | business owner | save my database | reuse the existing database when I restart the application |
- Should work on any mainstream OS with Java 17 installed.
- Should serve a business with up to 10,000 goods for sale.
- Should work with products with quantity below 1,000,000.
- Should work with products with price below $1,000,000.
- A user with decent typing speed for normal text should be able to complete most tasks faster through typing out commands, compared to using the mouse to navigate a GUI application.
- Business Credentials - Unique identifiers (ID, name, password) for a registered business.
- Command Parser - A component responsible for interpreting user commands and triggering appropriate actions.
- Inventory Manager - Manages stock, allowing addition, deletion, and updates of products.
- Sales Manager - Tracks product sales and ensures accurate revenue reporting.
- Revenue Calculator - Computes total revenue and generates sales reports.
- CLI (Command-Line Interface) - A text-based interface where users interact with the application.
- Mainstream OS - Windows, Linux, Unix, macOS
- Download the
.jarfile and copy into an empty folder. - Open Command Prompt on Windows / Terminal on macOS.
- Change the current working directory to the folder containing the
.jarfile. - run
java -jar <file name>.jaron Command Prompt / Terminal.
- When the program asks for the login details, do not input anything and press
Enter.- Example Input: When
Please enter your business name:is shown, pressEnterwithout inputting anything. - Output: An error message stating that no input was detected will be shown.
- Example Input: When
- When the program asks for the login details, input an incorrect set of login information.
- Example Input: When asked for the business name, input an incorrect name.
- Output: The program will provide an option to create a new business account before termination.
- Example Input: When asked for the business ID and password, input some incorrect information.
- Output: The program will provide an option to display the ID and password before termination.
- When the program requests for Credentials information (e.g. ID / Name / Password / Business Type), do not input
anything and press
Enter.- Example Input: When
Enter Business ID:is shown, pressEnterwithout inputting anything. - Output: An error message stating that no input was detected will be shown.
- Example Input: When
- When the program requests for the Business Type, input something other than FNB or RETAIL.
- Example Input:
fnb/retail/SERVICE - Output: An error message stating the Business Type is invalid will be shown.
- Example Input:
- Input the
addcommand with missing attributes.- Example Input:
add/add MILK 50/add WHITE_RICE 13.00/add 30 6.00 - Output: An error message stating that the format is incorrect will be shown.
- Example Input:
- Input the
addcommand with negative values for quantity and price.- Example Input:
add MILK -50 2.50/add EGGS 30 -6.00 - Output: An error message stating that the quantity and/or price cannot be negative will be shown.
- Example Input:
- Input the
addcommand with a non-proper value for quantity and/or price.- Example Input:
add MILK 50.4 2.50/add MILK 50 hi/add XD XD XD - Output: An error message stating that the quantity and/or price is not a proper number will be shown.
- Example Input:
- Input the
addcommand with the price as zero.- Example Input:
add MILK 50 0.00 - Output: An error message stating that the price cannot be zero will be shown.
- Example Input:
- Input the
deletecommand with missing attributes.- Example Input:
delete - Output: An error message stating that the ID is missing will be shown.
- Example Input:
- Input the
deletecommand with an invalid ID.- Example Input:
delete XD - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
deletecommand with an ID that does not exist in the product list.- Example Input:
delete 15(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:
- Input the
updatecommand with missing attributes.- Example Input:
update/update /name/update 1 /qty/update 2 /price - Output: An error message stating that the flags are invalid will be shown.
- Example Input:
- Input the
updatecommand with an invalid ID.- Example Input:
update XD /name MILK - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
updatecommand with an ID that does not exist in the product list.- Example Input:
update 15 /qty 50(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:
- Input the
updatecommand with negative values for quantity and price.- Example Input:
update 1 /qty -50 2.50/update 2 /price -6.00 - Output: An error message stating that the quantity and/or price cannot be negative will be shown.
- Example Input:
- Input the
updatecommand with a non-whole number value for quantity and/or price.- Example Input:
update 1 /qty 50.4/update 2 /price hi - Output: An error message stating that the quantity and/or price is not a proper number will be shown.
- Example Input:
- Input the
updatecommand with the price as zero.- Example Input:
update 1 /price 0.00 - Output: An error message stating that the price cannot be zero will be shown.
- Example Input:
- Input the
searchcommand with an invalid format.- Example Input:
search/search XD - Output: An error message stating that the format is incorrect will be shown.
- Example Input:
- Input the
searchcommand with missing attributes.- Example Input:
search /name/search /id - Output: An error message stating that the name or ID is missing will be shown.
- Example Input:
- Input the
searchcommand with a name that does not exist in the product list.- Example Input:
search /name BEANS - Output: An error message stating that the product with the provided name cannot be found will be shown.
- Example Input:
- Input the
searchcommand with an invalid ID.- Example Input:
search /id XD - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
searchcommand with an ID that does not exist in the product list.- Example Input:
search /id 15(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:
- Input the
soldcommand with missing attributes.- Example Input:
sold/sold 5(where 5 is the quantity) /sold 1(where 1 is the ID) - Output: An error message stating that the format is incorrect will be shown.
- Example Input:
- Input the
soldcommand with an invalid ID.- Example Input:
sold XD 5 - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
soldcommand with an ID that does not exist in the product list.- Example Input:
sold 15 5(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:
- Input the
soldcommand with a negative value for quantity.- Example Input:
sold 1 -5 - Output: An error message stating that the quantity cannot be negative will be shown.
- Example Input:
- Input the
soldcommand with a non-whole number value for quantity.- Example Input:
sold 1 5.6/sold 1 hi - Output: An error message stating that the quantity must be a whole number will be shown.
- Example Input:
- Input the
clearcommand with missing attributes.- Example Input:
clear - Output: An error message stating that there are missing attributes will be shown.
- Example Input:
- Input the
clearcommand with an invalid ID.- Example Input:
clear XD - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
clearcommand with an ID that does not exist in the product list.- Example Input:
clear 15(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:
- Input the
revenuecommand with an invalid ID.- Example Input:
revenue XD - Output: An error message stating that the ID is invalid will be shown.
- Example Input:
- Input the
revenuecommand with an ID that does not exist in the product list.- Example Input:
revenue 15(when there are 5 products in the list) - Output: An error message stating that the product with the provided ID cannot be found will be shown.
- Example Input:



