Overview
This portfolio documents my contributions towards the project I have undertaken in the course CS2103T - Software Engineering. It aims to demonstrate the theoretical and practical knowledge I have gained in the field of Software Engineering over the semester.
PROJECT: MeNUS
MeNUS is an integrated restaurant management desktop application designed for restaurant owners. It comprises five sub-management systems - 1) Menu, 2) Inventory, 3) Sales, 4) Reservation and 5) Authentication, each of which plays an indispensable role in ensuring the success of a restaurant business. They were meticulously developed to streamline the process of tracking dishes, ingredients, bookings and sales records while upholding a substantial level of security.
Summary of contributions
Given below are contributions I made for the project. They showcase my capability to |
-
Code contributed: RepoSense
-
Major enhancement: Developed and integrated a Sales Management System (SMS) into MeNUS to help restaurant owners keep track of financial records, analyse their financial performance and devise marketing strategies.
-
What it does: SMS allows owners to add, modify and remove sales records. An Auto-ingredient update mechanism is incorporated to enable automatic consumption of ingredients whenever a record is added. Also provides owners with analytical features to generate sales report, plot sales chart and rank dates/items according to profitability.
-
Justification: These features provide efficiency and effectiveness in keeping track of huge amount of financial records every day which can be extremely tedious if done via the conventional means of pen and paper. The
Auto-ingredient update mechanism
also saves restaurant managers the trouble of frequent inventory tracking which often takes up a significant amount of time and effort. Analytical features assists restaurant owners in making strategic marketing decisions, projecting business’s revenue as well as monitoring its long-term growth. These ensure the financial success of the restaurant in the long run. -
Highlights: This enhancement adds on to the limited number of key management aspects MeNUS can provide. It requires an in-depth analysis of design alternatives as well as a thorough understanding of the entire code architecture. The implementation was challenging as the
Auto-ingredient update mechanism
required the integration of the Menus, Ingredients and Sales management system. An extensive knowledge of how each management works was therefore essential. Analytical features also required substantial knowledge of front-end programming languages such as CSS and XML.
-
-
Other contributions:
-
Project Management:
-
Managed the integration and collaboration aspect of MeNUS. #147
-
Ensured loose coupling and flawless coordination between various management systems of MeNUS.
-
Maintained issue tracker and merging of pull requests (PRs).
-
Oversaw the Storage component of MeNUS and preserved its functionality throughout.
-
-
Enhancements to existing features:
-
Updated MeNUS’s Cascading Style Sheets (CSS) theme.
-
-
Quality Assurance:
-
Wrote unit and integration tests which helped improve the overall code coverage beyond 94%.
-
-
Documentation:
-
User Guide:
-
Developer Guide:
-
-
Community:
-
Contributions to the User Guide
The following sections are my contributions to the User Guide. They reflect my ability to write clear and concise documentation targeting non-technical readers. Please refer to User Guide for more of my contributions. The full version of my contribution can be found under section 5.6 and 5.7.5 - 5.7.8 of the User Guide. |
Sales Management
The following are sales-related commands to help you with financial tracking and analysis. The terms "sales record" and "record list" will be used frequently under this section so it is advisable to first understand their definition in the glossary.
Recording sales volume of an item: record-sales
or rs
Records the sales volume of an item within a specific day into the record list.
Format: record-sales d/DATE n/ITEM_NAME q/QUANTITY_SOLD p/ITEM_PRICE
or rs d/DATE n/ITEM_NAME q/QUANTITY_SOLD
p/ITEM_PRICE
Examples:
-
record-sales d/25-09-2018 n/Fried Rice q/35 p/5.50
-
rs d/25-09-2018 n/Fried Rice q/35 p/5.50
Auto-ingredient update mechanism
record-sales
also determines all the ingredients you used and automatically deducts them from the ingredient
list, subjected to the following conditions:
1) The item exists in the menu.
See Section 5.4.1, “Adding an item to the menu" for more information.
2) The required ingredients to make one unit of ITEM_NAME
is specified.
See Section 5.4.14, “Add required ingredients" for more information.
3) All required ingredients exist in the ingredient list.
See Section 5.3.1, “Adding an ingredient" for more information.
4) There are sufficient ingredients to make QUANTITY_SOLD
units of ITEM_NAME
.
See Section 5.3.6, “Stocking up an ingredient" for more information.
Sales volume will still be recorded even if some of the above conditions are not met. However, ingredient list will not be updated |
If you recorded a sales volume by mistake, you can use the |
Display sales report: display-sales
or dis
Generate and display the sales report for a specific day.
Format: display-sales DATE
or dis DATE
Examples:
-
display-sales 30-09-2018
-
dis 30-09-2018
Displays the sales report dated 30-09-2018.
The following (Figure 5.6.2.1) is an example of what you will see if the sales report is generated and displayed correctly:
Figure 5.6.2.1: Sales Report
Deleting a sales record: delete-sales
or des
Deletes the sales record identified by the index.
Format: delete-sales INDEX
or des INDEX
Deleting a sales record will not undo the effect of "Auto-ingredient update" which may or may not have happened during recording |
Examples:
-
delete-sales 2
-
des 2
Deletes the 2nd record from the record list.
Editing a sales record: edit-sales
or es
Edits the sales record identified by the index.
Format: edit-sales INDEX [d/DATE] [n/ITEM_NAME] [q/QUANTITY_SOLD] [p/ITEM_PRICE]
or es INDEX [d/DATE]
[n/ITEM_NAME] [q/QUANTITY_SOLD] [p/ITEM_PRICE]
Editing a sales record will permanently delete its "Ingredient used" data |
Editing a sales record will not update the ingredient list. See Auto-ingredient update for more information |
Examples:
-
edit-sales 3 n/Fried Omelet
-
es 3 n/Fried Omelet
Edits the item name of the 3rd record to be "Fried Omelet". -
edit-sales 7 q/37 p/6.50
-
es 7 q/37 p/6.50
Edits the quantity sold and price of the 7th record to be 37 and 6.50 respectively.
Ranking dates according to total revenue: rank-date
or rad
Ranks and displays all existing dates in the record list based on the total revenue.
Format: rank-date
or rad
You can generate the sales report of a specific date to get a more detailed analysis. See Section 5.6.2, “Display sales report" for more information |
The following (Figure 5.6.6.1) is an example of what you will see if the ranking is generated and displayed correctly:
Figure 5.6.6.1: Ranking of dates by revenue
Contributions to the Developer Guide
The following sections are my contributions to the Developer Guide. They reflect my ability to convey technical information in a comprehensible manner. It also showcases the technical depth of my contributions. Please refer to Developer Guide for more of my contributions. The full version of my contribution can be found under section 4.4, 4.5, and UC5XX of appendix A. |
Auto-ingredient update feature
The auto-ingredient update mechanism is facilitated by RecordSalesCommand
and triggers whenever the "record-sales"
command is invoked. A SalesRecord
will be instantiated based on the information given and attempts to compute
the ingredients used before deducting them from the ingredient list automatically.
Current Implementation
A SalesRecord
is associated with 6 attributes - Date
, ItemName
, QuantitySold
, Price
, Revenue
and
IngredientUsed
.
The success of the auto-ingredient update mechanism is subjected to the following conditions:
1) ItemName
exists in the Menu
.
2) The required ingredients to make one unit of ItemName
is specified in the Menu
.
3) The required ingredients exist in the Ingredient
list.
4) There are sufficient ingredients to make QuantitySold
units of ItemName
in the Ingredient
list.
If any of the above conditions are not satisfied, sales volume will be recorded without updating the ingredient list |
If conditions 1 and 2 are satisfied, RecordSalesCommand will compute all the ingredients used and store the data in
IngredientUsed attribute of SalesRecord
|
This mechanism is aided by methods from the Menu
and Ingredient
components, all of which are exposed in the
Model
interface. Given below is an example scenario and how the auto-ingredient update mechanism behaves at each step.
Step 1. The user executes record-sales d/11-01-2018 n/Fried Rice q/35 p/5.50
command to record the sales volume of
Fried Rice
on 11-01-2018
. A SalesRecord
would be instantiated based on the command arguments given.
Step 2. RecordSalesCommand
will request for the item Fried Rice
from Menu
. This is done through the Item
findItem (Name)
method given in Menu
component. This also checks if condition 1 is satisfied.
Step 3. RecordSalesCommand
then proceeds to request for the required ingredients to make a unit of Fried Rice
from Menu
. This is done through the Map<IngredientName, Integer> getRequiredIngredients(Item)
method given
in Menu
. This also checks if condition 2 is satisfied.
Step 4. With the required ingredients per unit data now at hand, RecordSalesCommand
will compute the total
ingredients used in making 35
units of Fried Rice
. The IngredientUsed
attribute in SalesRecord
will then be updated.
Step 5. RecordSalesCommand
will then pass the computed IngredientUsed
to Ingredient
component to request for
an update of ingredients. This is done through the void consumeIngredients(Map<IngredientName, Integer>)
method
given in Ingredient
component. This checks for condition 3 & 4.
Step 6. The SalesRecord
is then finally added into UniqueRecordList
via the void addRecord(SalesRecord)
method given in Sales
component of Model
.
An exception will be thrown in step 2, 3 or 5 should the conditions be violated. In such scenario,
RecordSalesCommand will jump to step 6 instantly and omit the remaining steps
|
The following activity diagram (Figure 4.4.1.1) summarizes what happens when a user executes record-sales
command:
Figure 4.4.1.1: Activity Diagram for record-sales
command
Display sales report feature
Current Implementation
The display sales report mechanism is facilitated by the Model, UI and Event components of the App. A SalesReport
class encapsulates the attributes of a sales report to be displayed.
The sales report is internally generated by generateSalesReport(Date)
in UniqueRecordList
. It then
propagates up the Model
call hierarchy to getSalesReport(Date)
in ModelManager
, which is exposed in the Model
interface.
The following sequence diagram (Figure 4.5.1.1) illustrates how the display sales report operation works when the
user enters display-sales 25-12-2017
:
Figure 4.5.1.1: Sequence Diagram for display-sales
command
The sequence diagram for the "Parse Command" reference frame above is shown below in Figure 4.5.1.2:
Figure 4.5.1.2: Sequence Diagram for "Parse Command" reference frame
Given below is an example usage scenario and how the display sales report operation behaves at each step.
Step 1. The user executes display-sales 25-12-2017
command to request for the sales report dated 25-12-2017. The
display-sales
command calls Model#getSalesReport(Date)
, passing in the date "25-12-2017", and gets the generated
SalesReport
in return.
display-sales command will not call Model#getSalesReport(Date) if the specified date is invalid
|
If no sales record associated with the given Date is found, an empty SalesReport will be
returned. In such cases, the command will terminate with a message notifying the user about the absence of such record
|
Step 2. The display-sales
command then raises the DisplaySalesReportEvent
event, which also encapsulates the
generated SalesReport
in step 1.
Step 3. The EventsCenter
reacts to the above event, which results in handleDisplaySalesReportEvent(Event)
in UI’s MainWindow
being called. This method instantiates a SalesReportWindow
object by passing in the
SalesReport
to its constructor. This SalesReportWindow
acts as the controller for the sales report window.
Step 4. The SalesReportWindow
is then initialized and displayed on user’s screen.
Design Considerations
Aspect: How SalesReport
is generated internally
-
Alternative 1 (current choice):
generateSalesReport(Date)
inUniqueRecordList
filters the entire record list. Records that match the givenDate
are added into aList<SalesRecord>
. TheSalesReport
is generated based on this list.-
Pros: Easy to implement.
-
Cons: Execution is of linear time complexity and would be considerably slow should the list size be very large.
-
-
Alternative 2: Maintain another list that sorts itself by date every time it is modified. Conduct a binary search to fill in the
List<SalesRecord>
every time a sales report is requested.-
Pros:
SalesReport
can be generated with a O(logN) time complexity. -
Cons: Sorting after every input would require O(NlogN) time which is slow. Additionally, the sorted list also takes up an O(N) memory space.
-
Use case: UC501 - Record sales volume of an item
Guarantees:
-
A new sales record of an item will be appended to the record list.
MSS
-
User requests to record sales volume of an item for a specified day.
-
App computes the ingredients used and updates the ingredient list automatically.
-
App appends the record at the end of record list.
-
App returns a success message confirming that the recording is successful.
Use case ends.
Extensions
-
1a. Invalid command format entered by the user.
-
1a1. App returns a message telling user that the command format is invalid.
-
1a2. User requests to record sales volume again.
Steps 1a1-1a2 are repeated until a valid command format is entered.
Use case resumes at step 2.
-
-
1b. The given date or name or quantity sold or price is invalid.
-
1b1. App returns a message telling user that the date or name or quantity sold or price is invalid.
-
1b2. User requests to record sales volume again.
Steps 1b1-1b2 are repeated until all fields entered by the user are valid.
Use case resumes at step 2.
-
-
1c. Sales record of the same date and item name already exists in the record list.
-
1c1. App returns a message telling user that the item’s record already exists.
-
1c2. User requests to record sales volume again.
Steps 1c1-1c2 are repeated until a record with unique date and item name is entered.
Use case resumes at step 2.
-
-
2a. One or more of the criteria to update ingredient list were not satisfied.
-
2a1. App takes note of which criteria were not satisfied, and appends a notification message after the success message.
Use case resumes at step 3.
-