Shawn Lim's Portfolio page
Project: SalesNote
SalesNote is a desktop app for tailors, optimized for use via a Command Line Interface (CLI), suitable for fast typists. SalesNote aims to help tailors simplify their administrative tasks, with the main features split between helping to manage:
- Client Information (e.g. Contact details, measurements, notes)
- Tasks to be done
- Sales orders and accounts
Summary of Contributions
Code Contributed
Enhancements Implemented
- A fair amount of bugfixes. After the PE-D, I took care of about 16 surfaced issues, though many were admittedly small issues that were quickly resolved.
- Much of the implementation of our new classes under the Model package, and their related commands were handled by me. A quick summary here:
- The Task package, and the UniqueTaskList class
- The Order package, and the UniqueOrderList class
- Add/Delete/List/Mark Task commands
- List/Mark Order commands
- The functionality that links orders and tasks was also handled by me. This concerns the application logic that ensures orders can only be added if the appropriate client is already in SalesNote, that related orders are edited when a client is edited, and that related orders and tasks are deleted when a client is deleted.
Contributions to the UG
-
I was responsible for overall re-writing of the document, to meet the requirements of CS2101. In this process, I took care of adapting the language to more appropriately meet the requirements of cs2101 by making it more user-centric. The language now more directly addresses the user, and I fixed several formatting errors that were in the document up to that point.
-
Some specific examples of what I did to make the guide more user friendly was to include links that allowed the user to quickly return to the table of contents conveniently at sensible places. I also included many more examples of how to use commands and what behavior to expect, in addition to several images to help the user understand exactly how commands were meant to behave
-
Given that the changes are general and are all over the entire document, I thought it was easiest to provide a link to the relevant PR
Contributions to the DG
- I wrote up a few sections of the “Implementation” portion of the developer guide, to explain various design decisions made for the project.
Contributions to team-based tasks
-
Testcases is probably the thing I contributed the most to, as far as team-based tasks go. Although many of the test-cases I had to write were very straightforward extensions of existing test-cases in the system, we felt this was tedious but still necessary work. Throughout the project, I wrote around 1500 lines of test code, as can be checked in the code contributed section above.
-
I was responsible for some minor refactoring and renaming of classes as well. Eventually when we decided that we did want all types of objects to be unique for instance, I changed our TaskList and OrderList to UniqueTaskList and UniqueOrderList respectively, with the other necessary edits to their functionality.
Review/mentoring contributions
- PRs reviewed #262, #260, #249, #247, #229, #228, #122, #119, #99, #87, #74, #41, #36, #35, #34, #32, #26, #22
Contributions to the DG
Task and Order Package
Implementation
The implementation of both of these packages is largely similar to the person
package. In the original AB3, there is a
person
class, stored in a UniquePersonList
that handles list operations, further stored in a AddressBook
that handled
other utility functions like data management.
Following this structure and outline, we had a task
class, stored in a UniqueTaskList
stored in a TaskBook
, and a
order
class, stored in a UniqueOrderList
stored in a OrderBook
. Below is an updated model diagram reflecting these
changes:
Similar to the Person
class, the Task
and Order
classes have fields, as seen here:
)
These fields satisfy the following conditions:
- Both:
Date
,Label
: Nonempty block of alphanumeric characters of length at most 100 characters. We felt this was a reasonable length for both fields, and would guarantee the UI display worked the way we intended.
- Task:
TaskTag
: This is a tag that is eitherGeneral
, orSO{ID}
whereID
is theId
field of someOrder
object.isDone
: Boolean flag to indicate whether or not the task is done.
- Order:
Amount
Accepts any string that can be parsed by Double.parseDouble(), that results in a non-negative real number. Represents the amount the user charges for a givenOrder
Customer
Blocks of 1 or more alphanumeric characters, separated by at most one space. Represents thePerson
the order is addressed to.id
Long used to uniquely identifyOrder
objects. In this case, we did not deal with potential overflow given that the range of a Long in Java is up to 2^63 (which is > 10^18!). We judged that this should be more than sufficient for any realistic use of the application.isComplete
: Boolean flag to indicate when theOrder
is complete, and payment has been received.
Something alluded to in the fields above, is that there are implicit dependencies between the Task
, Order
, and Person
classes.
To add an Order
to SalesNote, we decided it made the most sense for there to already be a Person
in the application
the Order
was addressed to. So for instance, to add an order from a client named Jamie Tan
, the user would need to ensure
that a Person
with Name
Jamie Tan
existed in the application first.
Another link we thought would make sense to allow for, was to make it possible to tie a Order
object to related Task
objects.
Task
objects were meant to help users manage their work, and so we felt there should be a way for a user to relate a Task
to a specific Order
if they wanted to.
In both of these cases, we did not link the classes directly, hence there is no arrow between the Order
and Person
class
and no arrow between the Order
and Task
class in the diagram above. Instead we simply made use of the fact that SalesNote
maintains both a UniquePersonList
and a UniqueOrderList
. To relate a Order
to a Person
, it is enough to remember the
Name
field (in UniquePersonList
, two Person
objects with the same Name
are considered equal). To relate a Task
to
a Order
, we can make use of the fact that Order
objects have unique id
fields.
Design choices
A very reasonable alternative one might consider is linking the classes directly. For instance, allowing a Person
, to
have a list of Order
objects related to the Person
, and a Order
, to have a list of Task
objects related to the Order
.
This was an alternative method we considered, that would come with a cost in complexity by relating the Person
,
Task
and Order
objects. We felt that the method we chose that made use of the UniqueXList
properties and kept the
classes more distinct better adhered to the Separation of concerns and Law of Demeter principle.
Updating related fields in Person class
In implementing the fields for the Task
and Order
object and considering possible feature flaws, we decided to update
the fields for the Person
class as well. The original AB3 treated two people as equal only if their names were spelt exactly
the same, with this being case-sensitive. We decided that multiple clients having the exact same name was rare
enough that this notion of equality made sense, however, we felt it should apply regardless of case, i.e. a Person
with Name
john doe
should be recognised as the same a Person
with Name
JOHN DOE
.
We updated the equality check to account for this, and also updated the input validation for Name
to allow at most one
space between blocks of characters (previously John Doe
would be different from John Doe
. We felt this likely to be
a mistake and should be avoided).
Add Order feature
As mentioned above, to add an Order
, the Person
the Order
is addressed to should already be in SalesNote
. The
following is a sequence diagram showing the execution of the command:
Focusing on after AddOrderCommand:execute
is called,
- First the application calls
model:hasOrder(toAdd)
to check iftoAdd
is already in the model. - Next, the application calls
model:hasPersonWithName(toAdd.getCustomer.getName())
to check if thePerson
theOrder
is addressed to is already in the application - If both checks pass, the application finally calls
model:addOrder(toAdd)
to add theOrder
.
Here is an activity diagram to more clearly illustrate the logic of the application:
Result
An Order can only be added to SalesNote if the Person
it is addressed to is already in SalesNote, and the Order
is unique and does not duplicate an existing Order
object in SalesNote.