PROJECT: EventOrganiser

Overview

EventOrganiser is a desktop application for organisation and management of events. 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.

Summary of

  • Major enhancement: added Event and Poll commands and functionality.

    • What it does: Event-related commands allow event organisers to create, edit and manage events, and users to find and join events. Poll-related commands allow the event organiser to create polls and for participants to vote in the poll.

    • Justification: Events are essential to the event organiser. Polls in the Event are useful for event organisers to decide on a suitable activity, date and time for the event.

    • Highlights:

      • Updated all components: logic, model, storage, UI to support events and polls

      • Integrated Persons into Events: Persons are stored in events by index in storage and in runtime, and events are updated when user are edited or deleted.

      • Implemented dependencies between commands e.g. users should select events before editing

  • Code contributed: [Functional code]

  • Other contributions:

    • Project management:

      • Pushed tags and closed milestones for v1.1 and v1.2 to GitHub.

      • Created PR from team-repo to AB4.

      • Assigned issues after PE dry-run: issue tracker

      • Updated AboutUs.doc: #3

      • Updated ReadMe: #10

      • Updated sample data: #165

    • Documentation:

      • Contributed to portions of User Guide and Developer Guide relevant to my own features as well as User Guide overview. Links can be found below.

      • Contributed to initial draft of User Guide and Developer Guide (e.g. use cases): #3

    • Community:

      • PR comments to team members: #199, #44

Contributions to the User Guide

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

How it works, in brief

  • To use the application, you must first create an account using the addUser command, and then login.

  • If you are not yet logged in, you can still view event details using selectEvent, and find events using findEvent and findEventByTime, and list events using listEvent.

  • Without logging in, you can also use the selectUser, findUser, listUser, listFriends, suggestFriendsByInterests commands.

  • When you are done, simply logout or exit the application.

Organise an event

  • If you are looking to organise an event, you may do so using the addEvent command.

  • After creating the event, you may wish to specify the date, time, or specify only after participants have joined.

  • You may create polls to get participants to vote on the details of the event using addPoll and addPollOption.

  • You can create a special TimePoll using addTimePoll after all participants have joined to decide on a suitable time. This generates poll options based on the NUSMOD schedules of the participants.

  • You may decide to deleteEvent after the event is over, or leave it in the organiser as a form of record.

Join an event

  • If you are looking to join an event as a participant, you may search for an event to join using the findEvent and findEventByTime commands.

  • You can also search for other users using the findUser and listFriends commands to see what events they have joined and join that event as well.

  • After joining the event using joinEvent, you can vote in the polls by displaying the poll details using displayPoll.

  • You can then add options using addOption, or simply vote for an option using vote.

Create and confirm event commands

Create a new event : addEvent

Adds a new event to EventOrganiser.
Format: addEvent n/NAME a/LOCATION [t/TAG] …​

  • Login is required.

  • Adds a new event with the given name, location and any number of tags.

  • Tags must be a single word not separated by spaces.

  • The newly created event will display the logged in user as the event organiser.

  • The event organiser is immediately added as one of the participants.

  • The newly created event will automatically be selected for further editing.

Examples:

  • addEvent n/NUS Tennis Welcome Session a/SOC Canteen t/Public

  • addEvent n/CS1101S Meet-up a/UTown t/ByInvite

Delete an event : deleteEvent

Deletes the specified event from EventOrganiser.
Format: deleteEvent INDEX

  • Deletes the event at the specified INDEX.

  • The index refers to the index number shown in the displayed event list.

  • The index must be a positive integer 1, 2, 3, …​

  • Login is required, and the event can only be deleted by the event organiser.

  • While it is recommended that the event organiser closes the event after it is over, this is not required, in case the details of the event is needed to record-keeping purposes.

Examples:

  • listEvent
    deleteEvent 2
    Deletes the 2nd event in EventOrganiser.

Select an event : selectEvent

Selects an event to be edited.
Format: selectEvent INDEX

  • An event must be selected before setDate, setTime, addPoll, addTimePoll, addOption, and vote commands can be used.

  • The event is automatically selected after you have either created the event using addEvent or joined the event using joinEvent.

  • Selecting an event displays the event participants as well as the polls associated with the event.

  • Each poll in the event is given a unique poll index.

Create a new poll for an event : addPoll

Sets up a new poll for the pre-selected event with the specified name.
Format: addPoll n/POLL_NAME

  • Events must be selected first. Only the event organiser may create a new poll.

  • Multiple polls of the same name are allowed.

  • addPoll n/Date
    Upon adding a new poll, only the index and name of the poll is displayed, as shown. The event organiser can then proceed to add options to the poll. Selecting the event again using the selectEvent command displays the list of all polls in the event.

Create a new time-based poll for an event : addTimePoll

Sets up a new time-based poll for the event with the specified name after all users have joined.
Format: addTimePoll d1/DAY-MONTH-YEAR d2/DAY-MONTH-YEAR

  • This is a special type of poll which generates poll options based on the given date range and the schedules of the participants who have joined the event.

  • The time poll options represent 30 minute slots within the start and end date specified. All event particpants must be free at that slot for it to be in the time poll.

  • The date with prefix d1 represents the start of the given date range and d2 represents the end of the date range.

  • The start date must not be after the end date, and the given dates must not be more than 30 days apart.

  • The time poll does not automatically update if a new user joins the event, and should be created only after all users have joined.

Examples:

  • addTimePoll d1/08-09-2018 d2/10-09-2018

Add options to poll : addOption

Add new poll option in the specified poll.
Format: addOption i/POLL_INDEX o/POLL_OPTION

  • The poll index is the index of the poll in the selected event, which can be viewed by selecting the event using selectEvent.

  • An event must first be selected. As long as you have joined the event, you may add options to the poll.

  • An option can be any string.

  • Time polls do not support adding of options.

  • When options are added and no users have voted, the list of most popular options is empty.

Examples:

  • addOption i/1 o/Play chess
    Adds an option to the first poll of the selected event, where the option is Play chess. This option would be relevant in the context of a poll for an appropriate activity.

  • addOption i/3 o/12 November
    addOption i/3 o/13 November
    In the following example, the options 12 November and 13 November have been added to the poll. Since there are no voters yet, the most popular options list is empty.

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.

Poll feature

Current implementation

This section explains the implementation of the features associated with the Poll class of each Event while detailing some implementation details of the Event class. The relevant commands which are callable by the user to be discussed are:

  • AddPollCommand - adds a new Poll to the event given the name of the poll to be created.

  • AddPollOptionCommand - adds a new poll option to the poll given the poll index and the name of the option to be added.

  • VoteCommand - adds the current user as a voter to the voter list of the given option.

  • AddTimePollCommand - creates a new TimePoll automatically populated with options based on the schedules of the event participants.

For all the above commands, the event must first be selected using the selectEvent command, which will set the currentEvent through the Model#setSelectedEvent() method. This is done to ensure that users do not have to continually specify the event for which the Poll commands are called for every command. This is on top of the currentUser in the Model which was already selected through the LoginCommand.

There are two types of Polls which extends from the abstract class AbstractPoll: Poll and TimePoll. Each AbstractPoll object contains a pollData attribute which is stored as a HashMap<String, UniquePersonList>. The pollData stores each option as a string and the list of voters to that particular option as a UniquePersonList. As can be seen in the class diagram, AbstractPolls also include a unique ID to identify the poll and a poll name. They also support the adding of votes by participants who have joined the event, and the display of the poll details, including the most popular options.

PollClassDiagram

The TimePoll class extends from the abstract AbstractPoll class which is constructed by calling the AddTimePollCommand. This command automatically generates a list of 30 minute time slots based on the schedules of the persons on the event invite list, and a specified date range in the user input. The two dates must not be more than a month apart.

The TimePoll shares most of its functionality with Poll, except that users may not add new options. The TimePoll does not automatically update when new event participants join the event. This is done in order to present existing votes for certain options being removed when additional participants join the event. Hence, the event organiser must wait for all participants to be confirmed before adding a TimePoll.

When storing the Poll object in the Storage component, since the XML format does not support the HashMap format, each entry of the HashMap must be converted to a XmlAdaptedPollEntry. Each XmlAdaptedPollEntry contains the option as a String as well as a list of XmlPersonIndex objects, which serve as pointers to the actual Person objects stored in EventOrganiser. Hence, when the EventOrganiser data is retrieved from storage, the Persons in the list of voters for each option, as well as the Persons in the event participant list, refer to the same Person objects in the list of users of the EventOrganiser. This ensures that when a user is edited or deleted, they are updated or deleted in the poll details accordingly. This functionality is supported by the AbstractPoll#updatePerson() and AbstractPoll#deletePerson() methods.

As an example, the following sequence diagram illustrates the workings of the VoteCommand.

VoteSequenceDiagram

As stated above, since Model already stores the current user and the selected event from prior user commands, the Model can call the correct Event e and currently logged-in user in the addVoteToPoll method. If there is no logged-in user, a NoUserLoggedInException is thrown, and if there is no selected event, a NoEventSelectedException is thrown.

In addition, four other possible exceptions might be thrown by the VoteCommand:

  • A user must have already joined the event as a participant, or be on the invite list in order to vote, failing which, a UserNotJoinedEventException is thrown.

  • A user must not already have voted for that particular option in the poll already. This is enforced by the UniquePersonList, which throws a DuplicatePersonException if someone tries to vote twice.

  • A poll must exist at the given poll index for the selected event, else, an IndexOutOfBoundsException is thrown.

  • The given option must exist in the selected poll, else, an IllegalArgumentException is thrown.

The other commands AddPollCommand and AddPollOptionCommand follow a very similar structure. The sequence diagram within the model for the AddPollCommand is illustrated here:

AddPollSequenceDiagram

In all cases, the contents of the poll is returned to the calling Command object as String through the Poll#displayPoll() method. The displayed details of the poll contains the most popular options, computed using the Poll#getPopularOptions() method. This method returns an empty list if no user has voted for any option yet, i.e. if the most popular option has no voters. A new DisplayPollEvent is then posted to the EventsCenter, which is handled by the PollDisplayPanel in the UI component.

Design considerations

Aspect: The relationship between Poll and TimePoll
  • Alternative 1 (Current implementation): Design them as separate classes which both inherit from an abstract AbstractPoll class.

    • Pros: Allows for future extendability from the AbstractPoll class eg additional types of Polls (location, date) which constrain the option types and include additional features to recommend the best option eg most convenient location by distance for participants.

  • Alternative 2: Allow TimePoll to extend from the Poll class.

    • Pros: The two classes differ only in that TimePoll has the augmented feature of generating options from the schedule of event participants.

    • Cons: Unable to constrain the input and prevent users from adding the wrong format for options into TimePoll, since this would violate the Liskov Substitution Principle.

Aspect: Storage of voters in Poll
  • Alternative 1 (Current implementation): Store the voters as Persons.

    • Pros: All information about the voters are stored. This also allows the application to distinguish between two users of the same name. Future extensions to the application might also require additional details about the voters.

    • Cons: Need for complete reference to the actual person via the XmlPersonIndex class in storage, rather than duplicating the person details. The voter list must also be manually updated every time the person details are updated.

  • Alternative 2: Store only the names of voters.

    • Pros: No need for complete reference to the actual person via the XmlPersonIndex class in storage.

    • Cons: Some persons might share the same name. It is also not extendable for future versions where the data/attributes of the voters might be relevant to computing the best option.