Developer Guide
Introduction
PropertyMatch is a JavaFX application that helps property agents manage their database of customers and properties using a command-line interface.
Purpose of the Developer Guide
This guide was made for developers looking to comprehend or build upon the functionalities of PropertyMatch, and software testers looking to test PropertyMatch’s features.
About the Guide
This developer guide provides a high-level architecture overview of the workings of PropertyMatch, followed by main features and functions of PropertyMatch along with their explanations, design considerations and implementations
Table of Contents
- Introduction
- Purpose of the Developer Guide
- About the Guide
- Table of Contents
- 1. Acknowledgements
- 2. Setting up, getting started
- 3. Design
-
4. Implementation
- 4.1 Internal implementations of Customer and Property
- 4.2 Adding of customers and properties
- 4.3 Editing of buyers and properties
- 4.4 Deleting of customers and properties
- 4.5 Finding of Customers and Properties
- 4.6 Filtering of Customers and Properties
- 4.7 Matching for Customers and Properties
-
4.8 Reset the application with
clear
- 4.9 Exit with a delay
- Documentation, logging, testing, configuration, dev-ops
- Appendix A: Requirements
-
Appendix B: Instructions for manual testing
- B.1 Launch and shutdown
- B.2 Adding a customer
- B.3 Adding a property
- B.4 Listing all customers
- B.5 Listing all properties
- B.6 Deleting a customer
- B.7 Deleting a property
- B.8 Editing a customer
- B.9 Editing a property
- B.10 Finding customers
- B.11 Finding properties
- B.12 Filtering customers
- B.13 Filtering properties
- B.14 Matching properties to a customer
- B.15 Matching customers to a property
- B.16 Clearing the application
- B.17 Viewing help
- B.18 Exiting the application
- Appendix C: Proposed enhancements
- Appendix D: Effort
1. Acknowledgements
- Our developer guide is built upon Addressbook-level3
2. Setting up, getting started
Refer to the guide Setting up and getting started.
3. Design
![:bulb: :bulb:](https://github.githubassets.com/images/icons/emoji/unicode/1f4a1.png)
- The
.puml
files used to create diagrams in this document docs/diagrams
folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
- The diagrams are merely to showcase the general idea of how our codebase work. They do not serve as exact replicas of our code.
3.1 Architecture
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
Main components of the architecture
Main
(consisting of classes Main
and MainApp
) is in charge of the app launch and shut down.
- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app’s work is done by the following four components:
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Commons
represents a collection of classes used by multiple other components.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delcust 1
.
Each of the four main components (also shown in the diagram above),
- defines its API in an
interface
with the same name as the Component. - implements its functionality using a concrete
{Component Name}Manager
class (which follows the corresponding APIinterface
mentioned in the previous point).
For example, the Logic
component defines its API in the Logic.java
interface and implements its functionality using the LogicManager.java
class which follows the Logic
interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component’s being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
The sections below give more details of each component.
3.2 UI component
The API of this component is specified in Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, CustomerListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class which captures the commonalities between classes that represent parts of the visible GUI.
The UI
component uses the JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
- executes user commands using the
Logic
component. - listens for changes to
Model
data so that the UI can be updated with the modified data. - keeps a reference to the
Logic
component, because theUI
relies on theLogic
to execute commands. - depends on some classes in the
Model
component, as it displaysCustomer
object residing in theModel
.
3.3 Logic component
API : Logic.java
Here’s a (partial) class diagram of the Logic
component:
The sequence diagram below illustrates the interactions within the Logic
component, taking execute("delcust 1")
API call as an example.
![:information_source: :information_source:](https://github.githubassets.com/images/icons/emoji/unicode/2139.png)
DeleteCustomerCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
How the Logic
component works:
- When
Logic
is called upon to execute a command, it is passed to anAddressBookParser
object which in turn creates a parser that matches the command (e.g.,DeleteCustomerCommandParser
) and uses it to parse the command. - This results in a
Command
object (more precisely, an object of one of its subclasses e.g.,DeleteCustomerCommand
) which is executed by theLogicManager
. - The command can communicate with the
Model
when it is executed (e.g. to delete a customer). - The result of the command execution is encapsulated as a
CommandResult
object which is returned back fromLogic
.
Here are the other classes in Logic
(omitted from the class diagram above) that are used for parsing a user command:
How the parsing works:
- When called upon to parse a user command, the
AddressBookParser
class creates anXYZCommandParser
(XYZ
is a placeholder for the specific command name e.g.,AddCustomerCommandParser
) which uses the other classes shown above to parse the user command and create aXYZCommand
object (e.g.,AddCustomerCommand
) which theAddressBookParser
returns back as aCommand
object. - All
XYZCommandParser
classes (e.g.,AddCustomerCommandParser
,DeleteCustomerCommandParser
, …) inherit from theParser
interface so that they can be treated similarly where possible e.g, during testing.
3.4 Model component
API : Model.java
The Model
component,
- stores the address book data i.e., all
Customer
objects (which are contained in aUniqueCustomerList
object). - stores the currently ‘selected’
Customer
objects (e.g., results of a search query) as a separate filtered list which is exposed to outsiders as an unmodifiableObservableList<Customer>
that can be ‘observed’ e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - stores a
UserPref
object that represents the user’s preferences. This is exposed to the outside as aReadOnlyUserPref
objects. - does not depend on any of the other three components (as the
Model
represents data entities of the domain, they should make sense on their own without depending on other components)
![:information_source: :information_source:](https://github.githubassets.com/images/icons/emoji/unicode/2139.png)
Tag
list in the AddressBook
, which Customer
references. This allows AddressBook
to only require one Tag
object per unique tag, instead of each Customer
needing their own Tag
objects.![](images/BetterModelClassDiagram.png)
3.5 Storage component
API : Storage.java
The Storage
component,
- can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
- inherits from both
AddressBookStorage
andUserPrefStorage
, which means it can be treated as either one (if only the functionality of only one is needed). - depends on some classes in the
Model
component (because theStorage
component’s job is to save/retrieve objects that belong to theModel
)
3.6 Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1 Internal implementations of Customer and Property
4.1.1 Customer
The structure of a Customer
object can be viewed in the object diagram below.
From the diagram, the Customer
object consists of the following attributes.
-
Name
: The name of the customer. -
Phone
: The phone number of the customer. -
Email
: The email address of the customer. -
Budget
: The budget that the customer is willing to pay for the property. -
Tags
: The characteristics of the property that the customer is looking for.
4.1.2 Property
The structure of a Property
object can be viewed in the object diagram below.
From the diagram, the Property
object consists of the following attributes.
-
PropName
: The name of the property. -
PropAddress
: The address of the property. -
PropPhone
: The phone number of the property. -
Price
: The price of the property. -
Tags
: The characteristics of the property that the customer is looking for.
4.1.3 User input validation
Phone numbers both follow this validation regex.
public static final String VALIDATION_REGEX = "(6|8|9)\\d{7}";
This means that phone numbers must start with 6, 8, or 9 and must have at least 8 digits. This means it only supports Singapore phone numbers.
Price
and Budget
follow this validation regex.
public static final String VALIDATION_REGEX = "[1-9]\\d{4,11}";
This means that the price or budget must be a positive integer with at least 5 digits and at most 12 digits. It also cannot start with 0.
We decided on this arbitrary limit because we thought that it is not possible for a property to cost less than 10,000 dollars. We also thought that it is not possible for a property to cost more than 1 trillion dollars.
4.2 Adding of customers and properties
4.2.1 Customers
The customer list should not allow duplicate customers to be added. This is because it is not possible for a customer to have two profiles. This means we need to define a condition to check if the customer is already in the list.
At the start, we used a customer’s Name
to check if he was a duplicate entry. However, we realised that two unique customers may have the same names. Therefore, we decided to use the customer’s Phone
number to check if he was a duplicate entry. This is because it is unlikely for two unique customers to have the same phone number.
The activity diagram for the creation of a customer can be seen below.
4.2.2 Properties
Similar to the customer list, the property list should not allow duplicate properties to be added as well. This is because it will cause bugs in our other features. This means we need to define a condition to check if the property is already in the list.
At the start, we used a property’s Name
to check if he was a duplicate entry. However, we realised that two unique properties may have the same names. Therefore, we decided to use the property’s Address
to check if he was a duplicate entry. This is because it is unlikely for two unique properties to have the same address.
The activity diagram for the creation of a property can be seen below.
4.3 Editing of buyers and properties
4.3.1 Motivation
The property agent may want to edit the details of a customer or property after adding it to the application. For example, the property agent may want to change the budget range of a customer after adding it to PropertyMatch. Or, the property agent may want to change the budget of a property after adding it to PropertyMatch.
4.3.2 Implementation
The EditCustomerCommand
and EditPropertyCommand
classes extends the Command
class. They are used to edit the details of a customer or property, respectively.
Both commands allow the user to change any of the fields of a customer or property. The commands expect at least one flag to be edited, otherwise an error message will be displayed.
When the edit command is inputted, the EditCustomerCommandParser
and EditPropertyCommandParser
classes are used to parse the user input and create the respective EditCustomerCommand
and EditPropertyCommand
objects.
When these created command objects are executed by the LogicManager
, the EditCustomerCommand#execute(Model model)
or EditPropertyCommand#execute(Model model)
methods are called. These methods will edit the customer or property in the model, and return a CommandResult
object.
![:exclamation: :exclamation:](https://github.githubassets.com/images/icons/emoji/unicode/2757.png)
During this execution process, the existing entity is first retrieved from the model. The fields of the entities are then edited according to what flags were passed in by the user during the edit commands. A new customer or property is then created with the edited fields, and any fields that have not been edited will be copied over from the original entity. The new entity is then added to the model, and the original entity is removed from the model. The new customer or property is then added into the model, replacing the old one. The new entity will then be displayed to the user, and a success message is displayed.
4.3.3 Design Considerations
Aspect: How the edit commands should relate to each other:
-
Alternative 1 (current choice):
EditCustomerCommand
andEditPropertyCommand
are separate, and both inherit from theCommand
class.- Pros:
- Both the
Customer
andProperty
classes have different fields that are exclusive to each other. - This reduces complexity of the system, and unexpected behaviours.
- The inheritance of the
Command
class allows us to keep to the Command design pattern, to easily add more types of edit commands in the future, without having to change the existing code.
- Both the
- Cons:
- More boilerplate code for each of the classes, which increases the size of the codebase.
- Pros:
-
Alternative 2: A single
EditCommand
class is used to edit both customer and property.- Cons:
- Unnecessary complexity is introduced into the system.
- Cons:
Aspect: How the edited entities should interact with the model:
- We also decided for the edit commands to create a new entity, instead of editing the existing one. This allows us to not include any setters in the
Customer
andProperty
classes, which make the objects immutable, so there is less likelihood of unexpected changes to the object. This enables us to maintain the defensiveness of our code. By creating a new entity every time the property agent edits, we can easily add the new customer or property into the model, and remove the old one. This also allows us to easily undo the edit command in the future, by simply adding the old entity back into the model.
The following sequence diagram shows how the EditCustomerCommand
is executed.
The following sequence diagram shows how the EditPropertyCommand
is executed.
4.4 Deleting of customers and properties
4.4.1 Motivation
The property agent may want to delete the profile of any customer or property that has been previously added into the app. For example, the property agent might want to remove a particular property after it has been sold. Or, a particular client is no longer interested in buying a house anymore.
4.4.2 Implementation
The DeleteCustomerCommand
and DeletePropertyComannd
classes extends from the Command
class. They are used to delete the details of a Customer or Property respectively. The command expects exactly one INDEX
of the Customer or Property to be deleted, otherwise an error message will be displayed.
When the delete command is inputted, the DeleteCustomerCommandParser
and DeletePropertyCommandParser
classes are used to parse the user input and create the DeleteCustomerCommand
or DeletePropertyCommand
objects respectively.
When these created command objects are executed by the LogicManager
, the DeleteCustomerCommand#execute(Model model)
or DeletePropertyCommand#execute(Model model)
methods are called. These methods will delete the customer or property in the model, and return a CommandResult
object.
4.4.3 Design Considerations
Aspect: How the delete commands should relate to each other:
-
Alternative 1 (current choice):
DeleteCustomerCommand
andDeletePropertyCommand
are separate, and both inherit from theCommand
class. -
Alternative 2: A single
DeleteCommand
class is used to edit both customer and property.- Cons:
- Unnecessary complexity is introduced into the system.
- Cons:
The following activity diagram summarises the execution of a delcust INDEX
command.
The following sequence diagram shows how the DeleteCustomerCommand
is executed.
The following sequence diagram shows how the DeletePropertyCommand
is executed.
4.5 Finding of Customers and Properties
4.5.1 Motivation
The property agent may want to find and access the details of a particular Customer or Property that has been previously added into the app. For example, the property agent may want to refresh their memory on a particular customer’s budget. Or the property agent may want to check the details of a particular property.
4.5.2 Implementation
The FindCustomerCommand
and FindPropertyCommand
classes extends the Command
class. They are used to find the profiles of a customer or property, respectively.
Both commands allow the user to find any customer or property. The commands expect at least one substring to base the search on, otherwise an error message will be displayed.
When the find command is inputted, the FindCustomerCommandParser
and FindPropertyCommandParser
classes are used to parse the user input and create the respective FindCustomerCommand
and FindPropertyCommand
objects.
When these created command objects are executed by the LogicManager
, the FindCustomerCommand#execute(Model model)
or FindPropertyCommand#execute(Model model)
methods are called. These methods will find the customer or property in the model, and return a CommandResult
object.
The following sequence diagram shows how the FindCustomerCommand
is executed.
4.5.3 Design Considerations
Aspect: How the find commands should relate to each other:
-
Alternative 1 (current choice):
FindCustomerCommand
andFindPropertyCommand
are separate, and both inherit from theCommand
class.- Pros:
- Both the
Customer
andProperty
classes have different fields that are exclusive to each other. - This reduces complexity of the system, and unexpected behaviours.
- The inheritance of the
Command
class allows us to keep to the Command design pattern, to easily add more types of edit commands in the future, without having to change the existing code.
- Both the
- Cons:
- More boilerplate code for each of the classes, which increases the size of the codebase.
- Pros:
-
Alternative 2: A single
FindCommand
class is used to find both customer and property.- Cons:
- Unnecessary complexity is introduced into the system.
- Cons:
4.6 Filtering of Customers and Properties
4.6.1 Motivation
The property agent may want to see a list of customers based on their budget. For example, the property agent may want to filter customers with budget more than $100000. Or, the property agent may want to see a list of customers based on the characteristics of the property they desired. For example, the property agent may want to filter customers who love pink properties. Or, the property agent may want to see a list of customers based on both budget and characteristics to enhance productivity.
The property agent may also want to see a list of properties based on their budget. For example, the property agent may want to filter properties with budget less than $1000000. Or, the property agent may want to see a list of properties based on the characteristics. For example, the property agent may want to filter pink properties. Or, the property agent may want to see a list of properties based on both budget and characteristics to enhance productivity.
4.6.2 Implementation
The FilterCustomerCommand
and FilterPropertyCommand
class extends the Command
class. They are used to filter customers and properties, respectively.
The filtercust
command allows the user to filter customers based on their budget and/or properties’ characteristics they love. While the filterprop
command allows the user to filter properties based on their budget and/or characteristics.
The commands expect at least one flag, either budget/price or characteristics, to be used as a filter.
When the filter command is inputted, the FilterCustomerCommandParser
and FilterPropertyCommandParser
class is used to parse the user input and create the respective FilterCustomerCommand
or FilterPropertyCommand
objects.
When these created command objects are executed by the LogicManager
, the FilterCustomerCommand#execute(Model model)
or FilterCustomerCommand#execute(Model model)
methods are called. These methods will update the filtered customer or property list in the model
which will eventually update the customers shown in the UI, and return a CommandResult
object.
During this execution process, a new BudgetAndTagsInRangePredicate
or PriceAndTagsInRangePredicate
object which is used as a predicate to check whether a customer’s budget is bigger and all the characteristics are desired by the customer or whether a property’s price is lower and the property has all the characteristics, respectively.
All customers or properties will be tested using this BudgetAndTagsInRangePredicate
or PriceAndTagsInRangePredicate
. Customers or properties which satisfy this condition will be included into the FilteredCustomerList
or FilteredPropertyList
in the model.
The following sequence diagram shows how the FilterCustomerCommand
is executed.
4.6.3 Design Considerations
Aspect: How the filter customer commands should relate to filter property commands:
-
Alternative 1 (current choice):
FilterCustomerCommand
andFilterPropertyCommand
inherit from theCommand
class and separated with each other.- Pros:
- Both the
Customer
andProperty
classes have different fields that are exclusive to each other. - This reduces complexity of the system, and unexpected behaviours.
- The inheritance of the
Command
class allows us to keep to the Command design pattern, to easily add more types of edit commands in the future, without having to change the existing code.
- Both the
- Cons:
- More boilerplate code for each of the classes, which increases the size of the codebase.
- Pros:
-
Alternative 2: A single
FilterCommand
class is used to edit both customer and property.- Cons:
- Unnecessary complexity is introduced into the system.
- Cons:
Aspect: How the filtered customers or properties should interact with the model:
- We also decided for the filter commands to put the filtered customers or filtered properties in a different list (
FilteredCustomerList
andFilteredPropertyList
), instead of removing the ‘unused’ customers and properties from the model.
4.7 Matching for Customers and Properties
4.7.1 Motivation
The property agent may want to get all properties that satisfy the customers criteria or get all customers that want the properties characteristics. For example, the property agent want to get all properties that certain specified customer want and can afford. Or, the property agent want to get all customers that might want to buy certain specified property.
4.7.2 Implementation
The MatchCustomerCommand
and MatchPropertyCommand
classes extends the Command
class.
They are used to match the details of a customer or property, respectively.
The command expects exactly one “Index” of the customer or property to be match, otherwise an error message will be displayed.
When the match command is inputted, the MatchCustomerCommandParser
or MatchPropertyCommandParser
classes are used to parse the user input and create the MatchCustomerCommand
or MatchPropertyCommand
objects respectively.
When these created command objects are executed by the LogicManager
, the MatchCustomerCommand#execute(Model model)
or MatchProeprtyCommand#execute(Model model)
method is called.
These methods will match the customer or property in the model, and return a ComandResult
object.
The following sequence diagram shows how the MatchCustomerCommand
is executed.
4.7.3 Design Consideration
-
Alternative 1 (current choice):
MatchPropertyCommand
andMatchCustomerCommand
are separate, and both inherit from theCommand
class.- Pros:
- Allows the property agent to match only customers or properties.
- The inheritance of the
Command
class allows us to keep to the Command design pattern, to easily add more types of edit commands in the future, without having to change the existing code.
- Cons:
- More code for each of the classes, which increases the size of the codebase
- More commands for the property agent to remember
- Pros:
-
Alternative 2: A single
MatchCommand
class is used to match both customers and properties.- Pros:
- Lesser commands for the property agent to remember
- Cons:
- Unable to match only customers or properties without specify it which increase the complexity of the commands
- Pros:
4.8 Reset the application with clear
4.8.1 Motivation
The property agent may want to clear the list of customers or properties to start from a clean slate.
4.8.2 Implementation
The ClearCommand
extends the Command
class. It is used to clear the list of customers or properties.
4.8.3 Design Considerations
-
Alternative 1:
ClearPropertyCommand
andClearCustomerCommand
are separate, and both inherit from theCommand
class.- Pros:
- Allows the property agent to clear only customers or properties.
- The inheritance of the
Command
class allows us to keep to the Command design pattern, to easily add more types of edit commands in the future, without having to change the existing code.
- Cons:
- More boilerplate code for each of the classes, which increases the size of the codebase
- More commands for the property agent to remember
- Pros:
-
Alternative 2 (current choice): A single
clear
class is used to clear both customers and properties.- Pros:
- Less overhead to deal with
- Lesser commands for the property agent to remember
- Cons:
- Unable to clear only customers or properties
- Pros:
4.9 Exit with a delay
4.9.1 Motivation
The property agent should exit the application with a peace of mind. A delay is required for the property agent to read the exit message before the application closes.
4.9.2 Implementation
The ExitCommand
extends the Command
class. It is used to close the application and display the goodbye message.
The following code is used to implement the delay. There are many ways to implement a timeout, but since we are using JavaFX. This is probably the simplest way to accomplish it.
PauseTransition delay = new PauseTransition(Duration.seconds(3));
delay.setOnFinished(e -> primaryStage.hide());
delay.play();
Documentation, logging, testing, configuration, dev-ops
Appendix A: Requirements
A.1 Product scope
Target user profile:
- Property agents new to the real estate industry in Singapore
- Looking for a customer-property management tool
Value proposition: This tool is for property agents who want to organise their client profiles with their corresponding properties. Property agents can boost their efficiency by seamlessly matching their clients with their desired properties.
A.2 User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
property agent | add a new customer’s details | save their details in PropertyMatch |
* * * |
property agent | add a new property’s details | save their details in PropertyMatch |
* * * |
property agent | view all customers | easily access all my customers |
* * * |
property agent | view all properties | easily access all available properties |
* * * |
property agent | remove existing customers | remove customer who is either not interested anymore or has bought a property |
* * * |
property agent | remove existing properties | remove property which is either already sold or not sold anymore |
* * * |
property agent | read the user guide | learn to use the application |
* * |
property agent | update customers’ details | ensure customers’ information is up to date |
* * |
property agent | update properties’ details | ensure properties’ information is up to date |
* * |
property agent with a lot of customers | find customers based on customers’ names | get a list of customers I am looking for |
* * |
property agent with a lot of properties | find properties based on properties’ names | get a list of properties I am looking for |
* * |
property agent with a lot of customers | filter customers based on customers’ budget or required characteristics | understand specific needs of my customers |
* * |
property agent with a lot of properties | filter properties based on properties’ price or required characteristics | understand the specific traits of my properties |
* * |
property agent with a lot of customers | match a customer with suitable existing properties | get a list of specific properties with the detail satisfy the customer |
* * |
property agent with a lot of properties | match a property with suitable existing customers | get a list of specific customers with the detail satisfy the property |
* |
property agent | add notes to customers’ profiles | streamline customer management profile |
* |
property agent | add notes to properties’ profiles | streamline customer property profile |
* |
experienced property agent using the application with new device | import and export customers’ data | transfer customers’ data across devices |
* |
experienced property agent using the application with new device | import and export properties’ data | transfer properties’ data across devices |
A.3 Use cases
Use Case: UC01 - Add customer
System: PropertyMatch address book
Actor: Property Agent
- Property agent fills in name, phone number, email, budget and desired characteristic (tags).
- Property agent adds customer to address book.
Use case ends.
Extension:
1a. PropertyMatch detects an error in the entered command.
1a1. User edits the command.
Step 1a1 is repeated until the command entered is correct.
Use Case: UC02 - Add property
System: PropertyMatch address book
Actor: Property Agent
- Property agent fills in name, address, characteristics (tags), phone number, budget of property.
- Property agent adds property to address book.
Use case ends.
Extension:
1a. PropertyMatch detects an error in the entered command.
1a1. User edits the command.
Step 1a1 is repeated until the command entered is correct.
Use Case: UC03 - Delete customer
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the customer to be deleted and retrieves its index.
- Property agent inserts the index into the CLI.
- Property agent deletes the customer details from the address book.
Use case ends.
Extension:
2a. PropertyMatch detects an invalid index.
2a1. User edits the index.
Step 2a1 is repeated until the index entered is correct.
Use Case: UC04 - Delete property
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the property to be deleted and retrieves its index.
- Property agent inserts the index into the CLI.
- Property agent deletes the property details from the address book.
Use case ends.
Extension:
2a. PropertyMatch detects an invalid index.
2a1. User edits the index.
Step 2a1 is repeated until the index entered is correct.
Use Case: UC05 - List all entities
System: PropertyMatch address book
Actor: Property Agent
- Property agent decides to list either properties or customers.
- Property agent inputs the command.
- Property agent is able to view all entities.
Use case ends.
Extension:
2a. PropertyMatch detects an error in the entered command.
2a1. User edits the command.
Step 2a1 is repeated until the command entered is correct.
Use Case: UC06 - Edit entities
System: PropertyMatch address book
Actor: Property Agent
- Property agent decides to edit either properties or customers.
- Property agent identifies the property or customer to be deleted and retrieves its index.
- Property agent edits entity’s respective fields.
- Property agent is able to edit the entities details in the address book.
Use case ends.
Extension:
3a. PropertyMatch detects an error in the entered command.
3a1. User edits the command.
Step 3a1 is repeated until the command entered is correct.
Use Case: UC07 - Find specific entity
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the specific entity he wants.
- Property agent enters the entity name he wants.
- Property agent views the entity.
Use case ends.
Extension:
2a. PropertyMatch detects an invalid name entered.
2a1. User edits the inputted name.
Step 2a1 is repeated until a valid name is entered.
Use Case: UC08 - Filter properties or customer
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the specific criteria of properties or customer he wants.
- Property agent enters the criteria he wants.
- Property agent views the entity with that fulfills his criteria.
Use case ends.
Extension:
2a. PropertyMatch detects an error with the criteria entered.
2a1. User edits the inputted criteria.
Step 2a1 is repeated until a valid criteria is entered.
Use Case: UC09 - Match properties to customers
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the customer to be matched to its corresponding properties.
- Property agent inserts the index into the CLI.
- Property agent gets a list of properties that matches the criteria of the customer.
Use case ends.
Extension:
2a. PropertyMatch detects an invalid index.
2a1. User edits the index.
Step 2a1 is repeated until the index entered is correct.
Use Case: UC10 - Match customers to properties
System: PropertyMatch address book
Actor: Property Agent
- Property agent identifies the property to be matched to its corresponding customer.
- Property agent inserts the index into the CLI.
- Property agent gets a list of customers with criteria is fulfilled by the property.
Use case ends.
Extension:
2a. PropertyMatch detects an invalid index.
2a1. User edits the index.
Step 2a1 is repeated until the index entered is correct.
Use Case: UC11 - Import and export data
System: PropertyMatch address book
Actor: Property Agent
- Property agent can import data from another application to the existing application.
- Property agent can export data from the application and save the data.
Use case ends.
A.4 Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 properties and clients without a noticeable sluggishness in performance for typical usage.
- A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
- The system should respond to user inputs within 5 seconds.
- The user interface should be intuitive enough for property agents who are not IT-savvy.
- App functionality should not require access to an internet connection.
- Should save data locally in a human editable file.
- Should have a graphical user interface with readable font of at least size 11.
- Should have a graphical user interface which is intuitive and user-friendly.
A.5 Glossary
- Mainstream OS : Windows, Linux, Unix, OS-X
- API : API stands for Application Programming Interface, which is a set of definitions and protocols for building and integrating application software.
- Tag : A label or keyword assigned to a customer or property in the address book, to categorize, annotate, or identify specific characteristics of that customer or property.
- CLI : Command-line interface (CLI) is a text-based user interface (UI) used to run programs, manage computer files and interact with the computer.
- GUI : A graphical user interface (GUI) is a digital interface in which a user interacts with graphical components such as icons, buttons, and menus.
Appendix B: Instructions for manual testing
Given below are instructions to test the app manually.
![:information_source: :information_source:](https://github.githubassets.com/images/icons/emoji/unicode/2139.png)
B.1 Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder.
-
Double-click the jar file. If nothing happens after double-clicking the jar file, run
java -jar propertymatch.jar
on the command line in the folder.
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
B.2 Adding a customer
- Adding a customer with only compulsory fields
-
Test case:
addcust n/Tim Cook p/91234567 e/cook@apple.com b/2500000
- Expected: New customer should be added to Customer List with relevant details.
-
Test case:
- Adding a customer with all fields
-
Test case:
addcust n/Phoebe p/87654321 e/pb@gmail.com b/200000 c/bright c/sunny c/white
- Expected: New customer should be added to Customer List with relevant details.
-
Test case:
- Adding a customer with missing fields
-
Test case:
addcust n/Jack p/91135555
-
Expected: Command entered is highlighted in red. “Invalid command format” error message should be displayed and information regarding the syntax of the
addcust
command should be shown.
-
Test case:
- Adding a customer with an invalid field
-
Test case:
addcust n/Jack p/51234567 e/cook@apple.com b/2500000
- Expected: Command entered is highlighted in red. Error message is shown to highlight the invalid field to tell the user what is wrong.
-
Test case:
B.3 Adding a property
- Adding a property with only compulsory fields
-
Test case:
addprop n/Aqua Heights a/195 Paya Lebar 3 #18-32 p/91135235 pr/700000
- Expected: New property should be added to Property List with relevant details.
-
Test case:
- Adding a property with all fields
-
Test case:
addprop n/Skyview a/214 Clementi Ave 2 #09-78 p/98835235 pr/500000 c/bright c/sunny c/big c/square
- Expected: New customer should be added to Property List with relevant details.
-
Test case:
- Adding a property with missing fields
-
Test case:
addprop n/Beta p/91135555
-
Expected: Command entered is highlighted in red. “Invalid command format” error message should be displayed and information regarding the syntax of the
addprop
command should be shown.
-
Test case:
- Adding a property with an invalid field
-
Test case:
addprop n/Beta p/51234567 a/195 Paya Lebar 4 pr/700000
- Expected: Command entered is highlighted in red. Error message is shown to highlight the invalid field to tell the user what is wrong.
-
Test case:
B.4 Listing all customers
Prerequisite: Customer List should be a subset of the original list
- View all customers in database
-
Test case:
listcust
- Expected: Customer List should be shown with all customers in the database. “Listed all customers” should be displayed.
-
Test case:
- Adding parameters to the command
-
Test case:
listcust 1
,listcust p
- Expected: Same behaviour as above.
-
Test case:
B.5 Listing all properties
Prerequisite: Property List should be a subset of the original list
- View all properties in database
-
Test case:
listprop
- Expected: Property List should be shown with all properties in the database. “Listed all properties” should be displayed.
-
Test case:
- Adding parameters to the command
-
Test case:
listprop 1
,listprop p
- Expected: Same behaviour as above.
-
Test case:
B.6 Deleting a customer
Prerequisite: Customer List should have at least 1 customer record.
- Deleting a customer with a valid index
-
Test case:
delcust 1
- Expected: First customer is deleted from the list. Details of the deleted customer is displayed.
-
Test case:
- Deleting a customer with an invalid index
-
Test case:
delcust 0
- Expected: No customer is deleted. Error details shown in the status message.
-
Test case:
delcust x
, wherex
is larger than the total customer count - Expected: No customer is deleted. Error details shown in the status message.
-
Test case:
- Deleting a customer with no index provided
-
Test case:
delcust
- Expected: No customer is deleted. Error details shown in the status message.
-
Test case:
B.7 Deleting a property
Prerequisite: Property List should have at least 1 property record.
- Deleting a property with a valid index
-
Test case:
delprop 1
- Expected: First property is deleted from the list. Details of the deleted property is displayed.
-
Test case:
- Deleting a property with an invalid index
-
Test case:
delprop 0
- Expected: No property is deleted. Error details shown in the status message.
-
Test case:
delprop x
, wherex
is larger than the total property count - Expected: No property is deleted. Error details shown in the status message.
-
Test case:
- Deleting a property with no index provided
-
Test case:
delprop
- Expected: No property is deleted. Error details shown in the status message.
-
Test case:
B.8 Editing a customer
Prerequisite: Customer List should have at least 1 customer record.
- Editing the first customer with valid index and valid fields
-
Test case:
editcust 1 n/Andrew e/andrew@gmail.com
- Expected: The name and email fields of the first customer should be updated.
-
Test case:
- Attempting to edit with an invalid index
-
Test case:
editcust 0 n/Andrew
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
- Attempting to edit a customer with valid index but without valid fields
-
Test case:
editcust 1
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.9 Editing a property
Prerequisite: Property List should have at least 1 property record.
- Editing the first property with valid index and valid fields
-
Test case:
editprop 1 n/Asiatique p/98765432
- Expected: The name and phone number fields of the first property should be updated.
-
Test case:
- Attempting to edit with an invalid index
-
Test case:
editprop 0 n/Asiatique
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
- Attempting to edit a property with valid index but without valid fields
-
Test case:
editprop 1
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.10 Finding customers
Prerequisite: A customer that has ‘Tim’ in his name must exist in the customer list.
- Finding customers with “Tim” substring in their name
-
Test case:
findcust Tim
- Expected: Customer List should be filtered to contain only customers that start with the “Tim” substring in their name. (e.g. Timothy, Lee Timmy, Tim Cook) It should be case-insensitive. “x customers listed” should be displayed, where x refers to the number of customers in the new filtered list.
-
Test case:
- Attempting to find a customer with no substring
-
Test case:
findcust
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.11 Finding properties
Prerequisite: A property that has ‘Sky’ in his name must exist in the property list.
- Finding properties with “Sky” substring in their name
-
Test case:
findprop Sky
- Expected: Property List should be filtered to contain only properties that start with the “Sky” substring in their name. (e.g. Skyvista, The Skyrim, Sky View) It should be case-insensitive. “x properties listed” should be displayed, where x refers to the number of properties in the new filtered list.
-
Test case:
- Attempting to find a property with no substring
-
Test case:
findprop
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.12 Filtering customers
Prerequisite: A customer that has a budget of 100,000 and has ‘bright’ in his characteristics must exist in the customer list.
- Filter customers with valid budget and characteristics
-
Test case:
filtercust b/100000 c/bright
- Expected: Customer List should be filtered to contain only customers that have budgets of at least 100000 or more and has at least one tag named “bright”.
-
Test case:
- Invalid filter formats
-
Test case:
filtercust
,filtercust 1
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.13 Filtering properties
Prerequisite: A property that has a price of 500,000 and has ‘big’ in his characteristics must exist in the price list.
- Filter properties with valid price and characteristics
-
Test case:
filterprop pr/500000 c/big
- Expected: Property List should be filtered to contain only properties that have prices of 500000 or less and has at least one tag named “big”.
-
Test case:
- Invalid filter formats
-
Test case:
filterprop
,filterprop 1
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.14 Matching properties to a customer
Prerequisite: At least 1 customer record.
- Match properties which are suitable for a customer
-
Test case:
matchcust 1
- Expected: Properties with prices less than or equal to the budget of customer 1 will be shown. If the customer has existing tags, only properties with at least 1 matching tag will be shown. If the customer has no tag, only the budget requirement needs to be met.
-
Test case:
- Invalid match formats
-
Test case:
matchcust
,matchcust 0
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.15 Matching customers to a property
Prerequisite: At least 1 property record.
- Match customers which are suitable for a property
-
Test case:
matchprop 1
- Expected: Customers with budgets more than or equal to the price of property 1 will be shown. If the property has existing tags, only customers with at least 1 matching tag will be shown. If the property has no tag, only the price requirement needs to be met.
-
Test case:
- Invalid match formats
-
Test case:
matchprop
,matchprop 0
- Expected: Command is highlighted red and error message will be displayed.
-
Test case:
B.16 Clearing the application
- All data should be cleared
-
Test case:
clear
- Expected: All data from customer list and property list should be cleared.
-
Test case:
- Extra parameters added
-
Test case:
clear 123
,clear hello
- Expected: All data from customer list and property list should be cleared.
-
Test case:
B.17 Viewing help
- Help window should be cleared
-
Test case:
help
- Expected: Window containing PropertyMatch’s user guide should be shown.
-
Test case:
- Extra parameters added
-
Test case:
help 123
,help hello
- Expected: Window containing PropertyMatch’s user guide should be shown.
-
Test case:
B.18 Exiting the application
- Application should exit after 3 seconds
-
Test case:
exit
- Expected: Application should exit after 3 seconds.
-
Test case:
- Extra parameters added
-
Test case:
exit 123
,exit hello
- Expected: Application should exit after 3 seconds.
-
Test case:
Appendix C: Proposed enhancements
C.1 Improved GUI
C.1.1 Motivation
Our current GUI is not as user-friendly as we would like it to be. A well-designed and aesthetic GUI provides a more intuitive and user-friendly interface, making it easier for users to navigate, access features, and perform tasks within the app. It can also lead to higher user satisfaction.
C.1.2 Implementation
- Update the color scheme to make the GUI more visually appealing. Use colors that resonate with our brand or that create a pleasant atmosphere.
- Integrate relevant icons and imagery to represent different features and functions within the app, providing visual cues for users.
- Add whitespace effectively to create a clean and organized layout and reduce visual clutter.
- Add user guidance. Provide tooltips, hints, or tutorials for new users to help them get started and understand the app’s features.
C.2 Improved Error Messages
C.2.1 Motivation
Some of our current error messages can be quite vague. As a user, this can be hard for them to decipher what is wrong. Upon receiving the error message, they may not know what is wrong. Knowing what they entered wrongly can lead to higher user satisfaction.
C.2.2 Implementation
- Update the error messages to be more specific. For example, if the user enters an invalid command, the error message should tell the user which part of the command is invalid, instead of just saying that the command is invalid.
- Allow the
INDEX
for commands to accept very large numbers. Currently, the computer is unable to parse the number because it is too large, and PropertyMatch will mention that the command is invalid instead of mentioning that the number is too large.
C.3 Importing client data
C.3.1 Motivation
We realise that many property agents already have existing customers and properties. They may not want to manually enter all the data into the application. This feature will allow them to import their existing data into the application, saving them time and resources.
C.3.2 Implementation
- Add an
Import
button to the menu bar. - Create a file selection mechanism in which the user can import data from CSV files.
- Parse and process the data in the file.
- Validate the imported data to ensure it meets expected standards.
- Add the data fields to PropertyMatch.
- Provide clear feedback to the user about success/failure (success message or error message).
- Implement error handling, logging, and security measures.
C.4 Exporting client data
C.4.1 Motivation
We realise that many property agents may want to export their existing data in PropertyMatch to other platforms. This feature will allow them to easily export their data into other platforms to perform other functions (such as data analysis) not supported on PropertyMatch.
C.4.2 Implementation
- Add an
Export
button to the menu bar. - Create a file selection mechanism in which the user can import data from CSV files.
- Convert the data in the json files to CSV file.
- Allow the user to name the CSV file.
- Provide clear feedback to the user about success/failure (success message or error message).
- Implement error handling, logging, and security measures.
C.5 Ability to filter data less strictly
C.5.1 Motivation
Right now, the filter
commands require all characteristics to match the customer’s or property’s characteristics. This is too strict, and may not be useful for the property agent. This feature will allow the property agent to filter customers or properties based on a subset of characteristics.
C.5.2 Implementation
- Allow
filter
commands to take in an extra parameter calledloose
. - Add code to filter customers/properties that only match one of the criteria.
- Implement error handling and logging.
C.6 Budget for customer should be a range
C.6.1 Motivation
Customers should be able to indicate their budget as a range instead of a set number. This is because customers may not have a fixed budget, and may be willing to pay more or less for a property.
C.6.2 Implementation
- Add code in
Budget
to have a range of values. - Add test cases to verify that
find
,filter
,match
still works with a budget range. - Implement error handling and logging.
Appendix D: Effort
D.1 Difficulty Level
Overall, the difficulty level of the tP was reasonable. PropertyMatch is evolved from AB3. Once we understood the inner workings of AB3 and how to add commands to the application, the process was relatively simple. However, there were still many things we had to pick up along the way when accomplishing the project.
D.2 Challenges Faced
The main challenge came from having to manage two different kinds of entities – customers and properties. Since AB3 only handled one entity, this meant that there was no model answer for handling two entities. We had to come up with our own design for how to handle two entities, and this took some time to figure out.
We also had to learn new technologies like Git and GitHub. Learning about good code practices as well as the forking workflow, all while working on a moderately large project was a challenge for us. It took us time to resolve some messy merge conflicts.
We were also faced with tight deadlines for the various milestones and submissions. This meant that we had to work efficiently and effectively to meet the deadlines.
D.3 Effort Required
While some commands like edit
and list
were adapted from AB3, there were completely new commands like find
, match
, and filter
. The adapted commands were also heavily modified and separated into separate commands for separate entities, like editcust
and editprop
.
We also had to create multiple new classes for the Property
entity. This also meant that we had to come up with suitable test cases for them as well.
Although seemingly small, we had to tinker with the regex of each command such that it accepts the proper user input that we need. This was a tedious process as we had to test each regex to ensure that it works as intended.
D.4 Achievements of the project
We managed to implement all the features that we set out to do. We also managed to implement the filter
command, which was not in the original plan. We also managed to implement the match
command, which was a challenge for us.
We expanded our technical and non-technical proficiency, and we are proud of our wonderful journey!