Monday, 30 May 2016

2.3 Ninth Iteration

For this iteration I plan to:

  • Adapt and implement solutions to the feedback that I received from my first user prototype that was launched on the Google Play Store
Risks: The main risks associated with this iteration is that I will be unable to implement all the feedback in time for my submission deadline.

In my seventh iteration, it was addressed to me that users found it hard to identify the status of a shift. Furthermore, from the feedback, it was stated that symbols would be helpful to identify a shift from a swap. Using this feedback, I began to create a strategy that would solve both these issues simultaneous. My solution was to create a series of symbols that would present that status of a shift at any given time. I began to identify that status a shift may have in my application. I came up with four positions that a shift may have during it's life cycle in my application. The four positions are as follows:

  1. Normal i.e Shift has not status at this current time and is just a standard shift.
  2. Pending i.e A shift that a user has added to the swaps table but has yet to receive confirmation of a swap from another employee.
  3. New i.e A new shift resulting from a successful swap.
  4. Urgent i.e A shift that whose date matches the current date.
Each of these positions needed an easily identifiable symbol to be associated with the position that shift is currently in. For the shift with a status of "Pending", a test user suggested using an image of a swing to reinforce the name of the application. The app is called "Swing Shift" and therefore particular user suggested even using the verb "Swing" instead of swaps in some of the app alert dialog, Both aspects of this feedback I was able to adapt. A shift with an "Urgent" status needed a symbol synonymous with time. Therefore, the image that I selected was an icon of an alarm clock.
The most difficult symbols to select were for the shifts with a status of  "Normal" and "New". There I went browsing on a series of apps on my phone for inspiration. When I opened up the Gmail app, I noticed that each email had a symbol of a grey star beside it. On selecting the grey star, it would turn to a yellow star. It is also a very eye catching colour that can be quickly identified and processed. Therefore, I decided to adapt a grey star for the "Normal" shift and a yellow star for the "New" shifts.

As as selecting the symbols for each shift status, a certain amount of logic had to be implemented to allow for the app to identify each shifts current position. To do this, I had to modify the shift table in my database and add two Boolean values. This first value was called "genSwingPhoto" which when true, would generate the swing icon in for the shift. The other Boolean was called "genStarPhoto". This Boolean when true would generate a gold star image for the shift. When both Booleans were false, the image would generate the grey star image. To genereate the alarm clock image, I had to compare the current date to the the date of the shift in question. To access the current date, I had to create a date object and use the currentTimeMillis() method to get the system time. I then had to store the time in an array that was generated by splitting the date object at each space. A similar parsing process was used to access the relevant data in the shift object. When the date values were accessed, using an "if" statement, I could compare and see if they were equal. If they were equal, the alarm clock image would be generated.

Another suggestion from the feedback was that some of the text size in the shift and swaps lists was hard to see. In order to make it clearer, I changed both the font type and size of some of the text values of the shift and swaps. Furthermore, I tested to see what the app would like if a user modified the settings on their device to allow the font to be the largest size possible. After testing this, the app other then the size of the font visually looks identical when compared with the default font size on the device. Therefore, I will inform users that they may increase the font size of their phone if they have difficulty seeing certain information without impeding the user experience on the application.

From the feedback, a bug was discovered. This bug allowed a shift to be swapped multiple times over and over. To fix this, I was able to place a limit on the amount of times a shift can be swapped. Each time a users pushes a shift from their list of shifts into the swaps table, a POST REST call is initiated and the swap is recorded in the swaps table. Therefore, I added logic that would query the swaps table to see if the swap already existed. If it did, I prevented users from swapping that particular shift.

Finally, test users indicated that the current grey colour of the app did not quite fit. The users suggested a brighter, organic colour. After some research, I decided to go with the colour green. The user response to green has been very positive.



Citations: http://www.empower-yourself-with-color-psychology.com/color-yellow.html 
http://www.cultofmac.com/270606/popular-colors-ios-7-app-store-infographic/
http://thenextweb.com/dd/2014/04/01/standing-sea-blue-color-pick-icon/#gref


2.2 Eighth Iteration

For the eighth iteration I had to:

  1. Design and develop an data entry point for my administrations.
Risks:

The main risks in this iteration are data parsing. I need to make sure that the write data value is being entered into the correct column in each row. Failure to achieve this will ultimately corrupt my database. The reason this is that if this project is to a scallable project, there needs to be a minimum amount data that my application needs to function properly. Some companies could have up to 20 columns of data in their employee table in their database. However, my system does not need every single column in the companies database to operate but just a select few. This way, there is a standard that all companies can oblige to when then commit to my system.

For designing the data entry point, I wanted to design a system that could allow administrators to easily transfer large amounts of relevant data needed for system to function correctly while also alternatively able to create a single row in the database tables. The way I envisioned this process is that the administrators of the system would upload a csv file into the web application. The file would match the columns of the appropriate table in the database. The program would then parse the file and create objects for the table. These objects would then be saved into the database. This would allow my system to have a mirror representation of that data in the companies database, which as I have mentioned in the previous iteration, is essential for my application to authenticate users. 

To design the entry point, I needed to research how to create an file upload button in ASP.NET. After some time researching, I was able to locate a forum that depicted how to create such a button. Once I was able to make the button upload a file, I have to create a method that would parse the data into temporary string variables. These variables matched the column names of the table that data was being saved to. The file was parsed by splitting the input file string at each comma and storing this into a string array. Then using a "foreach" loop, I was able to instantiate an instance of the reverent object and populate the that object through it's constructor. After each iteration of the loop, I would save that data to the appropriate table using the method "saveChanges()".  A series of error handling had to be incorporated into this parsing method as at many stages, the file could be either corrupted, not in the right format or even the right file type. The end result was a web app with two data entry points. One location was for uploading employee data to the employee table and another was for creating shifts and again, adding them to the shift table in the database. 

Once this was complete, I created a log in system for the web application that mirrored my application log in. However, as administrators and standard employees will be using the web application, I had to add sufficient logic to examine the position of the user logging in so that the web app could direct them to the appropriate web pages. I managed this aspect of the log in element by creating an "if" statement that would examine the users "JobTitle" attribute. If the job title was set to "Floor Staff", then the user would be directed to an EmployeeController that managed all appropriate views and functions that are associated with the standard user. Similarly, if the user's job title was labeled "HR", then that user was redirected to the AdminController where all the administrator functionality lay.

After this iteration was complete, I successful create a web application that acted as a data entry point for my administrators while also creating a log in fuctionality that can detect the type of user trying to gain access and redirect each user type to their appropiate webpage.

For my next iteration, I plan to start adapting some of the feedback that my application received from going live on the app store.

Citations: http://stackoverflow.com/questions/15680629/mvc-4-razor-file-upload

2.1 Seventh Iteration : Going live on Google Play Store

For this iteration I plan to:

  1. Upload my application to the Google Play Store.
  2. Get some test users to download the app.
  3. Design future iterations based on feedback received.
Risks: The main risks associated with this app or the potential for unexpected crashes when the app goes live on the Google Play Store. Identifying these areas however will enhance the user experience of this app.

Putting the application on the app store was surprising more straight forward then anticipated. Once the app met Google's image icon criteria and the app was given a rating exam, the app was ready to be launched. The only key element was a signed APK. After uploading the signed apk, the app went live.  

Following the apps launch, I managed to get some test users to download my app and sign in with a specific user name and password. I explained briefly how the app operated before letting them test it. After a day or two of testing, I went to my testers for the initial wave of feedback.

The feedback was as follows:
  1. Users found it difficult to identify the status of a shift for example; whether a shift was currently pending, which shifts were their own and which were as a result of a successful swap.
  2. Users found it difficult to see some of the information of the swap. A suggestion was made to emphasis the text related to the day in each row of the shifts list.
  3. It was suggested to add a symbol to identify swaps quickly within the app.
  4. A more lively colour for the app was also suggested, the current colour being grey. 
  5. Users also discovered a bug where they could continuously swap the same shift over and over again with no constrainst on the number of swaps a single shift could preform.
With this feedback, I managed to design my future iterations so that I can address all this feedback and make the app a better experience for my users.

For my next iteration, I plan to develop and design the data entry point for my administrators. 

2.0 Sixth Iteration

For the sixth iteration I plan to:
  1. Design and implement the user log in and registration proportion of my application.
Risks: The main risk are to do with authentication. My application needs to only allow users from a particular company access to the app and prevent the accessibility of casual users and this will breach many data protection legislation that is present today.

Before creating the log in and registration views and operations in code, I needed to identify how I was going to enable a select number of users to log into the application. Essentially, I need to either a user is a genuine employee of the company using my system or not. Therefore, to design my application in this manner, I decided that the best way to authenticate an employee is to use the same primary key attribute that would identify them in the company that they work for. The unique attribute I chose was an unique employee number. This number would take the place of a username. 

Each employee would also create a password associate with their account. However, the problem that arises is how each user creates a password. In general, most applications or web applications need the user to be logged in to their account in order to modify any information relating to the user's profile. To overcome this issue, I designed a registration program that allowed users to input their employee number and email into the correct text boxes. The app would check the user's employee number against the numbers currently in the database. If the user was permitted to continue, a "mailto"
operation would execute on submission. This would cause the user's phone to open a mail related application where the user could see a generated temporary password that they could use to log in to the app. However, after further tests, I found that a user could easy select a non related mail application to open and share their password and username with unauthorized users. As a result, currently only a log in element exists in the application. Yet, I plan to explore the possibility of being able to send a direct email to registering users using android in a future iteration.

In this iteration I successfully was able to create a log in element in my application that authenticates users based on their employee number and a password. The registration factor of the app will be completed in a later iteration. 

1.9 Fifth Iteration

For the fifth iteration I had to:


  1. Outline the logic that needed to take place to allow the swap
  2. Implement that logic
  3. Test the logic
Risks: 

  • The main risks surrounding this iteration are in regard to the logic,  as there are many variables that I must consider. Therefore, maintaining and implementing these rules will be the biggest risk in this iteration.
  • There is also a risk that I will not have identified all the rules and logic surrounding a swap. However, I plan on releasing an "Alpha" version of my application on the Google plan store in order to get multiple users to test the app and its logic. I may be able to identify other rules during that test period that I was not able to initially.
This application is designed to be catered toward each specific company that wishes to use this service. Therefore, there may be some unique logic surrounding each company. For example, company A may have rules that forbid employees from different departments to swap a shift. Alternatively, company B might allow this rule. Therefore, it must be noted that some logic may be unique to each company. However, I will implement a set of base rules that I can assume the majority of companies obey. The unique logic can be added at a later stage and catered to each company.

As stated above, the logic I plan to implement will be a broad set of rules that I can assume most companies obey. Many of the rules are trivial however could seriously break the application if not implemented correctly.

The rules I will implement are as follows:
  1. A shift added into the swaps table cannot be swapped by the employee who added the shift into that table.
  2. A shift cannot be added into the swaps table if the date associated with the shift matches the current date.
  3.  Cannot swap a shift that is currently pending (waiting for an employee to respond to the swap) in the swaps table. 
  4. Cannot swap a shift whose date has already expired.
Rules related to contracted hours are something I need to address. Many companies may have rules relating to how many hours an employee can work in relation to their contract. Some companies wish for their employees to work within their contracted hours while other companies are more flexible, allowing employees to work a broader range of hours making the contract the minimum amount of working hours an employee must adhere to. To overcome this complex issue, I plan to implement logic in a later iteration that will only allow for swaps to take place if they contain an equal amount of working hours. This way, both parties are catered for and that contracted hours are not affected. 

However, the issue is not completely solved. This application has the potential to allow HR to post additional shifts into same a table of "Extra" shifts. Employees looking for extra hours or an additional shift that working week could request that shift and add it to their current roster. Yet, the dilemma in relation to the contracted hours occurs again and even gets more complex as now a employee could potentially work over the legal amount of hours as well as their contracted hours. According to the Irish Organisation of Working Time Act, section two, part 15, "An employer shall not permit an employee to work, in each period of 7 days, more than an average of 48 hours". This would have to be implemented as direct logic into my application in a later iteration when I attempt to construct a table of extra working hours.

Implementing the logic listed from one to four consisted of a serious of "if" statements as I was able to implement quite efficiently as my shift and swap objects consisted of the correct attributes for testing this logic. I the only issue I did encounter was in relation to the pending swap rule. The logic in the rule compares an employees currently list of shifts to the table of swaps. If there is a matching shift, the logic gets executed and does not allow the employee to swap the shift. The issues lay in my REST calls. The REST call would be initiated to fetch all the swaps in the system to allow for a comparison between an employees current list of shifts. As I am using the Volley framework to make these calls, the calls are by default passed into their own threads and executed. As the calls were fetching data, my code would continue to execute even before the swaps data was gathered. This would throw a null pointer exception as there would be no data in the list of swap objects yet. Therefore, to overcome this, I placed my calls in the "OnStart" life cycle of the fragment. This would ensure that the call would be made at the very start of the line of executed code. Furthermore, I created a Boolean trigger that would be set to true when that data was gathered and false otherwise. I surrounded that swap logic with an "if" statement that would only allow access to the user if the trigger was true, ensuring that the correct data was gathered.

Once I had completed the logic, I ran my unit tests that tested each rule to make sure that they were behaving as I had designed them to. 

Overall, I was successful in implemented basic logic and rules associated with the swap process. For my next iteration, I will began my designing a basic log in and register element to my app.

Citations: http://www.irishstatutebook.ie/eli/1997/act/20/section/15/enacted/en/html#sec15 

Saturday, 21 May 2016

1.8 Forth Iteration

For the forth iteration, I had to:


  1. Successfully preform a swap
Even though for this iteration only had one task, there were many other elements and complex components that make this iteration challenging.

Risks: This iteration was heavily dependent on REST calls such as GET, POST and PUT. Therefore the main risks with this are HTTP errors.

As mentioned in the third iteration, the swap will have to be preformed in a way that maintains and follows the Irish data privacy act. Therefore, all shifts in the swap table that are displayed to the user must be anonymous. Therefore, when a swap is initiated, both users in the swap can only see data related to the shifts involved in the process. The user data associated with the shift is hidden from all the users in order to protect each user's personal data.

The general flow of the swap process involved multiple REST calls to my database. What I found the most challenging was that the REST PUT calls sometimes would not be work successfully initially for a multitude of reasons. In my android logger, I could see that the response from my request would be a HTTP error. The three HTTP errors I encountered were, 400, 405 and 500. After researching what the errors meant, I was eventually able to successfully update my database with the PUT request. 

One of the things I ascertained while completing this iteration was the reason why callback functions are created. Multiple times my app would crash with null reference exception due to the fact the my REST call had not yet retrieved the relevant data from the data base however, my code would continue to execute regardless leading to the errors and crashes that I experienced. Therefore, I have made it a priority to look into how callback functions operation in android and try to utilize them in my application if possible.

Overall, I was able to successfully complete a basic swap operation that I set out to accomplish for this iteration. However there is still quite a bit of logic that I wish to include in the swap process that I will complete in the next iteration. It must be noted that this iteration contained the main core functionality of my project. All other elements will fit around this core functionality. 


Sequence diagram of swap


References: http://www.irishstatutebook.ie/eli/1988/act/25/section/2/enacted/en/html#sec2 

Friday, 13 May 2016

1.7 Third Iteration

For the third iteration I had to:

  • Develop a notification service.
  • Figuring out how the swap process will happen.
  • Discover technologies I may need in order to meet the requirements of this iteration.
Risks

The main risk associated with this iteration is lack of knowledge. I need to manage my time efficiently and make sure I do not spend too much time researching for information and not actual develop my project. 

Another risk is the complexity of a push notification. They are not easy to implement. If I cannot figure out how to create a push notification, I will need to rethink how my system will swap a shift.

Third Iteration:

The third iteration, I needed to redesign how a swap will take place in my system. Initially, when I began identifying some of the functionality of the system in iteration one, I thought that the process of a swap would consist of three parties, Employee1, Employee2 and HR. Emplpyee1 can see all the shifts relating to Employee2 and vice versa. However, this is where my problems began. Due to data protection laws, Employee1 can only see data relating to Employee1 and Employee2 can only see data relating to Employee2. This is an issue as the functionality that I designed heavily depends on users being able to see each-others data (ie Shift information). Therefore, I needed to redesign the system.


How the system will preform a swap is as follows:
  1. Employee 1 clicks on one of their own shifts that they wish to swap.
  2. A Push notification is sent to all users (who are suitable) that a shift is up for a swap.
  3. Employee 2 clicks on the notification which brings them to a list of all suitable shifts which they are eligible to swap with. It must be noted that only the shift information is displayed and not the Employee information.
  4. Employee 2 clicks the shift they want to swap with.
  5. They then select one of their shifts current shifts to swap.
  6. The swap then then gets stored stored in a database, waiting for HR to authorize the swap.
  7. Once the swap is authorize, the shift table gets updated and the swap is deleted from the DB.
The main hurdle in this iteration is the push notification. After extensive research, I continued to encountered a service called "Google Cloud Messaging". This service is second cloud database that acts as a middle man between your app and database. Each user is given a unique key from GCM which then is sent to the DB. Then, when a notification needs to be created and sent to X amount of users, the DB sends all the keys relative to the users to GCM which in turn then sents the notification to the users. Sounds complex? Its because it is!After many hours, I unsuccessfully managed to set up this service with my current project. I felt that it was time to move on the find a new solution to this problem. The solution however came from an unexpected resource.

To solve the issue, I turned back to Firebase. In iteration one I became familiar with Firebase as I was using it as my main back end service. One of the methods build into Firebase is called "OnChildAdded". This method is triggered when an item is added into the Firebase DB. I was able to incorporate this functionality to develop a push notification as follows:
  1. When a user wants to swap a shift, they push they shift they want to swap to Firebase.
  2. In Firebase, there is a generic "Shift" table. The shift in question is then added to the Firebase table.
  3. This in turn triggers the OnChildAdded method as the table has been updated. 
  4. When triggered, a notification is created and sent to all users notifying that a shift is as I call it "up for grabs".
  5. The user then can click into this notification and see all the information about the shift.
This method successfully created a notification. The only issues actually seem to be with the lifecycle of the notification. The user can only see notifications if the application is not in the "OnDestroy" cycle. Otherwise the user will receive them. Furthermore, occasionally the notification does not go when the user clicks into it. However, overall I am happy with what I have so for accomplished. The issues with the notifications I feel I will be able to solve over time. But because I am under time constraints, will suffice for now.