PROJECT: CRM Book


Overview

CRM Book is a desktop application targeted for salespeople. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. This application allows salespeople to organize their Leads, Contacts, and Accounts that suits their liking, as well as address problems that are symptomatic in the sales industry, such as identifying duplicates.

Summary of contributions

  • Major enhancement: Displaying list of non-duplicate Leads and Contacts

    • What it does: Informs the user if a Lead to be added in is already in the CRM Book as either a Lead or a Contact, and allows the user to see a Lead list and Contact list separately.

    • Justification: Current CRM applications fail to detect duplicates Leads and Contacts. As a result, these CRM applications may store a Lead or Contact numerous times, hence resulting in redundant data. Furthermore, these CRM applications may not be able to display Leads and Contacts separately. Hence, this enhancement tackles these issues so that the user will have a more pleasant experience with managing his/her Leads and Contacts.

    • Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives.

  • Minor enhancement: Created an alias command for basic commands

    • What it does: User can make the CRM Book perform basic commands with a few letters.

    • Justification: Salespeople may want the CRM Book to do a basic command as quickly as possible. This will involve typing as few letters as possible.

  • Minor enhancement: Enhanced the Find command to be able to search for phone numbers and email address

    • What it does: User can search for Leads and Contacts based on phone numbers and email address.

    • Justification: Salespeople may want to search for Leads and Contacts based on personal information other than names.

  • Code contributed: [Functional code] [Test code]

  • Other contributions:

    • Community:

    • Project management:

      • Managed the collation of code of my team for releases v1.4 - v1.5 (3 releases) on GitHub

    • Enhancements to existing features:

      • Made the find command be able to search for phone numbers and email addresses (Pull request #200)

Contributions to the User Guide

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

Displaying all Leads or all Contacts: disp, display

Shows a list of either Leads or Contacts in the CRM.
Format: disp Lead, display Lead, disp Contact, display Contact

  • The search is case insensitive. e.g lead will match Lead

  • Only a full word will be matched e.g. Contact will not match Contacts

  • Display : disp KEYWORD, display KEYWORD
    e.g. disp Lead, display Contact

  • Find : f KEYWORD [MORE_KEYWORDS], find KEYWORD [MORE_KEYWORDS]
    e.g. f Chris, find James Jake, f 99881122, find john@gmail.com

Contributions to the Developer Guide

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

Alias Commands feature

Current Implementation

A command can be performed by typing in its alias rather than the word.
The following is an example of implementing the alias command for the list command:

public class ListCommand extends Command {

    public static final String COMMAND_WORD = "list";
    //@@author Sheikh-Umar
    public static final String COMMAND_ALIAS = "l";
    //@@author

    public static final String MESSAGE_SUCCESS = "Listed all Leads and Contacts";


    @Override
    public CommandResult execute() {
        model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
        return new CommandResult(MESSAGE_SUCCESS);
    }
}

The alias command for all other commands will follow a similar implementation.

Design Considerations

Aspect: How to implement the alias command for all commands

The feature is implemented by adding the alias of the command into its respective java document, and updating the AddressBookParser java document.
The feature is implemented this way to utilise the command java documents that are available as opposed to creating a new java document for a certain alias.

This feature is implemented to allow a user to enter a command without specifying the entire word of the command.

Identifying a Duplicate feature

Current Implementation

The CRM Book will ensure that every Lead and Contact stored is a non-duplicate.

The feature is implemented by checking the phone number and email address of a new Lead with all of the phone numbers and email addresses of all leads and contacts currently in the CRM-Book.

The feature will be implemented on the add command because the current application detects duplicates at the add command.
The following is how the feature will be implemented:

public boolean contains(Person toCheck) {
        requireNonNull(toCheck);
        for (int i = 0; i < internalList.size(); i++) {
            Person current = internalList.get(i);
            if (current.getPhone().equals(toCheck.getPhone())
                    || current.getEmail().equals(toCheck.getEmail())) {
                return true;
            }
        }
        return false;
    }

The phone number and email address of a Lead will be checked in the list of all Leads and Contacts. If either the phone number of email address of the Lead to be added is found in the list, the CRM application will display a message that the lead is a duplicate and will reject this lead.

The following activity diagram shows how the operation of identifying a duplicate lead works:

DetectDuplicateActivityDiagram

Design Considerations

Aspect: How to implement identifying a duplicate
  • Alternative 1 (current choice): Iterate through all Leads and Contacts in CRM-Book.

    • Pros: Search will be performed in linear time, and enhances an existing portion of code.

Displaying Lead list and Contact list feature

Current Implementation

The CRM Book will be able to list out all Leads and Contacts separately.

The feature is implemented by checking on the type of the persons already stored in the CRM, and displaying all persons that match the keyword (either Lead or Contact) that the user enters.

The feature is implemented through the DisplayCommand, which is based on FindCommand. Hence, the DisplayCommand will operate similarly as the FindCommand, with the only difference being the DisplayCommand searches for all Leads or Contacts already in the CRM Book.

The DisplayCommand inherits from Command. It is implemented this way:

public class DisplayCommand extends Command {
    @Override
    public CommandResult execute() {
        // … import logic …
    }
}

The following activity diagram shows how the operation of displaying the Leads or Contacts list works:

DisplayListOfACertainTypeActivityDiagram

Design Considerations

Aspect: How displaying Lead list and Contact list works
  • Alternative 1 (current choice): Iterate through the CRM Book for persons that match the keyword that user entered just like the FindCommand.

    • Pros: Iteration will be performed in linear time, and utilises the functionality of the FindCommand.

Adding a Parent Company tag feature [Coming in v2.0]

Current Implementation

It is possible that the user may want to keep track of the companies associated with the Leads and Contacts in the CRM Book. For example, Skype and Nokia are two different companies whose parent company is Microsoft. Hence, every Lead and Contact will have an additional tag named after the parent company if their company has a parent company. The following activity diagram illustrates how this will be implemented:

AddParentCompanyTagActivityDiagram

Design Considerations

Aspect: How adding a Parent Company tag feature works
  • Alternative 1 (current choice): If the user updated the Company of a Lead or Contact, the CRM Book determines if this company has a parent company using a Google search. If yes, it automatically adds a tag to this Lead or Contact labelled as the parent company of the company of the Lead or Contact.

Enhancement of Find Command feature

Reason for Implementation

The user may want to search for Leads and Contacts based on phone numbers and email addresses rather than names.

Current Implementation

The CRM Book currently searches for a Lead or Contact based on their name.

This command can be further improved by being able to find phone numbers and email addresses.

The following is how the feature will be implemented:

public boolean test(Person person) {
         return keywords.stream().anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)                .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword)
                        || StringUtil.containsWordIgnoreCase(person.getPhone().value, keyword)
                        || StringUtil.containsWordIgnoreCase(person.getEmail().value, keyword));
     }
 }

The phone number and email address that the user entered will be checked in the list of all Leads and Contacts. If either the phone number of email address is found in the list, the CRM Book will display the Leads and/or Contacts that match the keywords entered. If not, the CRM Book will display zero Leads and Contacts found.

Design Considerations

Aspect: How to implement finding phone numbers and email addresses
  • Alternative 1 (current choice): Edit the current search implementation to include finding phone numbers and email addresses.

    • Pros: Search will be performed in linear time, and utilises an existing portion of code.

Use case: User seeks Lead list or Contact list

MSS

  1. User enters command for Lead list or Contact list.

  2. CRM retrieves the Lead list or Contact list.

  3. User sees the Lead list or Contact list.

Extensions

  • 1a. User enters a keyword that is neither Lead nor Contact.

    • 1a1. CRM Book displays an empty list.

      Use case ends.

Use case: User seeks to add a company to a Lead or Contact [Coming in v2.0]

MSS

  1. User enters command to update the company of Lead or Contact.

  2. CRM updates company of the Lead or Contact.

  3. User sees the updated company of the Lead or Contact.

Extensions

  • 1a. User enters command incorrectly.

    • 1a1. CRM Book displays an error message.

      Use case ends.

  • 1a. The keyword that user entered has a parent company.

    • 1a1. CRM Book adds a tag named after the parent company to the Lead or Contact.

      Use case ends.

  • 1a. User enters a company (keyword) has no parent company.

    • 1a1. CRM Book does not add any to the Lead or Contact.

      Use case ends.

Use case: User enters phone numbers and/or email addresses to find

MSS

  1. User enters keywords (phone numbers and/or email addresses) for find command.

  2. CRM searches for Leads and/or Contacts that match with the keywords.

  3. User sees the Leads and/or Contacts that match with the keywords.

Extensions

  • 1a. User enters find command incorrectly.

    • 1a1. CRM Book displays error message.

      Use case ends.

  • 2a. CRM Book is unable to find Leads and/or Contacts that match with the keywords.

    • 2a1. User sees an empty list.

      Use case ends.

Displaying Lead or Contact list

  1. Finding Lead(s) or Contacts(s) based on phone numbers and email addresses.

    1. Prerequisites: Nil.

    2. Test case: disp Lead, display Lead
      Expected: All Leads in the CRM Book. Timestamp in the status bar is updated.

    3. Test case: disp Contact, display Contact
      Expected: All Contacts in the CRM Book. Timestamp in the status bar is updated.

Duplicate Detection

  1. Detecting a duplicate Lead or Contacts.

    1. Prerequisites: There is at least 1 Lead or Contact.

    2. Test case: a n/John Tan p/99991234 e/johntan@gmail.com a/33, Eunos Street 7, #5-67, add n/John Tan p/99991234 e/johntan@gmail.com a/33, Eunos Street 7, #5-67
      Ensure the information entered has either a phone number or email address that is identical to any Lead or Contact in the CRM Book. Expected: Duplicate Lead/Contact message shown. Timestamp in the status bar is updated.

Executing commands via alias

  1. Executing commands via its alias

    1. Prerequisites: Read through the User Guide for commands that have aliases.

    2. Test case: disp Lead, display Lead
      Expected: All Leads in the CRM Book. Timestamp in the status bar is updated.

    3. Test case: l, list
      Expected: List all Leads and Contacts in the CRM Book. Timestamp in the status bar is updated.

Finding Lead(s) and Contact(s) via Phone Numbers and Email Addresses

  1. Finding Lead(s) or Contacts(s) based on phone numbers and email addresses.

    1. Prerequisites: Nil.

    2. Test case: f 99991234, find 99991234
      Expected: Lead/Contact with the phone number 99991234 is shown in the status message. Timestamp in the status bar is updated.

    3. Test case: f johntan@gmail.com, find johntan@gmail.com
      Expected: Lead/Contact with the email address johntan@gmail.com is shown in the status message. Timestamp in the status bar is updated.