Project: FitBiz


Overview

FitBiz is a fitness business management application, specially created for fitness coaches to manage their clients. It is a platform where coaches can store his clients' information, exercises done and weekly training schedule. FitBiz is primarily a desktop application where the user interacts with the program via the Command Line Interface (CLI), and views data via the Graphical User Interface (GUI). This project is written in Java 11, packaged using Gradle, and uses JavaFX for the GUI.

Summary of contributions

  • Major enhancement: added the filter feature which allows user to filter and display the clients list using client’s Tag and Sport

    • What it does: Allows user to filter through his list of clients using Tag or Sport keywords and return clients that have Tag or Sport matching all of the keywords specified.

    • Justification: Allows user to group and view clients based on their Tag or the Sport they play, which is a convenient way of looking at similar groups of client when planning exercises or scheduling clients with similar needs to train as a group. This increases the efficiency of viewing clients from a long list based on their attributes and to find clients' INDEX to view their information.

    • Highlights: Provides a simple yet important way of grouping and viewing clients from the list. The implementation was done in such a way that makes it easy to expand to filter all attributes of clients allowing user to make training plans more robust. Future expansion plan includes the abilities to filter clients by ranges of their current and target weight to group those with similar needs and filter by address to allow user to schedule clients living near each other on the same day.

  • Major enhancement: helped to build the foundation of schedule feature

    • What it does: Allows user to add and view the training schedule of clients

    • Justification: Users will be able to add, store and view clients schedule and therefore eliminating the need to use another application for the same purpose. This increases the efficiency of users while planning for clients' trainings as the schedule, exercise history and information can all be viewed in the same page.

    • Highlights: We have essentially created a mini version of a calendar app that is simple yet maintain the important functionalities to add training schedules and display them in a weekly view. Many real life conditions for the training schedule added such as overlapping training time, whether to allow backlogging of training dates and clients having same training time have been resolved through multiple trials and discussions.

  • Minor enhancement: added Sport attribute to Client

  • Code contributed: [RepoSense]

  • Other contributions:

    • Enhancements to existing features:

      • Wrote test code for classes regarding filter to improve test coverage (Pull request #231)

      • Wrote test codes for Sport attribute and part of Schedule classes to improve test coverage (Pull request #46, #62, #141)

    • Documentation:

      • Wrote the command guide for add-c and filter-c in User Guide (Pull request #260, #273)

      • Wrote the implementation of filter-c and view-c in Developer Guide (Pull request #248, #272)

      • Edited Logic to reflect the implementation of FitBiz in Developer Guide (Pull request #248)

    • Community:

      • Reported bugs and suggestions for other teams in the class that were resolved or implemented (1, 2, 3)

Contributions to the User Guide

Given below are the sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Add a new client profile: add-c --- Toh Ker Wei

After setting up the program, the first thing you might want to do is to add your client to FitBiz. You can do so by using the add-c command, followed by the details of your client.

Format: add-c n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [g/GENDER] [b/BIRTHDAY] [h/HEIGHT] [cw/CURRENT_WEIGHT] [tw/TARGET_WEIGHT] [r/REMARK] [s/SPORT]… [t/TAG]…

Parameters

This section summarises the format and important information to note while using the add-c command.

Parameters Important points to note

n/NAME

* Substitute NAME with the name of the client.

* NAME should only contain alphanumeric characters, spaces and commas, and it should not be blank.

* NAME is compulsory.

p/PHONE

* Substitute PHONE with the phone number of the client.

* PHONE should only contain numbers.

* PHONE should be at least 3 digits long.

* PHONE is compulsory.

e/EMAIL

* Substitute EMAIL with the email of the client.

* EMAIL should be of the format xxx@yyy, where:

* xxx should only contain alphanumeric characters and the set of special characters* shown below this table

* yyy must be at least 2 characters long, start and end with alphanumeric characters, and consist of alphanumeric characters, a period or a hyphen for the characters in between, if any.

* EMAIL is compulsory.

a/ADDRESS

* Substitute ADDRESS as the address of the client.

* ADDRESS can take any value, but it should not be blank, or start with a whitespace.

* ADDRESS is compulsory.

[g/GENDER]

* Substitue GENDER with the gender of the client.

* GENDER is case insensitive

* GENDER can only be male or m, female or f, or others or o.

* GENDER is optional.

[b/BIRTHDAY]

* Substitue BIRTHDAY with the birthday of the client.

* BIRTHDAY should be in the format DD-MM-YYYY

* BIRTHDAY cannot exceed the current date.

* BIRTHDAY cannot be earlier than 120 years from the current year.

* BIRTHDAY is optional.

[cw/CURRENT_WEIGHT]

* Substitute CURRENT_WEIGHT with the current weight of the client.

* CURRENT_WEIGHT must take the value of a whole or decimal number(eg. 65 or 86.22)

* CURRENT_WEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* CURRENT_WEIGHT is optional.

[tw/TARGET_WEIGHT]

* Substitute TARGET_WEIGHT with the target weight for the client.

* TARGET_WEIGHT must take the value of a whole or decimal number(eg. 65 or 86.22)

* TARGET_WEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* TARGET_WEIGHT is optional.

[h/HEIGHT]

* Substitue HEIGHT with the height of the client.

* HEIGHT must either be a whole or decimal number.

* HEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* HEIGHT is optional.

[s/SPORT]

* Substitute SPORT with the sports of the client.

* SPORT should only contain alphanumeric characters and spaces.

* Sports given in this command will overwrite all of the client’s existing sports.

* SPORT is optional.

[t/TAG]

* Substitue TAG with a tag for the client.

* TAG should only contain alphanumeric characters.

* Tags given in the command will overwrite the Client’s existing tags

* You can remove all of the client’s tags by typing t/ without specifying any TAG

* TAG is optional.

[r/REMARK]

* Substitute REMARK with remarks for the client.

* REMARK should be alphanumeric.

* Any whitespace at the start of REMARK will be removed.

* REMARK is optional.

*The set of special characters are !#$%&'*+/=?{|}~^.-`

Example

Lets say you want to add a new client with the following details:
Name: Amanda Low
Phone number: 95436543
Email: AmandaLow@dmail.com
Address: West Coast Grove 69
Birthday: 5 April 1990
Sport: Swimmer
Tag: Vegetarian

  1. Type the command below into the command box.

    • add-c n/Amanda Low p/95436543 e/AmandaLow@dmail.com a/West Coast Grove 69 s/Swimmer t/Vegetarian

      AddExampleCommand
  2. Press enter to execute.

  3. After Amanda has been successfully added to the clients list, the result will be displayed as shown.

AddExampleSuccess

Common errors/ problems:

If you are facing errors or difficulty adding a client, you can refer to the common errors and problems listed below and resolve your error using the solution given.

  1. Compulsory fields missing

    If you are adding a client and miss out any of the compulsory parameters. You will not be able to add the client.

    For example, when you want to add a Rachel Tan into FitBiz but did not include the compulsory field a/ADDRESS

    AddNoAddress

    After pressing enter, the following error message will be shown.

    AddNoAddressError

    To solve this error, ensure that all compulsory parameters are included when adding a client. The compulsory parameters include: n/NAME, p/PHONE, e/EMAIl and a/ADDRESS. To continue with the same example, the command will now include Rachel’s address.

    AddWithAddressCommand

    The result of successfully adding Rachel will show the following

    AddAddressSuccess
  2. Adding clients with the same phone number or email

In FitBiz, you cannot add 2 clients with the either same phone number or email.

For example, you have client with the email RachelTan@dmail.com and you want to add another client with the same email.

AddSameEmailCommand

The following error message will be shown.

AddSameEmailError

To solve this issue, ensure that any new client you add does not have the same phone number or email as existing client.

Filter clients based on attribute: filter-c --- Toh Ker Wei

When you have many clients and want to filter the list of clients to view a specific group, you can use the command filter-c to filter clients based on their tags or their sports.

Format: filter-c [t/TAG]…​ [s/SPORT]…​

Parameters

Parameter Important notes

[t/TAG]

TAG is the tag of the clients you want to match and list.

TAG is case-insensitive.
e.g. healthy will match Healthy

TAG should only contain letters or numbers.
e.g. monday or obese200kg

[s/SPORT]

SPORT is the sport of the clients you want to match and list.

SPORT is case-insensitive.
e.g. track and field returns the same result as Track And Field

SPORT should only contain letters, numbers or spaces. e.g. sumo wrestling or 100m sprint

Order of words in SPORT does not matter e.g. track and field returns the same result as field and track

Example

Let’s say you want to filter through your list of clients and only display those with the tag healthy and play the sport badminton.

  1. Type the command filter-c t/healthy s/badminton into the command box.

    FilterExampleCommand
  2. Press enter to execute.

  3. The clients with the matching tag and sport will be displayed as shown.

FilterExampleSuccess

Common error/ problem

Tags with spaces

When you want to filter the clients list with multiple tags like healthy and sporty, you might enter the command shown below.

FilterTagCommand

You will then encounter the error Tags names should be alphanumeric.

FilterTagError

This error occurs because TAG only accepts letters and numbers but not spaces. To solve the problem, add an additional delimiter for each tag you want to specify. Note that sports does not require multiple delimiter.

FilterTagCorrectCommand

The list of successfully filter clients will then be displayed.

FilterTagSuccess

Contributions to the Developer Guide

Given below are the 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.

Logic component

LogicClassDiagram
Figure 1. Structure of the Logic Component

API : Logic.java

  1. Logic uses the FitBizParser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding or deleting a client).

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

  5. In addition, the CommandResult object can also instruct the Ui to perform certain actions, such as displaying the list of clients or exercise graphs.

Given below is the sequence diagram for interactions within the Logic component for the execute("delete-c 1") API call mentioned previously.

DeleteSequenceDiagram
Figure 2. Interactions Inside the Logic Component for the delete-c 1 Command

Filtering the list of clients --- Toh Ker Wei

This feature allows users to filter the list of clients by specifying the Tag or Sport of the clients they want to view.

Implementation

This filtering mechanism is facilitated by TagAndSportContainsKeywordsPredicate, that implements Predicate<Client> which is a wrapper class for a boolean. FilterCommand is associated with Model is responsible for calling Model#updateFilteredClientList based on TagAndSportContainsKeywordsPredicate. TagAndSportContainsKeywordsPredicate will call test on Client to check if the clients Tag and Sport contains all the keyword. the relations between these classes are shown in the class diagram below.

FilterClassDiagram

To further elaborate, TagAndSportContainsKeywordsPredicate contains 2 booleans:

  1. hasTag: evaluates if the client has all the Tag specified

  2. hasSport: evaluates if the client has all the Sport specified

If there is no keyword specified for either Tag or Sport, the corresponding boolean will return true. There must be at least 1 keyword specified, regardless of whether it is a Tag or Sport. TagAndSportContainsKeywordsPredicate will then evaluate and return the logical addition of hasTag and hasSport.

In the following sequence diagram, we will be tracing the execution of the command filter t/obese s/swim entered by the user.

FilterSequenceDiagram

Design Considerations

Table 1. Table of Design Considerations
Using separate booleans to check for Tag and Sport keywords (Chosen) Using one boolean to check for all keywords

Ease of Implementation

Checks for client’s Tags and Sports containing keywords can be done separately ensuring that individual results are correct before combining them

Simpler logic but errors are more difficult to pinpoint to either TAG or SPORT

Ease of Expanding Feature

Easier to add new parameters to filter since a separate check will be done before combining with the result of previous checks

Boolean conditions can get very complex and logical error will be prone to occur

We decided to use the first approach of checking if the client contains Tag specified and Sport specified separately.

Firstly, by separating the checks for each attributes, a correct implementation of checking Tag against the keywords will allow us to easily duplicate the logic to be done for Sport. This makes the code easier to debug as we can simply check the hasAttribute boolean to see if it gives the correct value.

Secondly, separating the checks for each attributes will allow us to add attributes of different types stored in different data structure easier. We could simply add another check on the attribute against the keyword specified then do a logical addition of the result against the others.

Therefore, as we foresee us adding more attributes to be filtered increasing the need to ensure logical correctness, the first approach is the most ideal.

Viewing the information of a client --- Toh Ker Wei

This feature allows users to view the information of a specific client using his INDEX in the clients list. Information displayed includes additional information of the client, exercises done and his personal best of exercises done.

Implementation

The view client’s information feature is primarily facilitated by the model Client. The details for list of exercises done and personal best will be discussed in section 3.7 and not be covered here. The client’s INDEX in the clients list will be used to identify and retrieve his information. Additionally, only when a client’s information is being viewed, graph of his exercises can be plotted.

In the following sequence diagram, we will be tracing the execution when the user enters the command view-c 3

ViewSequenceDiagram

Design Considerations

Choose client to view based on INDEX (Chosen) Choose client to view based on NAME

Adhering to Single Responsibilities Principle

view-c only has to retrieve and display the client based on INDEX entered

view-c has to retrieve clients with the same name and use INDEX to specify the client to view

Ease of Implementation

Easier to implement as MODEL only needs to be accessed once

Harder to implement as view-c needs to return a list of clients with the same name before using INDEX to specify the client

We decided to use the first approach of using the client’s INDEX to view his information.

Firstly, as the client’s INDEX is unique, view-c will only be responsible for retrieving and displaying the client’s information and will not need to resolve clients with the same names.

Secondly, for clients with the same name, INDEX qill be used to specify the client to be view. This causes extra work for the implementation. Furthermore, in cases where users manage many clients and some with same names, there are functions like find and filter which allow users to scope the clients list and easily find the desired client’s INDEX.

Therefore, viewing a client by his INDEX minimises the responsibility of the command and will not need to resolve conflicting clients and is the most ideal.