Subversion Repositories SmartDukaan

Rev

Rev 5738 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

$(function(){
        feedbacks = null;
        
        function getPriceAsInt(priceString)     {
                return parseInt(priceString.replace('Rs.', '').replace(',', ''));
        }
        
        function roundNumber(num, dec) {
                return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
        }
        
        function updateWithSecondaryCrawledData()       {
                $.ajax({
                        url: '/feedback-url',
                        type: 'GET',
                        dataType: 'html',
                        
                        success: function(dataString){
                                var data = eval('(' + dataString + ')');
                                //console.log(dataString, data);
                                
                                $.each(data, function(entityId, sourceData){
                                        //console.log(entityId, sourceData);
                                        var tr = $('#' + entityId);
                                        
                                        $.each(sourceData, function(source, productData){
                                                //console.log(source, productData);
                                                
                                                var td = $(tr).children('td[source=' + source +']')[0];
                                                var anchor = $(td).children('a')[0];
                                                //console.log(anchor);
                                                
                                                if(anchor != undefined) {                                               
                                                        $(anchor).attr('href', productData['product_url']);
                                                        $(anchor).html(productData['price']);
                                                } else {
                                                        try{
                                                                $(td).html($(td).html().replace('Not Found', productData['price']));
                                                        }catch(e) { 
                                                                console.log(e);
                                                        }
                                                }
                                                
                                                $(td).children('span.url-feedback-link').addClass('url-saved');
                                        });
                                        markBestPrice(tr);
                                });
                        }
                });
        }
        
        function updateWithFeedback()   {
                $.ajax({
                        url: '/feedback',
                        type: 'GET',
                        success: function(data){
                                feedbacks = eval('(' + data + ')');
                                
                                $.each(feedbacks, function(entityId, feedback){
                                        var tr = $('#' + entityId);
                                        
                                        $.each(feedback, function(source, feedback_instruction){
                                                
                                                var td = $(tr).children('td[source=' + source + ']')[0];
                                                
                                                //if($(td).hasClass('conflict'))        
                                                updateCellWithFeedback(td, feedback_instruction);
                                        });
                                        markBestPrice(tr);
                                });
                                updateWithSecondaryCrawledData();
                        }
                })
        }
        
        function updateCellWithFeedback(td, feedback)   {
                var anchor = $(td).children('.link-conflict');
                
                var source = $(td).attr('source');
                var cellActionLinks = $(td).children('.url-feedback-link, .reject-link').clone();
                $(anchor).html('Filtered');
                
                if(feedback.type == 'reject')   {
                        $(td).html('Not Found ' + $('<a>').append($(anchor).clone()).remove().html()).addClass('with-feedback');
                        $(td).append(cellActionLinks);
                        $(td).children('span.reject-link').addClass('rejected')
                        
                } else  {
                        var itemInfo = lookupInfoForItem(eval($(td).attr('data')), feedback.selected_item);
                        
                        if (itemInfo != null)   {
                                $(td).html(
                                        '<a href="' + baseUrl[source] + itemInfo.url + '">' + itemInfo.price + '</a> ' + 
                                        $('<a>').append($(anchor).clone()).remove().html()
                                ).addClass('with-feedback');
                        }
                }
        }
        
        function lookupInfoForItem(data, itemName)      {
                var info = null;
                
                try {
                        $.each(data, function(index, item){
                                
                                if (item.name == itemName)      {
                                        info = {name: item.name, price: item.price, url: item.url};
                                }
                        });
                } catch(err) {
                }
                        return info;
                
        }

        $('tbody tr').each(function(index, e)   {
                var class_tr = index % 2 == 0 ? 'even' : 'odd';
                $(e).addClass(class_tr);
                markBestPrice(this);
                
                $(this).find('td').each(function(){
                        if($(this).hasClass('conflict'))        $(this).children('a').addClass('link-conflict');
                        
                        if(! $(this).hasClass('diff') && ! $(this).hasClass('name') && ! $(this).hasClass('saholic') && ! $(this).hasClass('minPrice')) {
                                $(this).append('<span class="reject-link" title="Click to reject the displayed figure">X</span>&nbsp;');
                                $(this).append('<span class="url-feedback-link" title="Click to map a product page URL">U</span>');
                        }
                });
        });
        
        updateWithFeedback();
        
        function markBestPrice(trNode)  {
                $(trNode).children().removeClass('best');
                var tdBestPrice = $(trNode).children('.saholic')[0];
                var saholicPrice = parseInt($(tdBestPrice).html());
                var bestPrice = saholicPrice;
                var maxPrice = saholicPrice;
                
                $(trNode).find('a[href!="#"]').each(function(index, a){
                        var price = getPriceAsInt(a.innerHTML);
                        
                        if (price < bestPrice)  {
                                bestPrice = price;
                                tdBestPrice = $(a).parent();
                        }
                        
                        if(price > maxPrice)    maxPrice = price;
                });
                var maxMinDiff = roundNumber((maxPrice - bestPrice) * 100 / maxPrice, 2);
                
                $(tdBestPrice).addClass('best');
                
                var tds = $(trNode).children()
                if (bestPrice < saholicPrice) {
                        $($(trNode).children()[0]).addClass('red');
                        tds[2].innerHTML = tdBestPrice.attr('source') + '<br/>' + bestPrice;
                } else {
                        try{
                                tds[2].innerHTML = "";
                        } catch(err){
                                console.log(err);
                        }
                }
                
                if (tds.length == 10)   {
                        tds[9].innerHTML = maxMinDiff + '%'
                } else  {var diffCssClass = '';
                
                if(maxMinDiff >= 25.0)  {
                        diffCssClass = 'dark-orange';
                } else if(maxMinDiff >= 10.0)   {
                        diffCssClass = 'orange';
                }
                $(trNode).append('<td class="diff ' + diffCssClass + '" title="Max-Min price difference">' + maxMinDiff + '%</td>');
                }
        }

        var baseUrl = {
                'flipkart': 'http://www.flipkart.com',
                'homeshop18': '',
                'infibeam': 'http://www.infibeam.com',
                'letsbuy': '',
                'snapdeal': 'http://www.snapdeal.com/',
                'sulekha': '',
                'tradus': 'http://www.tradus.com'
        };
        
        $('.conflict a').live('click', function(){
                var td = $(this).parent();
                
                var entityId = $(td).parent().attr('id');
                var source = $(td).attr('source');
                
                var data = eval("{results: " + $(td).attr('data') + "}");
                
                var feedback = null;
                var selectedItem = null; 
                
                if(feedbacks && feedbacks[entityId] && feedbacks[entityId][source])     {
                        feedback = feedbacks[entityId][source];
                        
                        if (feedback.type == 'select')  selectedItem = feedback.selected_item;
                }

                if (feedback && feedback.type == 'reject')      {
                        var text = '<div class="msg">Currently following set is marked <i>rejected</i></div>';
                        
                } else  {
                        var text = '';
                }
                text += '<table id="' + entityId + '" source="' + source + '">';
                
                for (i in data) {
                        var checked = selectedItem && selectedItem == data[i]['name'] ? 'checked' : ''; 
                        text += '<tr>';
                        text += '<td>' + data[i]['name'] + '</td>';
                        text += '<td><a target="_blank" href="' + baseUrl[data[i]['source']] + data[i]['url'] + '">' + data[i]['price'] + '</a></td>';
                        text += '<td><input type="radio" name="chosen_one_' + entityId + '" value="' + data[i]['name'] + '" ' + checked + '></td>';
                        text += '</tr>';
                }
                text += '<tr>';
                text += '<td colspan="2" align="center"><a id="feedback-reject" href="#">Reject All</a></td>';
                text += '<td><a id="feedback-select" href="#">Save</a></td>';
                text += '</tr>';
                text += '</table>';
                
                $.facebox(text);
        });
        
        $('#feedback-reject').live('click', function(){
                var table = $(this).parents('table');
                var feedback = {
                                type: 'reject',
                                entityId: $(table).attr('id'),
                                source: $(table).attr('source')
                };
                postFeedback(feedback, table);
        });
        
        $('#feedback-select').live('click', function(){
                var table = $(this).parents('table');
                var entityId = $(table).attr('id');
                
                var selected_item = $("input:radio[name='chosen_one_" + entityId + "']:checked").val();
                
                if(! selected_item)     {
                        
                        showMsg(table, true, 'At least one option must be selected');
                        
                } else  {
                        var feedback = {
                                        type: 'select',
                                        entityId: entityId,
                                        source: $(table).attr('source'),
                                        selected: selected_item
                        };
                        postFeedback(feedback, table);
                }
        });
        
        function postFeedback(feedback, table)  {
                var feedbackType = feedback.type;
                var entityId = feedback.entityId;
                
                $.ajax({
                        url: '/feedback',
                        type: 'POST',
                        data: feedback,
                        success: function(msg)  {
                                
                                if (feedbackType == 'reject')   {
                                        $("input:radio[name='chosen_one_" + entityId + "']:checked").prop('checked', false);
                                }
                                var td = $('#' + feedback.entityId).children('td[source=' + feedback.source + ']')[0];
                                updateCellWithFeedback(td, {type: feedback.type, selected_item: feedback.selected});
                                
                                if(table && table != 'undefined')       {
                                        showMsg(table, false, 'Your feedback has been saved successfully.');
                                }
                                markBestPrice($(td).parent());
                        },
                        error: function(msg)    {
                                showMsg(table, true, 'Error! please try again.');
                        }
                });
        }
        
        function showMsg(table, is_error, msg)  {
                msg_class = is_error ? 'error' : 'notice';
                
                if($(table).siblings('.msg').length > 0)        {
                        var msgDiv = $(table).siblings('.msg')[0];
                        $(msgDiv).html(msg);
                        
                } else  {
                        $(table).before('<div class="msg">' + msg + '</div>');
                }
        }
        
        $('.url-feedback-link').live('click', function(){
                var source = $(this).parent().attr('source');
                var entity = $(this).parent().parent().attr('id');
//              console.log(source, entity);
                var html = '<div class="form-url-feedback">\n';
                var html = 'Enter the URL you want to be crawled for this product<br>\n';
                html += '<input type="text" id="url-feedback" size="40"><br />\n';
                html += '<input type="hidden" id="entity-url-feedback" value="' + entity + '">\n';
                html += '<input type="hidden" id="source-url-feedback" value="' + source + '">\n';
                html += '<input type="button" id="submit-url-feedback" value="Save">\n';
                html += '</div>';
                $.facebox(html);
        });
        
        $('#submit-url-feedback').live('click', function(){
                $.ajax({
                        url: '/feedback-url',
                        type: 'POST',
                        data: {
                                entity: $('#entity-url-feedback').val(), 
                                source: $('#source-url-feedback').val(), 
                                url: $('#url-feedback').val()
                        },
                        beforeSend: function(){
                                $('#url-feedback, #submit-url-feedback').attr('disabled', 'disabled');
                                $('#submit-url-feedback').val('Saving...').after('<img src="/static/images/loading.gif" width="24" />');
                        },
                        success: function(data){
                                var html = '<table>';
                                html += '<tr><td class="msg" colspan="2" align="center">The URL is saved and will be crawled next time</td></tr>';
                                html += '<tr><td colspan="2">&nbsp;</td></tr>';
                                html += '<tr><td align="center">' + data.name + '</td><td align="center">Rs.' + data.price + '</td></tr>';
                                html += '</table>';
                                var form = $('#facebox').find('.content').html(html);

                                var tr = $('#' + data.entityId);
                                var td = $(tr).children('td[source=' + data.source +']')[0];
                                var anchor = $(td).children('a')[0];
                                
                                $(anchor).attr('href', data.product_url);
                                $(anchor).html(data.price);
                                
                                $(td).children('span').addClass('url-saved');
                        }
                });
        });
        
        $('.reject-link').live('click', function(){
                var source = $(this).parent().attr('source');
                var entity = $(this).parent().parent().attr('id');
                
                if($(this).hasClass('rejected'))        {
                        var td = $(this).parent();
                        
                        var url = $(td).attr('url');
                        var price = $(td).attr('price');
                        
                        var cellActionLinks = $(td).children('.url-feedback-link, .reject-link');
                        $(td).html('<a target="_blank" href="' + url + '">' + price + '</a>');
                        $(td).append(cellActionLinks);
                        console.log($(td).children('.reject-link'));
                        $($(td).children('.reject-link')[0]).removeClass('rejected');
                        
                } else  {
                        var feedback = {
                                        type: 'reject',
                                        entityId: entity,
                                        source: source
                        };
                        
                        //Setting rejected URL in the cell's DOM
                        var td = $('#' + entity).children('td[source=' + source + ']')[0];
                        var anchor = $(td).children('a')[0];
                        $(td).attr('price', $.trim($(anchor).html()));
                        $(td).attr('url', $(anchor).attr('href'));
                        
                        postFeedback(feedback);
                }
        });
        
        $('#howTo').click(function(){
                html = '<ul>\n\
                        <li class="first">The price data is crawled directly from competitor websites at 8:00 AM everyday</li>\n\
                        <li class="first">All price figures are linked to their respective product pages</li>\n\
                        <li class="first">Cells showing "Not Found" are linked to search result page of relevant website.</li>\n\
                        <li class="first">Cells showing "Conflict" are linked to set of products which are conflicting to match with\n\
                        the product. You can either select one of them or reject all depending on the case. The selection \n\
                        will be taken into account when showing the dashboard next time.</li>\n\
                        <li class="first">Clicking on "U" (present in all price cells) will pop up a form where you can submit a URL \n\
                        pointing to the product page of the product. After submission this URL will be crawled and indexed \n\
                        in real-time and saved in the list of URLs for scheduled crawling in future.</li>\n\
                        <li class="first">In each row, right most cell shows the percentage difference between the minimum and maximum \n\
                        price of that product. Color coding:\n\
                                <ul>\n\
                                        <li>Yellow: 10 - 24.99% difference</li>\n\
                                        <li>Orange: Above 24.99%</li>\n\
                                </ul></li>\n\
                        <li class="first">In case of further clarification, email your query at varun.gupta@shop2020.in</li>\n\
                        </ul>';
                $.facebox(html);
        });
        
        $('#all').click(function(){
                $('tbody tr').show();
        });
        
        $('#watchlist').click(function(){
                $('tbody tr .watchlist-icon').each(function(){
                        if(! $(this).hasClass('on-watchlist'))  $(this).parent().parent().hide();
                });
        });
        
        $('#downloadXL').click(function(){
                $('form[action="/download"]').submit();
        });
        
        $('#facebox .close').live('click', function(){});
        
        var watchList = {
                        get: function() {
                                $.ajax({
                                        type: 'GET',
                                        url: '/watchlist',
                                        
                                        
                                        error: function(jqXHR, textStatus, errorThrown) {
                                                console.log(jqXHR, textStatus, errorThrown);
                                                alert('Could not get WatchList. Try again later.');
                                        },
                                        success: function(data, textStatus, jqXHR)      {
                                                console.log(data, textStatus, jqXHR);
                                                entities = eval('(' + data + ')');
                                                
                                                $.each(entities, function(index, entity)        {
                                                        var elementId = '#' + entity;
                                                        var tr = $(elementId);
                                                        $($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
                                                });
                                        }
                                });
                        },
                        add: function(entity)   {
                                $.ajax({
                                        type: 'POST',
                                        url: '/watchlist',
                                        data: {'type': 'save', 'entity': entity},
                                        
                                        error: function(jqXHR, textStatus, errorThrown) {
                                                console.log(jqXHR, textStatus, errorThrown);
                                                alert('Could not add this item to WatchList. Try again later.');
                                        },
                                        success: function(data, textStatus, jqXHR)      {
                                                console.log(data, textStatus, jqXHR);
                                                $($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
                                        }
                                });
                        },
                        remove: function(entity)        {
                                $.ajax({
                                        type: 'POST',
                                        url: '/watchlist',
                                        data: {'type': 'delete', 'entity': entity},
                                        
                                        error: function(jqXHR, textStatus, errorThrown) {
                                                console.log(jqXHR, textStatus, errorThrown);
                                                alert('Could not remove this item from WatchList. Try again later.');
                                        },
                                        success: function(data, textStatus, jqXHR)      {
                                                console.log(data, textStatus, jqXHR);
                                                $($('#' + entity).find('.watchlist-icon')[0]).removeClass('on-watchlist');
                                        }
                                });
                        }
        };
        
        watchList.get();
        
        $('.watchlist-icon').click(function(){
                
                var entity = $(this).parent().parent().attr('id');
                
                if($(this).hasClass('on-watchlist'))    {
                        watchList.remove(entity);
                } else  {
                        watchList.add(entity);
                }
        });
});