|
| 1 | +// *********************************************************** |
| 2 | +// REQUIRED CONSTANTS, DO NOT MODIFY |
| 3 | +// *********************************************************** |
| 4 | +var ASSIGNMENT_MARKING = 'Assignment Marking'; |
| 5 | +var COURSE_MATERIAL_PREPARATION = 'Course Material Preparation'; |
| 6 | +var TUTORIAL = 'Tutorial'; |
| 7 | +var CONSULTATION = 'Consultation with students'; |
| 8 | +var POST_URL = '/~tssclaim/tutor/teach_claim.php'; |
| 9 | +var END_REDIRECT_URL = '/~tssclaim/tutor/teach_claim.php?page=list'; |
| 10 | + |
| 11 | + |
| 12 | +// *********************************************************** |
| 13 | +// READ THE FOLLOWING BEFORE STARTING |
| 14 | +// *********************************************************** |
| 15 | +// 1. **IMPORTANT STEP** Change the properties in the config object in the next section. |
| 16 | + |
| 17 | +// 2. Login to the portal at: https://mysoc.nus.edu.sg/~tssclaim/. Fill in your bank account information if you haven't. |
| 18 | + |
| 19 | +// 3. Access the page titled 'Student Claim Submission' (https://mysoc.nus.edu.sg/~tssclaim/tutor/teach_claim.php?page=1) and click on |
| 20 | +// the 'Claim' button under your module. You should see the interface for you to enter details of the teaching claim activity. |
| 21 | + |
| 22 | +// 4. Open the JS console (Ctrl/Cmd + Shift/Option + J), paste all the code in this file in the JS console and press enter. You should |
| 23 | +// see the message 'Claim object successfully created. Run c.makeAllClaims() to start.'. |
| 24 | + |
| 25 | +// 5. Run the function c.makeAllClaims() . Wait until the alert 'All claims made!' is shown, then press 'OK'. |
| 26 | + |
| 27 | +// 6. You will be brought back to the previous page. Click on the button 'Claim' again and verify that you have the right number of hours. |
| 28 | + |
| 29 | +// To delete all claims on the page, run the function c.deleteAllClaims() |
| 30 | + |
| 31 | + |
| 32 | +// *********************************************************** |
| 33 | +// CONFIGURE THE RELEVANT PROPERTIES IN THE CONFIG OBJECT |
| 34 | +// *********************************************************** |
| 35 | + |
| 36 | +var config = { |
| 37 | + // Format: YYYY/MM/DD |
| 38 | + // Note: Month is from 0-11, Date is from 1-31 |
| 39 | + // This should be the semester's week 1. For AY13/14 Sem 2, it's Monday, Jan 13 |
| 40 | + first_day_of_sem: new Date(2014,7,11), |
| 41 | + // Your student ID |
| 42 | + student_id: 'a0099314', |
| 43 | + // Module you are claiming hours for |
| 44 | + module: 'CS1101S', |
| 45 | + // In case you want to customize the duties field for each activity |
| 46 | + // Do not modify the keys |
| 47 | + duties: { |
| 48 | + 'Assignment Marking': 'Graded students\' assignments', |
| 49 | + 'Course Material Preparation': 'Prepared course materials', |
| 50 | + 'Tutorial': 'Conducted tutorial', |
| 51 | + 'Consultation with students': 'Had consultation with students' |
| 52 | + }, |
| 53 | + |
| 54 | + // The following function should return a list of claim objects that you want to make |
| 55 | + activities_list_fn: function() { |
| 56 | + var activities_list = []; |
| 57 | + |
| 58 | + // This is an example of how you can make weekly claims |
| 59 | + // Note that the week value does not support recess and reading weeks. |
| 60 | + // |
| 61 | + // 2h DG * 11 weeks = 22 hours |
| 62 | + // 2h preparation * 10 weeks = 20 hours |
| 63 | + // 2h grading * 14 weeks = 28 hours |
| 64 | + // |
| 65 | + // TOTAL: 70 hours |
| 66 | + for (var week = 1; week <= 14; week++) { |
| 67 | + activities_list.push({ |
| 68 | + activity_type: ASSIGNMENT_MARKING, |
| 69 | + week: week, |
| 70 | + day: 'SATURDAY', |
| 71 | + start_time: '1300', |
| 72 | + end_time: '1500' |
| 73 | + }); |
| 74 | + |
| 75 | + if (week === 1 || week === 7 || week === 9) { |
| 76 | + // there was no tutorial in week 1, 7 (recess) and 9 (PH) |
| 77 | + } else { |
| 78 | + activities_list.push({ |
| 79 | + activity_type: TUTORIAL, |
| 80 | + week: week, |
| 81 | + day: 'TUESDAY', |
| 82 | + start_time: '1400', |
| 83 | + end_time: '1600' |
| 84 | + }); |
| 85 | + } |
| 86 | + |
| 87 | + if (week <= 10) { |
| 88 | + activities_list.push({ |
| 89 | + activity_type: COURSE_MATERIAL_PREPARATION, |
| 90 | + week: week, |
| 91 | + day: 'MONDAY', |
| 92 | + start_time: '1800', |
| 93 | + end_time: '2000' |
| 94 | + }); |
| 95 | + } |
| 96 | + }; |
| 97 | + |
| 98 | + return activities_list; |
| 99 | + } |
| 100 | +} |
| 101 | + |
| 102 | + |
| 103 | +// *********************************************************** |
| 104 | +// DO NOT CHANGE THE BOTTOM UNLESS YOU KNOW WHAT YOU ARE DOING |
| 105 | +// *********************************************************** |
| 106 | + |
| 107 | +var ACTIVITY_DICT = {}; |
| 108 | +ACTIVITY_DICT[ASSIGNMENT_MARKING] = '003'; |
| 109 | +ACTIVITY_DICT[COURSE_MATERIAL_PREPARATION] = '006'; |
| 110 | +ACTIVITY_DICT[TUTORIAL] = 'T'; |
| 111 | +ACTIVITY_DICT[CONSULTATION] = 'C'; |
| 112 | + |
| 113 | +var DAY_DICT = { 'MONDAY': 0, 'TUESDAY': 1, 'WEDNESDAY': 2, 'THURSDAY': 3, 'FRIDAY': 4, 'SATURDAY': 5, 'SUNDAY': 6 }; |
| 114 | + |
| 115 | +function Claim(config) { |
| 116 | + this.student_id = config.student_id.toLowerCase(); |
| 117 | + this.module = config.module; |
| 118 | + this.remarks = config.duties; |
| 119 | + this.first_day_of_sem = config.first_day_of_sem; |
| 120 | + this.error = false; |
| 121 | + |
| 122 | + var that = this; |
| 123 | + |
| 124 | + // Ensure claiming for correct module! |
| 125 | + if ($('h3:contains("Module")').text().substr(8) !== config.module) { |
| 126 | + alert('Ensure that the module in config matches that of this page.'); |
| 127 | + // Else you will have invisible claims taking up your time. |
| 128 | + throw new Error('Incorrect module in config.'); |
| 129 | + } |
| 130 | + |
| 131 | + function createActivity(activity_type, week, day, start_time, end_time) { |
| 132 | + var day_upper = day.toUpperCase(); |
| 133 | + try { |
| 134 | + if (ACTIVITY_DICT[activity_type] === undefined || typeof activity_type !== 'string') { |
| 135 | + throw 'Activity error: ' + activity_type + '. Activity type not supported.'; |
| 136 | + } |
| 137 | + if (typeof week !== 'number' || week <= 0) { |
| 138 | + throw 'Week error: ' + week + '. Week value has to be a positive number.'; |
| 139 | + } |
| 140 | + if (DAY_DICT[day_upper] === undefined || typeof day_upper !== 'string') { |
| 141 | + throw 'Day error: ' + day + '. Day value has to be a valid day string.'; |
| 142 | + } |
| 143 | + |
| 144 | + function checkTime(time) { |
| 145 | + var start_time_hour = time.slice(0,2); |
| 146 | + var start_time_min = time.slice(2); |
| 147 | + if (typeof time !== 'string' || |
| 148 | + time.length != 4 || |
| 149 | + !(parseInt(start_time_hour) >= 0 && parseInt(start_time_hour) <= 23) || |
| 150 | + !(start_time_min === '00' || start_time_min === '30')) { |
| 151 | + throw 'Time error: ' + time + '. Time has to be string in 24-hr format at half-hour intervals.'; |
| 152 | + } |
| 153 | + } |
| 154 | + |
| 155 | + checkTime(start_time); |
| 156 | + checkTime(end_time); |
| 157 | + var start_time_hour = parseInt(start_time.slice(0,2)); |
| 158 | + var end_time_hour = parseInt(end_time.slice(0,2)); |
| 159 | + |
| 160 | + if (start_time_hour > end_time_hour || start_time === end_time) { |
| 161 | + throw 'Time error: end_time: ' + end_time + ' must be after start_time: ' + start_time + '.'; |
| 162 | + } else if (end_time_hour - start_time_hour > 8) { |
| 163 | + throw 'Time error: ' + start_time + ' - ' + end_time + '. Activity cannot be more than 8 hours.'; |
| 164 | + } |
| 165 | + } catch (err) { |
| 166 | + error = true; |
| 167 | + console.log(err); |
| 168 | + } |
| 169 | + |
| 170 | + return function() { |
| 171 | + that.makeClaim(activity_type, week, day, start_time, end_time); |
| 172 | + }; |
| 173 | + } |
| 174 | + |
| 175 | + var activities = config.activities_list_fn(); |
| 176 | + this.activities_list = []; |
| 177 | + for (var i = 0; i < activities.length; i++) { |
| 178 | + var a = activities[i]; |
| 179 | + this.activities_list.push(createActivity(a.activity_type, a.week, a.day, a.start_time, a.end_time)); |
| 180 | + } |
| 181 | + // sum up existing hours claimed |
| 182 | + var $existing_claims = $('#claim-info-div table tr'); |
| 183 | + var existing_hours = 0; |
| 184 | + $existing_claims.each(function(){ |
| 185 | + var row = $(this); |
| 186 | + if (row.find('input[name=action]').val() === 'DELETE') { |
| 187 | + var hours = parseFloat(row.find('td:eq(5)').text()); |
| 188 | + if (!isNaN(hours)) { |
| 189 | + existing_hours += hours; |
| 190 | + } |
| 191 | + } |
| 192 | + }) |
| 193 | + this.ajax_index = 0; // index to keep track of the current ajax call |
| 194 | + console.log('Current hours claimed: ' + existing_hours); |
| 195 | + console.log('Claim object successfully created. Run c.makeAllClaims() to start.'); |
| 196 | +} |
| 197 | + |
| 198 | +Claim.prototype.makeClaim = function(activity_type, week, day, start_time, end_time) { |
| 199 | + var day_num = DAY_DICT[day]; |
| 200 | + var number_of_days = (week < 7 ? week - 1 : week)*7 + day_num; |
| 201 | + var activity_date = new Date(); |
| 202 | + activity_date.setTime(this.first_day_of_sem.getTime() + (number_of_days * 24 * 60 * 60 * 1000)); |
| 203 | + var claim_date_array = activity_date.toDateString().split(' '); |
| 204 | + var claim_date_str = [claim_date_array[2], claim_date_array[1], claim_date_array[3].slice(2)].join('-'); |
| 205 | + |
| 206 | + var post_data = { |
| 207 | + mod_c: this.module, |
| 208 | + action: 'ADD', |
| 209 | + std_id: this.student_id, |
| 210 | + activity_c: ACTIVITY_DICT[activity_type], |
| 211 | + remarks: this.remarks[activity_type], |
| 212 | + claim_date: claim_date_str, |
| 213 | + start_time_hr: start_time.slice(0,2), |
| 214 | + start_time_min: start_time.slice(2), |
| 215 | + end_time_hr: end_time.slice(0,2), |
| 216 | + end_time_min: end_time.slice(2), |
| 217 | + submit: 'ADD + Save as Draft' |
| 218 | + } |
| 219 | + |
| 220 | + var that = this; |
| 221 | + $.post(POST_URL, post_data, function(data) { |
| 222 | + console.log('Successfully added ' + activity_type + ' for ' + claim_date_str); |
| 223 | + that.ajax_index += 1; |
| 224 | + if (that.ajax_index < that.activities_list.length) { |
| 225 | + that.activities_list[that.ajax_index](); |
| 226 | + } else { |
| 227 | + alert('All claims made! Press OK to continue.'); |
| 228 | + // redirect to previous page because a refresh of the page would trigger the last ajax call |
| 229 | + window.location.href = window.location.protocol +'//'+ window.location.host + END_REDIRECT_URL; |
| 230 | + } |
| 231 | + }); |
| 232 | +}; |
| 233 | + |
| 234 | +Claim.prototype.deleteAllClaims = function() { |
| 235 | + var that = this; |
| 236 | + function deleteClaim(claim_id) { |
| 237 | + $.post(POST_URL, { |
| 238 | + mod_c: that.module, |
| 239 | + claim_id: claim_id, |
| 240 | + action: 'DELETE', |
| 241 | + std_id: that.student_id, |
| 242 | + submit: 'DELETE + Save as Draft' |
| 243 | + }, function(data) { |
| 244 | + console.log('Claim ' + claim_id + ' deleted'); |
| 245 | + count += 1; |
| 246 | + if (count === $existing_claims.length) { |
| 247 | + alert('All claims deleted! Press OK to continue.'); |
| 248 | + window.location.href = window.location.protocol + '//' + window.location.host + END_REDIRECT_URL; |
| 249 | + } |
| 250 | + }); |
| 251 | + } |
| 252 | + |
| 253 | + var count = 0; |
| 254 | + var $existing_claims = $('#claim-info-div table [name="claim_id"]'); |
| 255 | + $existing_claims.each(function() { |
| 256 | + deleteClaim(this.value); |
| 257 | + }); |
| 258 | +} |
| 259 | + |
| 260 | +Claim.prototype.makeAllClaims = function() { |
| 261 | + if (!this.error) { |
| 262 | + this.activities_list[this.ajax_index](); |
| 263 | + } |
| 264 | +} |
| 265 | + |
| 266 | +var c = new Claim(config); |
| 267 | +// c.makeAllClaims(); |
0 commit comments