<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Magavade</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Magavade"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Magavade"/>
	<updated>2026-05-16T21:10:49Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131183</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131183"/>
		<updated>2019-12-07T20:53:27Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Relevant Tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. &lt;br /&gt;
&lt;br /&gt;
Potential ways of displaying the Cake question on the UI:&lt;br /&gt;
&lt;br /&gt;
* Stars: Existing design for teammate reviews uses stars to symbolize the contribution provided by each student. We can implement the cake type using the same.&lt;br /&gt;
Cons: Stars are not very versatile when there are a greater number of students per team and if the student wants to equally rate their contribution.&lt;br /&gt;
&lt;br /&gt;
* Drop Down: In order to give the student more flexibility, another way a student can pick the contribution of each team member is using a dropdown of the % values.&lt;br /&gt;
Cons: Drop down values need to be restricted to intervals of 5 or more, as the drop down becomes too long to display all values from 0-100.&lt;br /&gt;
&lt;br /&gt;
* Text box with up-down arrows: Provides utmost flexibility and precision to the student while adding contribution of his team members, we can provide a text box with necessary validations which lets the student provide the contribution % for his teammates as any integral number within the limits. &lt;br /&gt;
&lt;br /&gt;
We decided to implement the text box, looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Screen_Shot_2019-12-07_at_3.07.57_PM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach:===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
Actors involved:&lt;br /&gt;
&lt;br /&gt;
*TA/Instructor: Responsible for making a questionnaire, includes a Cake question, and assigns the questionnaire to the required assignments. S/he also decides on enabling the inclusion of 'Self' for Cake question type contributions. The percentage calculation differs accordingly.&lt;br /&gt;
&lt;br /&gt;
*Student: Fills out the reviews, and chooses answers in accordance with the Cake question type imposed restrictions, if there is one. In this use case, the ResponseMap thus generated is restricted to TeammateReviewResponse, as Cake question would be used for grading contributions of team members.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For querying the model to get other answers submitted by a Reviewer for a particular question for his Team, we get the Team ID using his Participant ID for the Assignment.&lt;br /&gt;
From the Team ID, we get the rest of the Team Users (referred to as Reviewees in the ResponseMaps generated), and then the Reviewer's answers for the other Reviewees.&lt;br /&gt;
&lt;br /&gt;
We restrict the query to not include the current Reviewer-Reviewee combination, as we need to exclude it in case the user is editing his previous submits.&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131182</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131182"/>
		<updated>2019-12-07T20:46:23Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131181</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131181"/>
		<updated>2019-12-07T20:44:10Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131180</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131180"/>
		<updated>2019-12-07T20:29:05Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131179</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131179"/>
		<updated>2019-12-07T20:24:28Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131178</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131178"/>
		<updated>2019-12-07T20:22:09Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131177</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131177"/>
		<updated>2019-12-07T20:21:24Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-12-07 at 3.07.57 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131176</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131176"/>
		<updated>2019-12-07T20:20:54Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Proposed Solution: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. &lt;br /&gt;
&lt;br /&gt;
Potential ways of displaying the Cake question on the UI:&lt;br /&gt;
&lt;br /&gt;
* Stars: Existing design for teammate reviews uses stars to symbolize the contribution provided by each student. We can implement the cake type using the same.&lt;br /&gt;
Cons: Stars are not very versatile when there are a greater number of students per team and if the student wants to equally rate their contribution.&lt;br /&gt;
&lt;br /&gt;
* Drop Down: In order to give the student more flexibility, another way a student can pick the contribution of each team member is using a dropdown of the % values.&lt;br /&gt;
Cons: Drop down values need to be restricted to intervals of 5 or more, as the drop down becomes too long to display all values from 0-100.&lt;br /&gt;
&lt;br /&gt;
* Text box with up-down arrows: Provides utmost flexibility and precision to the student while adding contribution of his team members, we can provide a text box with necessary validations which lets the student provide the contribution % for his teammates as any integral number within the limits. &lt;br /&gt;
&lt;br /&gt;
We decided to implement the text box, looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Screen_Shot_2019-12-07_at_3.07.57_PM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach:===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
Actors involved:&lt;br /&gt;
&lt;br /&gt;
*TA/Instructor: Responsible for making a questionnaire, includes a Cake question, and assigns the questionnaire to the required assignments. S/he also decides on enabling the inclusion of 'Self' for Cake question type contributions. The percentage calculation differs accordingly.&lt;br /&gt;
&lt;br /&gt;
*Student: Fills out the reviews, and chooses answers in accordance with the Cake question type imposed restrictions, if there is one. In this use case, the ResponseMap thus generated is restricted to TeammateReviewResponse, as Cake question would be used for grading contributions of team members.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131175</id>
		<title>File:Screen Shot 2019-12-07 at 3.07.57 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-12-07_at_3.07.57_PM.png&amp;diff=131175"/>
		<updated>2019-12-07T20:18:47Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131174</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131174"/>
		<updated>2019-12-07T20:18:28Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Proposed Solution: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. &lt;br /&gt;
&lt;br /&gt;
Potential ways of displaying the Cake question on the UI:&lt;br /&gt;
&lt;br /&gt;
* Stars: Existing design for teammate reviews uses stars to symbolize the contribution provided by each student. We can implement the cake type using the same.&lt;br /&gt;
Cons: Stars are not very versatile when there are a greater number of students per team and if the student wants to equally rate their contribution.&lt;br /&gt;
&lt;br /&gt;
* Drop Down: In order to give the student more flexibility, another way a student can pick the contribution of each team member is using a dropdown of the % values.&lt;br /&gt;
Cons: Drop down values need to be restricted to intervals of 5 or more, as the drop down becomes too long to display all values from 0-100.&lt;br /&gt;
&lt;br /&gt;
* Text box with up-down arrows: Provides utmost flexibility and precision to the student while adding contribution of his team members, we can provide a text box with necessary validations which lets the student provide the contribution % for his teammates as any integral number within the limits. &lt;br /&gt;
&lt;br /&gt;
We decided to implement the text box, looks as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach:===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
Actors involved:&lt;br /&gt;
&lt;br /&gt;
*TA/Instructor: Responsible for making a questionnaire, includes a Cake question, and assigns the questionnaire to the required assignments. S/he also decides on enabling the inclusion of 'Self' for Cake question type contributions. The percentage calculation differs accordingly.&lt;br /&gt;
&lt;br /&gt;
*Student: Fills out the reviews, and chooses answers in accordance with the Cake question type imposed restrictions, if there is one. In this use case, the ResponseMap thus generated is restricted to TeammateReviewResponse, as Cake question would be used for grading contributions of team members.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131173</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131173"/>
		<updated>2019-12-07T20:01:14Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Use Case Diagram */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. We intend to keep the Cake type input in the form of the number of stars, on the lines of the existing code. &lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach:===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
Actors involved:&lt;br /&gt;
&lt;br /&gt;
*TA/Instructor: Responsible for making a questionnaire, includes a Cake question, and assigns the questionnaire to the required assignments. S/he also decides on enabling the inclusion of 'Self' for Cake question type contributions. The percentage calculation differs accordingly.&lt;br /&gt;
&lt;br /&gt;
*Student: Fills out the reviews, and chooses answers in accordance with the Cake question type imposed restrictions, if there is one. In this use case, the ResponseMap thus generated is restricted to TeammateReviewResponse, as Cake question would be used for grading contributions of team members.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131172</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131172"/>
		<updated>2019-12-07T19:48:57Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Why we chose this approach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. We intend to keep the Cake type input in the form of the number of stars, on the lines of the existing code. &lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach:===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131171</id>
		<title>CSC/ECE 517 Fall 2019 - E1992. Add cake type to rubrics design</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1992._Add_cake_type_to_rubrics_design&amp;diff=131171"/>
		<updated>2019-12-07T19:47:52Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Problem Definition: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction:==&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source application running on Ruby on Rails. It is used for management of courses and the assignments for respective courses, by the faculties and the students. Students can form teams in expertiza to work on an assignment in a group. A student team can submit their work through multiple means such as file uploads and embedded links. Expertiza also consists of questionnaires which can be leveraged for many tasks one of them being peer evaluation of submissions. Students can also review their teammates, making use of the teammate review questionnaire, based on their contribution to the projects.&lt;br /&gt;
&lt;br /&gt;
==Problem Definition:==&lt;br /&gt;
&lt;br /&gt;
Expertiza rubrics are utilized to build questionnaires and these rubrics incorporate several kinds of items, including Criterion (dropdown + comment), Checkbox, MultipleChoice, and Scale.  When we use these questionnaires for reviews, for example the teammate review assessment we encounter a few problems. One “problem” with all of these types is that there is nothing to stop a reviewer (say some student) from assigning the maximum score to all the reviewees (student's teammates). This is indeed a problem for teammate assessment, when the faculty asks for what fraction of the work each teammate did.So an alternative is needed, let’s call it a “Cake” item type, that allows a reviewer to divide a “cake” in any way between the reviewees, but does not allow him/her to divvy up more than 100% of the cake.&lt;br /&gt;
&lt;br /&gt;
#When the reviewer submits a score that would bring the total assigned for this item to &amp;gt; 100%, the system needs to warn. &lt;br /&gt;
#Allow a reviewer to give him/herself a score&lt;br /&gt;
# Proposed design needs to be compatible with existing self reviews code and teammates reviews&lt;br /&gt;
# Should be extensible to other kind of reviews apart from teammate reviews as well&lt;br /&gt;
&lt;br /&gt;
[[File:1_hjrnZknuFZswxaOKFCrDjQ.png|center]]&lt;br /&gt;
&lt;br /&gt;
For instance, the above figure consists of a team of 4 members, with self included as a team-member when reviewing every member's contribution.&lt;br /&gt;
&amp;lt;br&amp;gt;If A has reviewed his other 3 teammates B, C, D with contributions of 15%, 10%, and 45% respectively, he should only be allowed to review self with a contribution of 30% or lesser.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Proposed Solution:===&lt;br /&gt;
&lt;br /&gt;
The issue asks us to have a Cake type for the question taking in a participant’s contribution, whenever s/he is reviewing the other teammates. We add in a new Question type ‘Cake’, which will be extended from the Scored Question model [cake &amp;lt; scored question &amp;lt; choice question &amp;lt; question]. We intend to keep the Cake type input in the form of the number of stars, on the lines of the existing code. &lt;br /&gt;
&lt;br /&gt;
Addressing self-reviews for Cake Type:&lt;br /&gt;
&lt;br /&gt;
The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. The point whether the distribution of the cake should include the reviewer himself, is addressed on the basis of the enabling of ‘Self-Review’. If enabled, we include the self contribution to sum it up to one unit (for instance, five stars.) If not, we exclude the reviewer.&lt;br /&gt;
&lt;br /&gt;
There are two ways to integrate the Cake type to the existing flow:&lt;br /&gt;
&lt;br /&gt;
*'''Solution''': Self-review at team level as an instance of TeammateReviewResponseMap&lt;br /&gt;
&lt;br /&gt;
In the current system workflow, we found that the teammate reviews are taken as instances of TeammateReviewResponseMap. The questionnaire for reviewing teammates includes the question asking the cake (contribution) factor. Ideally, the cake should include the reviewer himself as well.&lt;br /&gt;
&lt;br /&gt;
Currently, whenever a participant is reviewing his teammates, s/he is displayed a page with his current teammates, and this page excludes the logged in user. We include the logged in user ID as well by removing this check, and let him submit his self-review with the same questionnaire as his other teammates have.&lt;br /&gt;
&lt;br /&gt;
The Teammate Review page would be displayed as:&lt;br /&gt;
&lt;br /&gt;
[[File:Oodd_copy.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Steps to reproduce the proposed workflow:&lt;br /&gt;
#Log in to expertiza to view the home page&lt;br /&gt;
#Login as an Instructor, and then impersonate a student or login as a Student&lt;br /&gt;
#Go to Assignments -&amp;gt; Your team&lt;br /&gt;
#You will see a list of your teammates, including self: Choose a member and click on ‘View’&lt;br /&gt;
#You can see the question for asking the contribution as a cake type&lt;br /&gt;
#There will be a text description next to it denoting what part of the cake is taken (what contribution factor of the work is used)&lt;br /&gt;
&lt;br /&gt;
===Why we chose this approach===&lt;br /&gt;
The initial idea for this project was to make use of the existing feature for self-review, when a team member reviews his/her contribution to the team. But after considering code that also involves teammate reviews, what we have observed is that every assignment has the option to render reports to the instructor - showcasing different types of reports such as Review Reports, Teammate Review Reports, Self Review Reports, Answer Tagging reports. If the existing self-review feature were to be implemented, the view for the Self Review reports would also contain self-teammate reviews, which would cause inconsistencies in rendering Self Review Reports, and does not help serve the purpose of a legible report. &lt;br /&gt;
&lt;br /&gt;
Thus, keeping self-teammate reviews as an instance of TeammateReview would help the instructor in evaluating all the reviews in one go, as the view that gets rendered is shown below: &lt;br /&gt;
[[File:ReviewReport.png|center]]&lt;br /&gt;
Here, for simplicity, the assignment - Assignment_Example can have teams with maximum of 2 participants. Consider Student8529, who has reviewed himself and his teammate Student8663. With the design approach taken for this project, when Student8529 reviews himself, the review would appear under the Teammate reviewed, under the Teammate review report. This would certainly help instructors verify reviews in a much simpler manner. The design also ensures minimal code change to existing code.&lt;br /&gt;
&lt;br /&gt;
==Use Case Diagram==&lt;br /&gt;
[[File:UseCaseExpertizaCake.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
A new class Cake has been newly introduced as a subclass of ScoredQuestion. The Cake class is a type of question that can be offered as part of any questionnaire, which keeps an account of all the answer values recorded for one specific question. The maximum value that can be given to a question of type cake is 100, and any value entered above 100 is automatically void, setting the answer entered to zero by default. The user is informed of the same and also can keep track of how much of the “cake” has already been taken, which helps him determine the value that he can enter. Upon entering a value greater than 100, a warning is displayed, informing the user that the value has exceeded 100, and setting the value back to 0. A textbox input with up-down arrows is being used, to help the user increment/decrement values as he pleases. &lt;br /&gt;
&lt;br /&gt;
The general makeup in expertiza for different type of questions is that each question has the following methods: &lt;br /&gt;
edit(_count)&lt;br /&gt;
View_question_text&lt;br /&gt;
complete()&lt;br /&gt;
view_completed_question()&lt;br /&gt;
&lt;br /&gt;
The parameters for the last two methods - complete and view_completed_question vary, depending on the type of question. These methods are responsible for rendering html code onto the view in which they are being referenced. Similarly, the following methods have been added to cake.rb :&lt;br /&gt;
&lt;br /&gt;
edit(_count)&lt;br /&gt;
[[File:EditCake.png|center]]&lt;br /&gt;
The edit method is called on the initial questionnaire creation, and the view on the browser is as shown below: &lt;br /&gt;
[[File:EditCake1.png|center]]&lt;br /&gt;
The method is invoked from the questionnaire/edit.html.erb file. &lt;br /&gt;
&lt;br /&gt;
View_question_text&lt;br /&gt;
The following code has been added to this method: &lt;br /&gt;
[[File:ViewQuestion.png|center]]&lt;br /&gt;
The method is invoked from the view questionnaire option (questionnaire/view.html.erb),  on each questionnaire, showing the text for the question, type (being cake) and weight (default 1).&lt;br /&gt;
&lt;br /&gt;
view_completed_question()&lt;br /&gt;
Snippet of the code is shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion.png|center]]&lt;br /&gt;
The method is called when the user/participant wants to view or review his/her. The screen for the same when a cake type question is added to the teammate review is as shown below: &lt;br /&gt;
[[File:ViewCompletedQuestion1.png|center]]&lt;br /&gt;
The cake type question will always have a green circle in the background, rending the score on top of it. The method is called from the response/view.html.erb file. &lt;br /&gt;
&lt;br /&gt;
In order to enable a student to review him/herself as a teammate we have implemented self reviews for teammate assessment. We have incorporated a checkbox in the review strategy tab of creating/ editing an assignment which will allow the instructor to either enable or disable this feature. We added the following code to '''assignments/edit/_review_strategy.html.erb''' file as follows: &lt;br /&gt;
[[File:SelfReviewCode.png|center]]&lt;br /&gt;
&lt;br /&gt;
We also included a warning for the instructor, incase they try to enable self teammate reviews after creating the assignment and after some of the students have given their reviews. Since, enabling this feature would cause inconsistencies in data with respect to cake. For example: In teammate review assessment, let there be a cake type question about the amount of contribution provided by each team member. Previously, the cake should be split between all the other team members apart from the author. After enabling self reviews, cake has to include the author as well. &lt;br /&gt;
The warning is implemented as follows: &lt;br /&gt;
[[File:SelfReviewCode2.png|center]]&lt;br /&gt;
&lt;br /&gt;
#Edited '''student_teams/view.html.erb''' to add reviewer to list of displayed teammates and show review link if self review is enabled&lt;br /&gt;
[[File:StudentTeamsView.png|center]]&lt;br /&gt;
&lt;br /&gt;
'''Other Changes'''&lt;br /&gt;
#Edit '''questionnaire/_questionnaire.html.erb''': Add Cake to the list question types&lt;br /&gt;
#Edit '''questionnaires_controller.rb''', under “add_new_questions” method, adding a cake type and handle the changes. &lt;br /&gt;
#Edit '''response/response.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
#Edit '''response/view.html.erb''' and add cake type questions to the displayed response.&lt;br /&gt;
&lt;br /&gt;
==Database Modification==&lt;br /&gt;
In order to implement the self review feature for teammate reviews we have added a column &amp;quot;is_self_teammate_review_enabled&amp;quot; to the assignments table. Below is the migration for the same: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; class SelfTeammateReview &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
	add_column :assignments, :is_self_teammate_review_enabled, :boolean, :default =&amp;gt; false&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Database Design==&lt;br /&gt;
Below is the simplified version of the ER diagram which displays the relationships between the entity sets. &lt;br /&gt;
&lt;br /&gt;
[[File:ER diagram.png|center]]&lt;br /&gt;
&lt;br /&gt;
===Relevant Tables===&lt;br /&gt;
[[File:Database.png|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan: ==&lt;br /&gt;
====Test Details:====&lt;br /&gt;
====UI Testing====&lt;br /&gt;
&lt;br /&gt;
*Reviewing teammates (happy case when contribution is &amp;lt; 100%)&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#Click on review link for a fellow team member&lt;br /&gt;
#Fill the responses for the given questions (which include cake type questions as well) &lt;br /&gt;
#Save the review&lt;br /&gt;
&lt;br /&gt;
*Giving &amp;gt; 100% for cake questions &lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates under team members&lt;br /&gt;
#While reviewing a teammate, a student gives 60% as contribution to teammate1 &lt;br /&gt;
#When he tries to give &amp;gt; 40% for the teammate2. He should see a warning that states that total of the cake is exceeding 100%&lt;br /&gt;
&lt;br /&gt;
*Context: Self reviews can be enabled/ disabled for an assignment as per the choice of the instructor. &lt;br /&gt;
#Self reviews enabled&lt;br /&gt;
#A student logs on to expertiza and clicks on an assignment &lt;br /&gt;
#Then he clicks on your team link&lt;br /&gt;
#He should be able to see his teammates and himself (for self review) under team members&lt;br /&gt;
#Total contribution for a cake type question in a teammate review should include the contribution provided by the student in the self review as well. &lt;br /&gt;
#If the contribution is exceeded, a warning should appear&lt;br /&gt;
&lt;br /&gt;
*Self review disabled&lt;br /&gt;
#The link for a reviewer to review himself as a team member should not show&lt;br /&gt;
#The cake type questions in the teammate review should include only contributions provided by the other team members&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is enabled after the assignment has been created and a few students have already given reviews, then it should give a warning. &lt;br /&gt;
#Self review enabled in the middle of the assignment&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 (make sure it adds upto 100%)&lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#As a student, notice that a new review button is visible in the “your team” page. &lt;br /&gt;
#Click on review, try to add contribution for self and make sure a warning appears that says that the cake is already at 100%&lt;br /&gt;
&lt;br /&gt;
*Context: If self review is disabled after the assignment has been created and a few students have already given reviews.&lt;br /&gt;
#Self review disabled in the middle of the assignment &lt;br /&gt;
#Enable self review as an instructor&lt;br /&gt;
#Add teammate review for teammate1&lt;br /&gt;
#Add teammate review for teammate2 &lt;br /&gt;
#Add self review (make sure it adds upto 100%)&lt;br /&gt;
#Disable self review as an instructor&lt;br /&gt;
#As a student, notice that the review button is NOT visible in the “your team” page&lt;br /&gt;
&lt;br /&gt;
====Automated testing using Rspec==== &lt;br /&gt;
&lt;br /&gt;
Both Rspec and Capybara with Rspec tests have been written, with the capybara file - cake_questionnaire.rb added to spec/features folder, and rspec model file - cake_spec.rb added to the spec/models folder. The capybara test creates a new questionnaire by logging into expertiza as instructor6, and adds the cake type questions to the questionnaire. &lt;br /&gt;
[[File:Testing1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Several other test cases such as successful login into expertiza, along with testing the two main scenarios (shown in the snippet above) had been tested. The question_type is a list of values which contain all types of questions, which includes the question type cake. The test cases pass, on creation of a review questionnaire and on creation of a questionnaire with different types of questions, including the cake type questions to the questionnaire rubric. &lt;br /&gt;
&lt;br /&gt;
The RSpec testing has been done on the cake.rb model, and has resulted in a decent code coverage of 82.73% and sample code can be seen in the snippet below: &lt;br /&gt;
[[File:Testing2.png|center]]&lt;br /&gt;
&lt;br /&gt;
With most of the code on the model is rendering html code, the correctness of the html code has been tested, to check if rspec also results in code that is expected. &lt;br /&gt;
To run and verify Rspec results, please do run the following commands from the expertiza folder: &lt;br /&gt;
&lt;br /&gt;
rspec spec/models/cake_spec.rb&lt;br /&gt;
rspec spec/features/cake_questionnaire.rb &lt;br /&gt;
&lt;br /&gt;
With the right gems installed, the test cases should ideally pass. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Team ==&lt;br /&gt;
&lt;br /&gt;
'''Mentor''': Carmen Bentley (cnaiken@ncsu.edu)&lt;br /&gt;
*Mita Gavade (magavade@ncsu.edu)&lt;br /&gt;
*Srujana Rachakonda (srachak@ncsu.edu)&lt;br /&gt;
*Ram Chavali (rlchaval@ncsu.edu)&lt;br /&gt;
*Abhirav Kariya (akariya@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:1_hjrnZknuFZswxaOKFCrDjQ.png&amp;diff=131170</id>
		<title>File:1 hjrnZknuFZswxaOKFCrDjQ.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:1_hjrnZknuFZswxaOKFCrDjQ.png&amp;diff=131170"/>
		<updated>2019-12-07T19:42:29Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127655</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127655"/>
		<updated>2019-11-07T00:46:27Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127653</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127653"/>
		<updated>2019-11-07T00:45:17Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127643</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127643"/>
		<updated>2019-11-07T00:42:34Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127640</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127640"/>
		<updated>2019-11-07T00:41:54Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127635</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127635"/>
		<updated>2019-11-07T00:41:21Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127286</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127286"/>
		<updated>2019-11-06T15:18:25Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier/populated:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
::3. Whenever the user-entered Topic Drop Deadline is earlier than the Submission Deadline, we set the date as per (1).&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127285</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127285"/>
		<updated>2019-11-06T15:18:02Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier/populated:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case &lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
::3. Whenever the user-entered Topic Drop Deadline is earlier than the Submission Deadline, we set the date as per (1).&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127156</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127156"/>
		<updated>2019-11-05T20:18:10Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127155</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127155"/>
		<updated>2019-11-05T20:18:00Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127154</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127154"/>
		<updated>2019-11-05T20:17:48Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127153</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127153"/>
		<updated>2019-11-05T20:17:18Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127152</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127152"/>
		<updated>2019-11-05T20:17:00Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127151</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127151"/>
		<updated>2019-11-05T20:16:39Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Issues in the Current Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127150</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127150"/>
		<updated>2019-11-05T20:16:32Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* About Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127149</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127149"/>
		<updated>2019-11-05T20:16:18Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127148</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127148"/>
		<updated>2019-11-05T20:16:03Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Files modified in Current Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127145</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127145"/>
		<updated>2019-11-05T19:56:05Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Topic Drop Deadline is not defined, we set the default based on the following dates, whichever is earlier:&lt;br /&gt;
:::a. Topic Submission Deadline&lt;br /&gt;
:::b. Assignment Drop Topic Deadline&lt;br /&gt;
:::c. Assignment Submission Deadline&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127131</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127131"/>
		<updated>2019-11-05T18:30:13Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier, and schedule a job accordingly.&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127130</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127130"/>
		<updated>2019-11-05T18:20:36Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier, and schedule a job accordingly.&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding any redundant updates.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127129</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127129"/>
		<updated>2019-11-05T18:20:16Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier, and schedule a job accordingly.&lt;br /&gt;
::2. In case of an updation on Drop Deadline, we check if the new entry is different from the existing date, and reschedule the job only if it is, thereby avoiding a redundant update.&lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127128</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127128"/>
		<updated>2019-11-05T18:16:53Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
:Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
:Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127127</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127127"/>
		<updated>2019-11-05T18:16:20Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
::Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from ''app/models/topic_due_date.rb'', dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127126</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127126"/>
		<updated>2019-11-05T18:11:45Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline. For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127125</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127125"/>
		<updated>2019-11-05T18:11:21Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database. Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127124</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127124"/>
		<updated>2019-11-05T18:10:59Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127123</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127123"/>
		<updated>2019-11-05T18:10:31Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127122</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127122"/>
		<updated>2019-11-05T18:10:00Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127121</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127121"/>
		<updated>2019-11-05T18:09:19Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
::Edge cases addressed:&lt;br /&gt;
&lt;br /&gt;
::1. In case the Drop Deadline is not defined, we set the default as the Topic Submission Deadline/Assignment Submission Deadline, whichever is earlier.&lt;br /&gt;
::2. In case we don't have any &lt;br /&gt;
&lt;br /&gt;
Below is the code snippet from , dealing with the above change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127120</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127120"/>
		<updated>2019-11-05T18:03:49Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, Expertiza uses Sidekiq, and creates jobs for every Topic. Referred to as delayed_jobs, it currently has some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We need a job to be executed on the day of the specified Drop Deadline, which would drop the waitlist. To resolve this, we added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. In case there is an update on a previously defined deadline by the instructor, we fetch the existing job, using the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127119</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127119"/>
		<updated>2019-11-05T17:57:24Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127118</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127118"/>
		<updated>2019-11-05T17:57:11Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127117</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127117"/>
		<updated>2019-11-05T17:56:50Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Drawbacks and Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127116</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127116"/>
		<updated>2019-11-05T17:55:44Z</updated>

		<summary type="html">&lt;p&gt;Magavade: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127115</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127115"/>
		<updated>2019-11-05T17:55:12Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2018, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_job_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127114</id>
		<title>CSC/ECE 517 Fall 2019 - E1941. Issues related to topic deadlines</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&amp;diff=127114"/>
		<updated>2019-11-05T17:54:08Z</updated>

		<summary type="html">&lt;p&gt;Magavade: /* Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1941- Issues Related to Topic Deadlines OSS assignment for Fall 2018, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''About Expertiza''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source project based on Ruby on Rails framework and the code is available on Github. Expertiza allows the instructor to create new assignments as well as edit new or existing assignments. Instructors can also create a list of topics the students can sign up for and specify deadlines for completion of various tasks. Students can form teams in Expertiza to work on various projects and assignments as well as peer review other students' submissions. Expertiza supports submission across various document types, including the URLs Wiki pages.&lt;br /&gt;
&lt;br /&gt;
== '''Issues in the Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* There is no deadline that specifies when a team can drop their topics. Due to this, few problems occur: The team might drop a topic later on which is close to the submission date and this results in topic not being assigned to any other team on time such that they can submit their assignment. Also, if one team was wait listed for the same topic which the other team dropped closer to the submission deadline, then the first wait-listed team will be assigned to the dropped topic which is not desirable as they might be working on their assigned topic for long time.&lt;br /&gt;
&lt;br /&gt;
* There are different topics on which students can work during different times. This type of assignment is known as Staggered- deadline assignment in which different topics have different submission and review deadlines. For these assignments too, there is a need for &amp;quot;Drop Topics Deadline&amp;quot;. In the current implementation, the drop topic deadline is same for all the topics in a Staggered Deadline assignment which is not desirable.&lt;br /&gt;
&lt;br /&gt;
* The following points were identified in the problem statement, regarding when a team should be dropped automatically:&lt;br /&gt;
::- They get a topic they were on the waitlist for&lt;br /&gt;
::- The last member leaves the team&lt;br /&gt;
::- A drop-topic deadline passes, or a submission passes&lt;br /&gt;
&lt;br /&gt;
Out the three requirements, first two features are already implemented. We have implemented the last one, details are given below.&lt;br /&gt;
&lt;br /&gt;
== '''Current Implementation''' ==&lt;br /&gt;
&lt;br /&gt;
=====Functionality=====&lt;br /&gt;
&lt;br /&gt;
* '''The instructor cannot add a Drop Topic Deadline for topics'''&lt;br /&gt;
&lt;br /&gt;
::The instructor has the functionality to specify Review and Submission deadlines, while editing a topic. This page however, doesn’t have any provision on the form to let the instructor add Drop Topic Deadlines. According to the current implementation, s/he can add in a date for Drop Topic Deadline as well.&lt;br /&gt;
&lt;br /&gt;
* ''' The wait-list for a topic doesn’t get cleared on reaching the Drop Topic Deadline'''&lt;br /&gt;
&lt;br /&gt;
::Whenever the Drop Topic Deadline is crossed, we expect:&lt;br /&gt;
&lt;br /&gt;
::- The waitlist queue for the topic is cleared&lt;br /&gt;
&lt;br /&gt;
::- The teams are not permitted to drop the assigned topics anymore. &lt;br /&gt;
&lt;br /&gt;
::Previously, we had no job scheduled for dropping the waitlists. This segment involves a queue set-up for job scheduling (Sidekiq), which is not fully functional in the current implementation. To fix the issue, we have written the code for dropping teams from the waitlist which will work as expected once the queue starts working.&lt;br /&gt;
&lt;br /&gt;
=====Drawbacks and Solutions=====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Problem 1''': No provision for taking user input for Drop Topic Deadline and persisting it in the database.&lt;br /&gt;
Although the current schema supports a Topic/Assignment having drop Topic Deadlines, there is not form input field for the same. &lt;br /&gt;
&lt;br /&gt;
* '''Solution''': The implementation has been changed in such a way that the user can input the date, and the same is persisted under the due_dates table.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # adds a new deadline if not present,&lt;br /&gt;
  # updates the date if already present&lt;br /&gt;
  def self.modify_drop_deadline(assignment_id, topic, drop_topic_input)&lt;br /&gt;
    # can create constants for all deadline types and use those when required&lt;br /&gt;
    deadline_type_id = DeadlineHelper::DEADLINE_TYPE_DROP_TOPIC&lt;br /&gt;
    drop_topic_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id).first rescue nil&lt;br /&gt;
&lt;br /&gt;
    calc_drop_topic_date = get_drop_topic_deadline_date(assignment_id, topic.id, drop_topic_input)&lt;br /&gt;
&lt;br /&gt;
    # if drop topic deadline is not in db, make an entry&lt;br /&gt;
    if drop_topic_date.nil?&lt;br /&gt;
      # if user sets a date before creating the first entry&lt;br /&gt;
      due_at = (drop_topic_input.nil? || drop_topic_input.blank?) ? nil : calc_drop_topic_date&lt;br /&gt;
&lt;br /&gt;
      # add delayed job to drop waitlisted teams after deadline passes&lt;br /&gt;
      delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, nil, false)&lt;br /&gt;
&lt;br /&gt;
      TopicDueDate.create(due_at: due_at,&lt;br /&gt;
                          parent_id: topic.id,&lt;br /&gt;
                          deadline_type_id: deadline_type_id,&lt;br /&gt;
                          type: DeadlineHelper::TOPIC_DEADLINE_TYPE,&lt;br /&gt;
                          delayed_job_id: delayed_job_id)&lt;br /&gt;
    else&lt;br /&gt;
      update_delayed_job = true&lt;br /&gt;
&lt;br /&gt;
      if !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; (drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is deleted&lt;br /&gt;
        due_at = nil&lt;br /&gt;
      elsif drop_topic_date.due_at.nil? &amp;amp;&amp;amp; !(drop_topic_input.nil? || drop_topic_input.blank?)&lt;br /&gt;
        # if drop topic deadline is entered first time&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      elsif !drop_topic_date.due_at.nil? &amp;amp;&amp;amp; drop_topic_date.due_at.to_datetime.strftime(DeadlineHelper::DATE_FORMATTER) != calc_drop_topic_date.strftime(DeadlineHelper::DATE_FORMATTER)&lt;br /&gt;
        # if drop topic deadline is updated&lt;br /&gt;
        due_at = calc_drop_topic_date&lt;br /&gt;
      else&lt;br /&gt;
        # if updated date is same as existing, don't update the delayed job&lt;br /&gt;
        update_delayed_job = false&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      if update_delayed_job&lt;br /&gt;
        delayed_job_id = modify_delayed_job(topic.id, calc_drop_topic_date, drop_topic_date.delayed_job_id, true)&lt;br /&gt;
        drop_topic_date.update_attributes(due_at: due_at, delayed_job_id: delayed_job_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # check if drop topic is set by user else get the date from assignment&lt;br /&gt;
  def self.get_drop_topic_deadline_date(assignment_id, topic_id, drop_topic_input)&lt;br /&gt;
    drop_topic_date = (drop_topic_input.nil? || drop_topic_input.blank?) ? DueDate.get_deadline_to_drop_topic(assignment_id, topic_id) : DateTime.parse(drop_topic_input)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2019-10-31 at 2.34.32 PM.png]]&lt;br /&gt;
&lt;br /&gt;
* '''Problem 2''': Waitlisted topics not getting dropped after the Drop Topic Deadline.&lt;br /&gt;
For executing the timed jobs, we are using Sidekiq, and creating jobs for every Topic. Referred to as delayed_jobs, we currently have some defined for tasks like dropping a team when the last member leaves, etc.&lt;br /&gt;
&lt;br /&gt;
* '''Solution''': We have added another job which gets created on every new Topic creation, to be executed at the Drop Topic Deadline. Whenever there is any update on the Deadlines by the instructor, we fetch the existing job, if any, by the delayed_job_id, and modify the same as per the new Deadline.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # This method either adds a new job to the queue or deletes&lt;br /&gt;
  # an existing job and replaces it with a new one&lt;br /&gt;
  def self.modify_delayed_job(topic_id, drop_topic_date, delayed_job_id, job_present)&lt;br /&gt;
    if job_present&lt;br /&gt;
      remove_job_from_queue(delayed_job_id)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    mins_left = calculate_mins_left(drop_topic_date)&lt;br /&gt;
    return add_job_to_queue(mins_left, topic_id, &amp;quot;drop_topic&amp;quot;, drop_topic_date)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.calculate_mins_left(drop_topic_date)&lt;br /&gt;
    curr_time = DateTime.now&lt;br /&gt;
    time_in_min = ((curr_time - drop_topic_date) * 24 * 60).to_i&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.add_job_to_queue(min_left, topic_id, deadline_type, due_at)&lt;br /&gt;
    delayed_job_id = MailWorker.perform_in(min_left * 60, topic_id, deadline_type, due_at)&lt;br /&gt;
    return delayed_job_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def self.remove_job_from_queue(job_id)&lt;br /&gt;
    queue = Sidekiq::ScheduledSet.new&lt;br /&gt;
    queue.each do |job|&lt;br /&gt;
      current_job_id = job.args.first&lt;br /&gt;
      job.delete if job_id == current_job_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== '''Files modified in Current Project''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. app/helpers/sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
2. app/models/due_date.rb&lt;br /&gt;
&lt;br /&gt;
3. app/models/signed_up_team.rb&lt;br /&gt;
&lt;br /&gt;
4. app/models/waitlist.rb&lt;br /&gt;
&lt;br /&gt;
5. app/controllers/sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
6. app/helpers/deadline_helper.rb&lt;br /&gt;
&lt;br /&gt;
7. app/mailers/mail_worker.rb&lt;br /&gt;
&lt;br /&gt;
8. app/models/topic_due_date.rb&lt;br /&gt;
&lt;br /&gt;
9. spec/controllers/sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== '''Test Plan''' ==&lt;br /&gt;
&lt;br /&gt;
*'''RSpec:'''&lt;br /&gt;
&lt;br /&gt;
::It was discussed that project does not require any Unit Test cases to be implemented as the changes are mostly visible in views.&lt;br /&gt;
::Of all the code changes, we have one controller modification that had a rspec test case. We modified the same as per the changes we made to the code.&lt;br /&gt;
&lt;br /&gt;
*'''UI Testing:'''&lt;br /&gt;
::'''[Problem 1]'''&lt;br /&gt;
::::1. Login to Expertiza using username: instructor6 &amp;amp; password: password.&lt;br /&gt;
::::2. Select an existing course/Create a course and an assignment under that course. Check 'Staggered deadline assignment?' for the assignment.&lt;br /&gt;
::::3. Create topics under the assignment.&lt;br /&gt;
::::4. Go to Assignment -&amp;gt; Topics. Click 'Show start/due date' at the bottom of the screen.&lt;br /&gt;
::::5. Enter 'Drop Topic Deadline' and hit 'Save start/due date'.&lt;br /&gt;
::::6. Reopen the assignment topic to cross verify if the deadline has been saved.&lt;br /&gt;
&lt;br /&gt;
::Caveat: While creating an assignment the page would error out, but the assignment does get created, which is not related to any of the changes we have done. In case unable to do so, use 'MadeUp Problem' with Creation Date of 'Aug 30, 2017 - 9:03 AM'&lt;br /&gt;
&lt;br /&gt;
::'''[Problem 2]'''&lt;br /&gt;
::::When a deadline is assigned for a topic, we create a job (identified with delayed_job_id) to be executed on the deadline date. The module for job and queue set-up on expertiza is not fully functional, and hence this cannot be tested directly. However, we have written the code for job scheduling, here's a snapshot of the due_dates table with the delayed_id populated:&lt;br /&gt;
&lt;br /&gt;
::::[[File:DB Snapshot.png]]&lt;br /&gt;
&lt;br /&gt;
== '''References''' ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GITHUB: https://github.com/expertiza/expertiza&lt;br /&gt;
&lt;br /&gt;
2. GitHub Project Repository Fork: https://github.com/sanveg-rane-13/expertiza&lt;br /&gt;
&lt;br /&gt;
3. Demo link: https://drive.google.com/open?id=1jUwbeeiI2KaIH3l0C7FD0QHgBL6PVwF1&lt;br /&gt;
&lt;br /&gt;
4. Pull Request: https://github.com/expertiza/expertiza/pull/1560&lt;br /&gt;
&lt;br /&gt;
5. Expertiza project documentation wiki: http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2019_-_E1941._Issues_related_to_topic_deadlines&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127071</id>
		<title>File:Screen Shot 2019-10-31 at 2.34.32 PM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2019-10-31_at_2.34.32_PM.png&amp;diff=127071"/>
		<updated>2019-11-05T02:57:07Z</updated>

		<summary type="html">&lt;p&gt;Magavade: uploaded a new version of &amp;amp;quot;File:Screen Shot 2019-10-31 at 2.34.32 PM.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DropTopic Screenshot&lt;/div&gt;</summary>
		<author><name>Magavade</name></author>
	</entry>
</feed>