APIs

Show:
/**
 Settings Backbone View
 @class FQManagerView
 @constructor
 @return {Object} instantiated FQManagerView
 **/
define(['jquery', 'backbone', 'ScrollToPlugin', 'TweenMax', 'FQQueuePropView', 'QueuesCollection', 'AnalyticsCollection', 'stopwatch', 'XDate', 'moment'], function ($, Backbone, ScrollToPlugin, TweenMax, FQQueuePropView, QueuesCollection, AnalyticsCollection, stopwatch, XDate, moment) {

    var FQManagerView = Backbone.View.extend({

        /**
         Constructor
         @method initialize
         **/
        initialize: function () {
            var self = this;
            self.m_offsetPosition = 0;
            self.m_selectedServiceID = -1;
            self.m_fqCreatorView = BB.comBroker.getService(BB.SERVICES.FQCREATORVIEW);
            self.m_stopWatchHandle = new Stopwatch();
            self.m_liveUpdatehandler = undefined;
            self.m_inView = false;
            self.m_masterPanelInView = true;
            self.m_fqQueuePropView = new FQQueuePropView({
                el: Elements.FASTERQ_QUEUE_PROPERTIES
            });

            self._listenNextPrev();
            self._listenCalled();
            self._listenServiced();
            self._listenGoBack();
            self._listenOpenRemoteStatus();

            self.listenTo(self.options.stackViewMaster, BB.EVENTS.SELECTED_STACK_VIEW, function (e) {
                if (e.$el.selector == Elements.FASTERQ_PANEL) {
                    self.m_masterPanelInView = true;
                } else {
                    self.m_masterPanelInView = false;
                }
            });

            self.listenTo(self.options.stackView, BB.EVENTS.SELECTED_STACK_VIEW, function (e) {
                if (e == self) {
                    self.m_inView = true;
                    self.m_liveUpdatehandler = setInterval(function () {
                        if (!self.m_masterPanelInView)
                            return;
                        self._getQueues(false);
                        self._pollNowServicing();
                    }, 10000);

                    self._getQueues(true);
                    // self._scrollTo($(Elements.FQ_LINE_QUEUE_COMPONENT + ':first-child'));

                } else {
                    self.m_inView = false;
                    window.clearInterval(self.m_liveUpdatehandler);
                    window.clearInterval(self.m_statusHandler);
                }
            });
        },

        /**
         Listen to go back to Line selection
         @method _listenGoBack
         **/
        _listenGoBack: function () {
            var self = this;
            $(Elements.FASTERQ_MANAGER_BACK).on('click', function () {
                self.options.stackView.selectView(Elements.FASTERQ_CREATOR_CONTAINER);
                self.m_property = BB.comBroker.getService(BB.SERVICES['PROPERTIES_VIEW']).resetPropertiesView();
            });
        },

        /**
         Get Queues collection from server and render UI
         @method _getLines server:getQueues
         @params {boolean} i_scrollTo scroll to
         **/
        _getQueues: function (i_scrollTo) {
            var self = this;
            self.m_queuesCollection = new QueuesCollection();
            self.m_queuesCollection.fetch({
                data: {line_id: self.m_fqCreatorView.getSelectedLine()},
                success: function (models) {
                    self._updateTotalToBeServiced();
                    self._render();
                    if (i_scrollTo)
                        self._scrollToFirstNotServiced();
                },
                error: function () {
                    log('error fetch /Queues collection');
                }
            });
        },

        /**
         Get the last called service_id for line
         @method _pollNowServicing server:LastCalledQueue
         **/
        _pollNowServicing: function () {
            var self = this;
            $.ajax({
                url: BB.CONSTS.ROOT_URL + '/LastCalledQueue',
                data: {
                    business_id: BB.Pepper.getUserData()['businessID'],
                    line_id: self.m_fqCreatorView.getSelectedLine()
                },
                success: function (i_model) {
                    $(Elements.FQ_NOW_SERVICING).text(i_model.service_id);
                },
                error: function (e) {
                    log('error ajax ' + e);
                },
                dataType: 'json'
            });
        },

        /**
         Update the total number of queues left to be serviced
         @method _updateTotalToBeServiced
         **/
        _updateTotalToBeServiced: function () {
            var self = this;
            if (_.isUndefined(self.m_queuesCollection))
                return;
            var total = 0;
            self.m_queuesCollection.each(function (model) {
                if (_.isNull(model.get('serviced')))
                    total++;
                $(Elements.FQ_TOTAL_TO_BE_SERVICED).text(total);
            });

        },

        /**
         Start the stop watch UI
         @method _watchStart
         **/
        _watchStart: function () {
            var self = this;
            self.m_stopWatchHandle.setListener(function (e) {
                $(Elements.FQ_TIME_WITH_CUSTOMER).text(self.m_stopWatchHandle.toString());
            });
            self.m_stopWatchHandle.start();
        },

        /**
         Stop the stop watch UI
         @method _watchStop
         **/
        _watchStop: function () {
            var self = this;
            self.m_stopWatchHandle.stop();
            self.m_stopWatchHandle.reset();
            $(Elements.FQ_TIME_WITH_CUSTOMER).text('00:00:00');
        },

        /**
         Render the UI queues list from returned server data
         @method _render
         **/
        _render: function () {
            var self = this;
            if (!self.m_inView)
                return;
            self.m_fqQueuePropView.showProp();
            var snippet;


            $(Elements.FQ_LINE_QUEUE_COMPONENT).empty();

            var selectedLine = self.m_fqCreatorView.getSelectedLine();
            $(Elements.FQ_LINE_NAME).text(self.m_fqCreatorView.getSelectedLineName(selectedLine));

            for (var i = -8; i < 0; i++) {
                snippet = '<div class="' + BB.lib.unclass(Elements.CLASS_PERSON_IN_LINE) + '">';
                $(Elements.FQ_LINE_QUEUE_COMPONENT).append(snippet);
            }

            self.m_queuesCollection.each(function (model) {
                var serviceID = model.get('service_id');
                var called = model.get('called');
                var serviced = model.get('serviced');
                var color = 'gray';

                if (serviced) {
                    color = '#ACFD89';
                } else if (called) {
                    color = '#BE6734';
                } else {
                    color = '#D0D0D0';
                }

                var val = BB.lib.padZeros(serviceID, 3, 0);
                snippet = '<div data-service_id="' + serviceID + '" class="' + BB.lib.unclass(Elements.CLASS_PERSON_IN_LINE) + '">';
                snippet += '<i style="font-size: 90px; color: ' + color + '"  class="fa fa-male">';
                snippet += '</i><h3 style="position: relative; left: 6px">' + val + '</h3></div>';
                $(Elements.FQ_LINE_QUEUE_COMPONENT).append(snippet);
            });
            self._listenToPersonSelected();
            self._getAnalytics();
        },

        /**
         Get line analytics / stats
         @method _getAnalytics server:lineAnalytics
         **/
        _getAnalytics: function () {
            var self = this;
            self.m_analyticsCollection = new AnalyticsCollection();

            self.m_analyticsCollection.fetch({
                data: {line_id: self.m_fqCreatorView.getSelectedLine()},
                success: function (models) {
                    self._calcAverages();
                },
                error: function () {
                    log('error fetch /Queues collection');
                }
            });
        },

        /**
         Calculate average respond and service line times
         @method _calcAverages
         **/
        _calcAverages: function () {
            var self = this;

            var avgServiceTime = [];
            var avgCalledTime = [];

            self.m_analyticsCollection.forEach(function (i_model) {
                var entered = i_model.get('entered');
                var serviced = i_model.get('serviced');
                var called = i_model.get('called');

                if (_.isNull(called)) {
                    // customer not called, do nothing
                } else if (!_.isNull(serviced)) {

                    // customer called & serviced
                    var xEntered = new XDate(entered);
                    var minFromEnteredToCalled = xEntered.diffMinutes(called);
                    if (minFromEnteredToCalled < 0)
                        minFromEnteredToCalled = 1;
                    avgCalledTime.push(minFromEnteredToCalled);

                    var xCalled = new XDate(called);
                    var minFromCalledToServiced = xCalled.diffMinutes(serviced);
                    avgServiceTime.push(minFromCalledToServiced);

                } else {

                    // customer called not serviced
                    var xEntered = new XDate(entered);
                    var minFromEnteredToCalled = xEntered.diffMinutes(called);
                    if (minFromEnteredToCalled < 0)
                        minFromEnteredToCalled = 1;
                    avgCalledTime.push(minFromEnteredToCalled);
                }
            });

            var avgServiceTimeCalc = _.reduce(avgServiceTime, function (memo, num) {
                    return memo + num;
                }, 0) / (avgServiceTime.length === 0 ? 1 : avgServiceTime.length);

            var avgCalledTimeCalc = _.reduce(avgCalledTime, function (memo, num) {
                    return memo + num;
                }, 0) / (avgCalledTime.length === 0 ? 1 : avgCalledTime.length);

            $(Elements.FQ_AVG_CUSTOMER_SERVICE).text(BB.lib.parseToFloatDouble(avgServiceTimeCalc))
            $(Elements.FQ_AVG_CUSTOMER_WAIT).text(BB.lib.parseToFloatDouble(avgCalledTimeCalc));
        },

        /**
         Scroll to first queue that has not been serviced yet, if non exist, scroll to first queue
         @method _scrollToFirstNotServiced
         **/
        _scrollToFirstNotServiced: function () {
            var self = this;
            var found = false;
            if (self.m_queuesCollection.length == 0)
                return;
            self.m_queuesCollection.each(function (model) {
                if (found)
                    return;
                var service_id = model.get('service_id');
                var serviced = model.get('serviced');
                if (_.isNull(serviced)) {
                    var elem = self.$('[data-service_id="' + service_id + '"]');
                    self._scrollTo(elem);
                    found = true;
                }
            });
        },

        /**
         Listen to UI person / queue click to load selected properties and scroll to selection
         @method _listenToPersonSelected
         **/
        _listenToPersonSelected: function () {
            var self = this;
            $(Elements.CLASS_PERSON_IN_LINE).off().on('click', function (e) {
                var person = $(this).closest('[data-service_id]');
                $(person).data('service_id');
                self._scrollTo(person);
            })
        },

        /**
         Scroll to position of selected queue / UI person
         @method _scrollTo
         @param {Element} i_element
         **/
        _scrollTo: function (i_element) {
            var self = this;
            self._watchStop();
            if (i_element.length == 0)
                return;
            self.m_selectedServiceID = $(i_element).data('service_id');
            var model = self.m_queuesCollection.where({'service_id': self.m_selectedServiceID})[0];
            self._populatePropsQueue(model);

            var scrollXPos = $(i_element).position().left;
            // console.log('current offset ' + scrollXPos + ' ' + 'going to index ' + $(i_element).index() + ' service_id ' + $(i_element).data('service_id'));
            self.m_offsetPosition = $(Elements.FQ_LINE_QUEUE_COMPONENT_CONTAINER).scrollLeft();
            scrollXPos += self.m_offsetPosition;
            var final = scrollXPos - 480;
            TweenLite.to(Elements.FQ_LINE_QUEUE_COMPONENT_CONTAINER, 2, {
                scrollTo: {x: final, y: 0},
                ease: Power4.easeOut
            });
        },

        /**
         Populate the selected queue's properties UI
         @method _populatePropsQueue
         @params {Number} i_value
         **/
        _populatePropsQueue: function (i_model) {
            var self = this;
            if (_.isUndefined(i_model))
                return;
            if (!self.m_inView)
                return;
            $(Elements.FQ_SELECTED_QUEUE).text(i_model.get('service_id'));
            $(Elements.FQ_VERIFICATION).text(i_model.get('verification') == -1 ? 'print out' : i_model.get('verification'));
            $(Elements.FQ_CALLED_BY).text(_.isNull(i_model.get('called_by')) ? 'none' : i_model.get('called_by'));
        },

        /**
         Listen to queue being called, mark on UI and post to server
         @method _listenCalled
         **/
        _listenCalled: function () {
            var self = this;
            $(Elements.FQ_LINE_COMP_CALL).on('click', function () {
                var model = self.m_queuesCollection.where({'service_id': self.m_selectedServiceID})[0];
                if (_.isUndefined(model))
                    return;
                if (!_.isNull(model.get('serviced'))) {
                    bootbox.alert('customer has already been serviced');
                    return;
                }
                self._watchStart();
                var elem = self.$('[data-service_id="' + (self.m_selectedServiceID) + '"]');
                $(elem).find('i').fadeOut(function () {
                    $(this).css({color: '#BE6734'}).fadeIn();
                });
                $(Elements.FQ_LAST_CALLED).text(self.m_selectedServiceID);
                var d = new XDate();
                model.set('called', d.toString('M/d/yyyy hh:mm:ss TT'));
                model.set('called_by', pepper.getUserData().userName);
                model.set('called_by_override', false);

                self._populatePropsQueue(model);

                model.save(null,{
                    success: (function (model, data) {
                        if (data.updated == 'alreadyCalled'){
                            bootbox.confirm('Customer already called by user' + data.called_by + ' <br/><br/>Would you like to call the customer again?', function(result) {
                                if (result){
                                    model.set('called_by_override', true);
                                    model.save();
                                }
                            });
                        }
                    }),
                    error: (function (e) {
                        bootbox.alert('Service request failure: ' + e);
                    }),
                    complete: (function (e) {
                    })
                });
            });
        },

        /**
         Listen to queue being serviced, mark on UI and post to server
         @method _listenServiced
         **/
        _listenServiced: function () {
            var self = this;
            $(Elements.FQ_LINE_COMP_SERVICED).on('click', function () {
                self._watchStop();
                var model = self.m_queuesCollection.where({'service_id': self.m_selectedServiceID})[0];
                if (_.isUndefined(model))
                    return;
                if (_.isNull(model.get('called'))) {
                    bootbox.alert('customer has not been called yet');
                    return;
                }
                if (!_.isNull(model.get('serviced'))) {
                    bootbox.alert('customer has already been serviced');
                    return;
                }
                var elem = self.$('[data-service_id="' + (self.m_selectedServiceID) + '"]');
                $(elem).find('i').fadeOut(function () {
                    $(this).css({color: '#ACFD89'}).fadeIn();
                });
                $(Elements.FQ_LAST_SERVICED).text(self.m_selectedServiceID);
                var d = new XDate();
                model.set('serviced', d.toString('M/d/yyyy hh:mm:ss TT'));
                log('service ' + model.get('serviced'));
                model.save({
                    success: (function (model, data) {
                        log(model);
                    }),
                    error: (function (e) {
                        log('Service request failure: ' + e);
                    }),
                    complete: (function (e) {
                    })
                });
            });
        },

        /**
         Listen to person navigation button selection to scroll to selected queue index
         @method _listenNextPrev
         **/
        _listenNextPrev: function () {
            var self = this;

            $(Elements.FQ_LINE_COMP_PREV).on('click', function () {
                if (_.isUndefined(self.m_queuesCollection))
                    return;
                if (self.m_selectedServiceID == 1)
                    return;
                var elem = self.$('[data-service_id="' + (self.m_selectedServiceID - 1) + '"]');
                self._scrollTo(elem);
            });

            $(Elements.FQ_LINE_GOTO).on('click', function () {
                var value = $(Elements.FQ_GOTO_LINE_INPUT).val();
                if (_.isUndefined(self.m_queuesCollection))
                    return;
                var elem = self.$('[data-service_id="' + value + '"]');
                self._scrollTo(elem);
            });

            $(Elements.FQ_LINE_COMP_NEXT).on('click', function () {
                if (_.isUndefined(self.m_queuesCollection))
                    return;
                if (self.$('[data-service_id]').children().length == self.m_queuesCollection.length)
                    return;
                var elem = self.$('[data-service_id="' + (self.m_selectedServiceID + 1) + '"]');
                self._scrollTo(elem);
            });

        },

        /**
         Open remote status terminal for selected queue
         @method _listenOpenRemoteStatus
         **/
        _listenOpenRemoteStatus: function () {
            var self = this;
            $(Elements.FQ_OPEN_CUSTOMER_REMOTE_STATUS).on('click', function (e) {
                var line_id = self.m_fqCreatorView.getSelectedLine()
                var data = {
                    call_type: 'REMOTE_STATUS',
                    business_id: BB.Pepper.getUserData()['businessID'],
                    line_id: line_id,
                    line_name: self.m_fqCreatorView.getSelectedLineName(line_id)
                };
                data = $.base64.encode(JSON.stringify(data));
                var url = BB.CONSTS.BASE_URL + '?mode=remoteStatus&param=' + data;
                window.open(url, "_blank", "toolbar=yes, scrollbars=yes, resizable=yes, top=10, left=10, width=400, height=400");
            })
        }
    });

    return FQManagerView;
});