Subversion Repositories SmartDukaan

Rev

Rev 4198 | Rev 5323 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3232 varun.gupt 1
$(function(){
3440 varun.gupt 2
	feedbacks = null;
3232 varun.gupt 3
 
3446 varun.gupt 4
	function getPriceAsInt(priceString)	{
5
		return parseInt(priceString.replace('Rs.', '').replace(',', ''));
6
	}
7
 
3551 varun.gupt 8
	function roundNumber(num, dec) {
9
		return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
10
	}
11
 
5291 varun.gupt 12
	function updateWithSecondaryCrawledData()	{
13
		$.ajax({
14
			url: '/feedback-url',
15
			type: 'GET',
16
			success: function(data){
17
 
18
				$.each(data, function(entityId, sourceData){
19
 
20
					$.each(sourceData, function(source, productData){
21
 
22
						var tr = $('#' + entityId);
23
						var td = $(tr).children('td[source=' + source +']')[0];
24
						var anchor = $(td).children('a')[0];
25
 
26
						$(anchor).attr('href', productData['product_url']);
27
						$(anchor).html(productData['price']);
28
 
29
						$(td).children('span.url-feedback-link').addClass('url-saved');
30
					});
31
				});
32
			}
33
		});
34
	}
35
 
3440 varun.gupt 36
	function updateWithFeedback()	{
37
		$.ajax({
38
			url: '/feedback',
39
			type: 'GET',
40
			success: function(data){
41
				feedbacks = eval('(' + data + ')');
42
 
43
				$.each(feedbacks, function(entityId, feedback){
44
					var tr = $('#' + entityId);
45
 
46
					$.each(feedback, function(source, feedback_instruction){
3462 varun.gupt 47
 
48
						var td = $(tr).children('td[source=' + source + ']')[0];
49
 
50
						if($(td).hasClass('conflict'))	updateCellWithFeedback(td, feedback_instruction);
3440 varun.gupt 51
					});
3446 varun.gupt 52
					markBestPrice(tr);
3440 varun.gupt 53
				});
5291 varun.gupt 54
				updateWithSecondaryCrawledData();
3440 varun.gupt 55
			}
56
		})
57
	}
58
 
59
	function updateCellWithFeedback(td, feedback)	{
60
		var anchor = $(td).children('.link-conflict');
3462 varun.gupt 61
 
3440 varun.gupt 62
		var source = $(td).attr('source');
5291 varun.gupt 63
		var cellActionLinks = $(td).children('.url-feedback-link, .reject-link').clone();
3440 varun.gupt 64
		$(anchor).html('Filtered');
65
 
66
		if(feedback.type == 'reject')	{
67
			$(td).html('Not Found ' + $('<a>').append($(anchor).clone()).remove().html()).addClass('with-feedback');
5291 varun.gupt 68
			$(td).append(cellActionLinks);
69
			$(td).children('span.reject-link').addClass('rejected')
3440 varun.gupt 70
 
71
		} else	{
72
			var itemInfo = lookupInfoForItem(eval($(td).attr('data')), feedback.selected_item);
4198 varun.gupt 73
 
74
			if (itemInfo != null)	{
75
				$(td).html(
76
					'<a href="' + baseUrl[source] + itemInfo.url + '">' + itemInfo.price + '</a> ' + 
77
					$('<a>').append($(anchor).clone()).remove().html()
78
				).addClass('with-feedback');
79
			}
3440 varun.gupt 80
		}
81
	}
82
 
83
	function lookupInfoForItem(data, itemName)	{
84
		var info = null;
85
 
86
		$.each(data, function(index, item){
87
 
88
			if (item.name == itemName)	{
89
				info = {name: item.name, price: item.price, url: item.url};
90
			}
91
		});
92
		return info;
93
	}
94
 
95
	$('tbody tr').each(function(index, e)	{
96
 		var class_tr = index % 2 == 0 ? 'even' : 'odd';
97
 		$(e).addClass(class_tr);
98
 		markBestPrice(this);
4198 varun.gupt 99
 
3440 varun.gupt 100
 		$(this).find('td').each(function(){
3462 varun.gupt 101
 			if($(this).hasClass('conflict'))	$(this).children('a').addClass('link-conflict');
4198 varun.gupt 102
 
103
 			if(! $(this).hasClass('diff') && ! $(this).hasClass('name') && ! $(this).hasClass('saholic'))	{
5291 varun.gupt 104
 				$(this).append('<span class="reject-link" title="Click to reject the displayed figure">X</span>&nbsp;');
4198 varun.gupt 105
 				$(this).append('<span class="url-feedback-link" title="Click to map a product page URL">U</span>');
106
 			}
3440 varun.gupt 107
 		});
108
	});
109
 
110
	updateWithFeedback();
111
 
3313 varun.gupt 112
	function markBestPrice(trNode)	{
3446 varun.gupt 113
		$(trNode).children().removeClass('best');
5291 varun.gupt 114
		var tdBestPrice = $(trNode).children('.saholic')[0];
115
		var saholicPrice = parseInt($(tdBestPrice).html());
3313 varun.gupt 116
		var bestPrice = saholicPrice;
3551 varun.gupt 117
		var maxPrice = saholicPrice;
3446 varun.gupt 118
 
119
		$(trNode).find('a[href!="#"]').each(function(index, a){
120
			var price = getPriceAsInt(a.innerHTML);
5291 varun.gupt 121
 
3313 varun.gupt 122
			if (price < bestPrice)	{
123
				bestPrice = price;
124
				tdBestPrice = $(a).parent();
125
			}
3551 varun.gupt 126
 
127
			if(price > maxPrice)	maxPrice = price;
3313 varun.gupt 128
		});
3551 varun.gupt 129
		var maxMinDiff = roundNumber((maxPrice - bestPrice) * 100 / maxPrice, 2);
130
 
3313 varun.gupt 131
		$(tdBestPrice).addClass('best');
132
 
133
		if (bestPrice < saholicPrice)	$($(trNode).children()[0]).addClass('red');
3551 varun.gupt 134
		var tds = $(trNode).children()
135
 
136
		if (tds.length == 7)	{
137
			tds[6].innerHTML = maxMinDiff + '%'
4198 varun.gupt 138
		} else	{var diffCssClass = '';
139
 
140
		if(maxMinDiff >= 25.0)	{
141
			diffCssClass = 'dark-orange';
142
		} else if(maxMinDiff >= 10.0)	{
143
			diffCssClass = 'orange';
3551 varun.gupt 144
		}
4198 varun.gupt 145
		$(trNode).append('<td class="diff ' + diffCssClass + '" title="Max-Min price difference">' + maxMinDiff + '%</td>');
146
		}
3313 varun.gupt 147
	}
148
 
149
	var baseUrl = {
150
		'flipkart': 'http://www.flipkart.com',
151
		'homeshop18': '',
152
		'infibeam': 'http://www.infibeam.com',
5291 varun.gupt 153
		'letsbuy': '',
154
		'snapdeal': 'http://www.snapdeal.com/'
3313 varun.gupt 155
	};
156
 
3440 varun.gupt 157
	$('.conflict a').live('click', function(){
158
		var td = $(this).parent();
3232 varun.gupt 159
 
3440 varun.gupt 160
		var entityId = $(td).parent().attr('id');
161
		var source = $(td).attr('source');
162
 
163
		var data = eval("{results: " + $(td).attr('data') + "}");
164
 
165
		var feedback = null;
166
		var selectedItem = null; 
167
 
168
		if(feedbacks && feedbacks[entityId] && feedbacks[entityId][source])	{
169
			feedback = feedbacks[entityId][source];
170
 
171
			if (feedback.type == 'select')	selectedItem = feedback.selected_item;
172
		}
173
 
174
		if (feedback && feedback.type == 'reject')	{
175
			var text = '<div class="msg">Currently following set is marked <i>rejected</i></div>';
176
 
177
		} else	{
178
			var text = '';
179
		}
180
		text += '<table id="' + entityId + '" source="' + source + '">';
181
 
3232 varun.gupt 182
		for (i in data)	{
3440 varun.gupt 183
			var checked = selectedItem && selectedItem == data[i]['name'] ? 'checked' : ''; 
3232 varun.gupt 184
			text += '<tr>';
185
			text += '<td>' + data[i]['name'] + '</td>';
3313 varun.gupt 186
			text += '<td><a target="_blank" href="' + baseUrl[data[i]['source']] + data[i]['url'] + '">' + data[i]['price'] + '</a></td>';
3440 varun.gupt 187
			text += '<td><input type="radio" name="chosen_one_' + entityId + '" value="' + data[i]['name'] + '" ' + checked + '></td>';
3232 varun.gupt 188
			text += '</tr>';
189
		}
3440 varun.gupt 190
		text += '<tr>';
191
		text += '<td colspan="2" align="center"><a id="feedback-reject" href="#">Reject All</a></td>';
192
		text += '<td><a id="feedback-select" href="#">Save</a></td>';
193
		text += '</tr>';
3232 varun.gupt 194
		text += '</table>';
3440 varun.gupt 195
 
3232 varun.gupt 196
		$.facebox(text);
197
	});
3440 varun.gupt 198
 
199
	$('#feedback-reject').live('click', function(){
200
		var table = $(this).parents('table');
201
		var feedback = {
202
				type: 'reject',
203
				entityId: $(table).attr('id'),
204
				source: $(table).attr('source')
205
		};
206
		postFeedback(feedback, table);
207
	});
208
 
209
	$('#feedback-select').live('click', function(){
210
		var table = $(this).parents('table');
211
		var entityId = $(table).attr('id');
212
 
213
		var selected_item = $("input:radio[name='chosen_one_" + entityId + "']:checked").val();
214
 
215
		if(! selected_item)	{
216
 
217
			showMsg(table, true, 'At least one option must be selected');
218
 
219
		} else	{
220
			var feedback = {
221
					type: 'select',
222
					entityId: entityId,
223
					source: $(table).attr('source'),
224
					selected: selected_item
225
			};
226
			postFeedback(feedback, table);
227
		}
228
	});
229
 
230
	function postFeedback(feedback, table)	{
231
		var feedbackType = feedback.type;
232
		var entityId = feedback.entityId;
233
 
234
		$.ajax({
235
			url: '/feedback',
236
			type: 'POST',
237
			data: feedback,
238
			success: function(msg)	{
239
 
240
				if (feedbackType == 'reject')	{
241
					$("input:radio[name='chosen_one_" + entityId + "']:checked").prop('checked', false);
242
				}
243
				var td = $('#' + feedback.entityId).children('td[source=' + feedback.source + ']')[0];
244
				updateCellWithFeedback(td, {type: feedback.type, selected_item: feedback.selected});
5291 varun.gupt 245
 
246
				if(table && table != 'undefined')	{
247
					showMsg(table, false, 'Your feedback has been saved successfully.');
248
				}
3446 varun.gupt 249
				markBestPrice($(td).parent());
3440 varun.gupt 250
			},
251
			error: function(msg)	{
252
				showMsg(table, true, 'Error! please try again.');
253
			}
254
		});
255
	}
256
 
257
	function showMsg(table, is_error, msg)	{
258
		msg_class = is_error ? 'error' : 'notice';
259
 
260
		if($(table).siblings('.msg').length > 0)	{
261
			var msgDiv = $(table).siblings('.msg')[0];
262
			$(msgDiv).html(msg);
263
 
264
		} else	{
265
			$(table).before('<div class="msg">' + msg + '</div>');
266
		}
267
	}
268
 
4198 varun.gupt 269
	$('.url-feedback-link').live('click', function(){
270
		var source = $(this).parent().attr('source');
271
		var entity = $(this).parent().parent().attr('id');
272
//		console.log(source, entity);
273
		var html = '<div class="form-url-feedback">\n';
274
		var html = 'Enter the URL you want to be crawled for this product<br>\n';
275
		html += '<input type="text" id="url-feedback" size="40"><br />\n';
276
		html += '<input type="hidden" id="entity-url-feedback" value="' + entity + '">\n';
277
		html += '<input type="hidden" id="source-url-feedback" value="' + source + '">\n';
278
		html += '<input type="button" id="submit-url-feedback" value="Save">\n';
279
		html += '</div>';
280
		$.facebox(html);
281
	});
282
 
283
	$('#submit-url-feedback').live('click', function(){
284
		$.ajax({
285
			url: '/feedback-url',
286
			type: 'POST',
287
			data: {
288
				entity: $('#entity-url-feedback').val(), 
289
				source: $('#source-url-feedback').val(), 
290
				url: $('#url-feedback').val()
291
			},
292
			beforeSend: function(){
293
				$('#url-feedback, #submit-url-feedback').attr('disabled', 'disabled');
294
				$('#submit-url-feedback').val('Saving...').after('<img src="/static/images/loading.gif" width="24" />');
295
			},
296
			success: function(data){
297
				var html = '<table>';
298
				html += '<tr><td class="msg" colspan="2" align="center">The URL is saved and will be crawled next time</td></tr>';
5291 varun.gupt 299
				html += '<tr><td colspan="2">&nbsp;</td></tr>';
4198 varun.gupt 300
				html += '<tr><td align="center">' + data.name + '</td><td align="center">Rs.' + data.price + '</td></tr>';
301
				html += '</table>';
302
				var form = $('#facebox').find('.content').html(html);
5291 varun.gupt 303
 
304
				var tr = $('#' + data.entityId);
305
				var td = $(tr).children('td[source=' + data.source +']')[0];
306
				var anchor = $(td).children('a')[0];
307
 
308
				$(anchor).attr('href', data.product_url);
309
				$(anchor).html(data.price);
310
 
311
				$(td).children('span').addClass('url-saved');
4198 varun.gupt 312
			}
313
		});
314
	});
315
 
5291 varun.gupt 316
	$('.reject-link').live('click', function(){
317
		var source = $(this).parent().attr('source');
318
		var entity = $(this).parent().parent().attr('id');
319
 
320
		if($(this).hasClass('rejected'))	{
321
			var td = $(this).parent();
322
 
323
			var url = $(td).attr('url');
324
			var price = $(td).attr('price');
325
 
326
			var cellActionLinks = $(td).children('.url-feedback-link, .reject-link');
327
			$(td).html('<a target="_blank" href="' + url + '">' + price + '</a>');
328
			$(td).append(cellActionLinks);
329
			console.log($(td).children('.reject-link'));
330
			$($(td).children('.reject-link')[0]).removeClass('rejected');
331
 
332
		} else	{
333
			var feedback = {
334
					type: 'reject',
335
					entityId: entity,
336
					source: source
337
			};
338
 
339
			//Setting rejected URL in the cell's DOM
340
			var td = $('#' + entity).children('td[source=' + source + ']')[0];
341
			var anchor = $(td).children('a')[0];
342
			$(td).attr('price', $.trim($(anchor).html()));
343
			$(td).attr('url', $(anchor).attr('href'));
344
 
345
			postFeedback(feedback);
346
		}
347
	});
348
 
4198 varun.gupt 349
	$('#howTo').click(function(){
350
		html = '<ul>\n\
351
			<li class="first">The price data is crawled directly from competitor websites at 8:00 AM everyday</li>\n\
352
			<li class="first">All price figures are linked to their respective product pages</li>\n\
353
			<li class="first">Cells showing "Not Found" are linked to search result page of relevant website.</li>\n\
354
			<li class="first">Cells showing "Conflict" are linked to set of products which are conflicting to match with\n\
355
			the product. You can either select one of them or reject all depending on the case. The selection \n\
356
			will be taken into account when showing the dashboard next time.</li>\n\
357
			<li class="first">Clicking on "U" (present in all price cells) will pop up a form where you can submit a URL \n\
358
			pointing to the product page of the product. After submission this URL will be crawled and indexed \n\
359
			in real-time and saved in the list of URLs for scheduled crawling in future.</li>\n\
360
			<li class="first">In each row, right most cell shows the percentage difference between the minimum and maximum \n\
361
			price of that product. Color coding:\n\
362
				<ul>\n\
363
					<li>Yellow: 10 - 24.99% difference</li>\n\
364
					<li>Orange: Above 24.99%</li>\n\
365
				</ul></li>\n\
366
			<li class="first">In case of further clarification, email your query at varun.gupta@shop2020.in</li>\n\
367
			</ul>';
368
		$.facebox(html);
369
	});
370
 
5291 varun.gupt 371
	$('#all').click(function(){
372
		$('tbody tr').show();
373
	});
374
 
375
	$('#watchlist').click(function(){
376
		$('tbody tr .watchlist-icon').each(function(){
377
			if(! $(this).hasClass('on-watchlist'))	$(this).parent().parent().hide();
378
		});
379
	});
380
 
3440 varun.gupt 381
	$('#facebox .close').live('click', function(){});
5291 varun.gupt 382
 
383
	var watchList = {
384
			get: function()	{
385
				$.ajax({
386
					type: 'GET',
387
					url: '/watchlist',
388
 
389
					error: function(jqXHR, textStatus, errorThrown)	{
390
						console.log(jqXHR, textStatus, errorThrown);
391
						alert('Could not get WatchList. Try again later.');
392
					},
393
					success: function(data, textStatus, jqXHR)	{
394
						console.log(data, textStatus, jqXHR);
395
						entities = eval('(' + data + ')');
396
 
397
						$.each(entities, function(index, entity)	{
398
							var elementId = '#' + entity;
399
							var tr = $(elementId);
400
							$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
401
						});
402
					}
403
				});
404
			},
405
			add: function(entity)	{
406
				$.ajax({
407
					type: 'POST',
408
					url: '/watchlist',
409
					data: {'type': 'save', 'entity': entity},
410
 
411
					error: function(jqXHR, textStatus, errorThrown)	{
412
						console.log(jqXHR, textStatus, errorThrown);
413
						alert('Could not add this item to WatchList. Try again later.');
414
					},
415
					success: function(data, textStatus, jqXHR)	{
416
						console.log(data, textStatus, jqXHR);
417
						$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
418
					}
419
				});
420
			},
421
			remove: function(entity)	{
422
				$.ajax({
423
					type: 'POST',
424
					url: '/watchlist',
425
					data: {'type': 'delete', 'entity': entity},
426
 
427
					error: function(jqXHR, textStatus, errorThrown)	{
428
						console.log(jqXHR, textStatus, errorThrown);
429
						alert('Could not remove this item from WatchList. Try again later.');
430
					},
431
					success: function(data, textStatus, jqXHR)	{
432
						console.log(data, textStatus, jqXHR);
433
						$($('#' + entity).find('.watchlist-icon')[0]).removeClass('on-watchlist');
434
					}
435
				});
436
			}
437
	};
438
 
439
	watchList.get();
440
 
441
	$('.watchlist-icon').click(function(){
442
 
443
		var entity = $(this).parent().parent().attr('id');
444
 
445
		if($(this).hasClass('on-watchlist'))	{
446
			watchList.remove(entity);
447
		} else	{
448
			watchList.add(entity);
449
		}
450
	});
3232 varun.gupt 451
});