Source: directives/rastreamento/rastreamento.js

/**
 * @ngdoc directives
 * @name Rastreamento
 * @module s4c.directives,rastreamento.Rastreamento
 * 
 * @description `s4c-rastreamento` exibe informações sobre um ponto de
 *              interesse
 * 
 * @example <s4c-rastreamento> </s4c-rastreamento>
 * 
 */
(function () {
    'use strict';

    rastreamentoController.$inject = [
        '$scope',
        '$window',
        '$filter',
        '$anchorScroll',
        'ngTableParams',
        'MsiService',
        'MsiFilter',
        'CommService',
        'MainState',
        'DetalhamentoManager',
        'IncidentesManager',
        'MapaManager',
        'CamadasService',
        'localize',
        'Base',
        '$http',
        'API_ENDPOINT',
        '$mdDialog',
        'PontoMovelManager'
    ];

    function rastreamentoController(
        $scope,
        $window,
        $filter,
        $anchorScroll,
        ngTableParams,
        MsiService,
        MsiFilter,
        CommService,
        MainState,
        DetalhamentoManager,
        IncidentesManager,
        MapaManager,
        CamadasService,
        localize,
        Base,
        $http,
        API_ENDPOINT,
        $mdDialog,
        PontoMovelManager) {

        $scope.res = $scope.$root.res;

        /**
         * @method _filterAfterQuery
         * @param {*} incidentes 
         */
        function _filterAfterQuery(incidentes) {
            var newIncidentes = _.chain(incidentes).map(parseIncidente).value();

            newIncidentes = _filterAberto24h(incidentes);
            newIncidentes.forEach(function (obj, index) {
                if (obj.extras != null && obj.extras.informacoes != null) {
                    var prioridade = obj.extras.informacoes.filter(function (item, i) {
                        if (item.label === 'Prioridade') {
                            delete obj.extras.informacoes[i];
                        }
                    });
                }
            });

            return newIncidentes;
        }

        // 1. Aberto 2. Fechado 3. Aberto 24h
        /**
         * @method _filterAberto24h
         * @param {*} incidentes 
         */
        function _filterAberto24h(incidentes) {
            var filterData = _getFilterData();
            var statuses = _filtrarAtivos(filterData.statuses, 'id');
            var timeWindow = _setTimeWindow(filterData.timeWindow, statuses);

            var newIncidentes = incidentes.filter(function (incidente) {
                if (!statuses.length) return incidente;

                if (incidente.status === 'ABERTO' && statuses.indexOf(1) === -1) {
                    if (incidente.inicio.isBefore(moment(timeWindow.start))) {
                        return incidente;
                    }
                } else {
                    return incidente;
                }
            });

            return newIncidentes;
        }

        var filterInstance = MsiFilter.getInstance('filtro-msi');

        $scope.pontosMoveisGrid = [];
        $scope.pontosMoveis = [];
        $scope.moduleFilter = {
            nome: '',
            agencia: ''
        };
        $scope.fields = [
            /*{
                active: true,
                pinnedLeft: true,
                enableFiltering: false,
                name: '',
                field: 'statusIcon',
                width: 40,
                headerCellClass: 'tableHeader',
                enableColumnMenu: false,
                cellClass: 'tableRow',
                headerCellTemplate: '<md-icon md-svg-icon="settings:engine" class="settings" ng-click="grid.appScope.toggleFieldSelection()"></md-icon>',
                cellTemplate: '<img ng-src="{{grid.appScope.setIconUrl(row)}}" ng-click="grid.appScope.openDetalhamentoFromRow(row)" width="14" height="14" style="margin-left: 7px; margin-top: 7px;"/>'
            },*/{
                active: true,
                name: 'Nome',
                field: 'nome',
                enableColumnMenu: false,
                width: 200,
                headerCellClass: 'tableHeader',
                cellClass: 'tableRow'
            }, {
                active: true,
                name: 'Descrição',
                field: 'descricao',
                width: 250,
                enableColumnMenu: false,
                headerCellClass: 'tableHeader',
                cellClass: 'tableRow'
            }, {
                active: true,
                name: 'Tipo',
                field: 'nomeTipo',
                width: 150,
                enableColumnMenu: false,
                headerCellClass: 'tableHeader',
                cellClass: 'tableRow'
            }
        ];

        // Main Load of PontosMoveis
        $scope.loadPontosMoveis = true;
        /**
         * @method loadPontosMoveis
         */
        function loadPontosMoveis() {
            var filterData = _getFilterData();
            //var query = _setQuery(filterData);

            if (!$scope.loadPontosMoveis) {
                return;
            }

            $scope.loadPontosMoveis = false;

            $http.get(API_ENDPOINT + "ponto_movel")
                .then(function (result) {

                    $scope.pontosMoveis = result.data;
                    loadTable($scope.pontosMoveis);

                }, function (err) {
                    $mdDialog
                        .show($mdDialog.alert()
                            .title($scope.res('COMUM_ERRO'))
                            .content(err.data.message)
                            .ok($scope.res('COMUM_OK')));
                });

        }

        /**
         * @method loadTable
         * @param {*} pontosMoveis 
         */
        function loadTable(pontosMoveis) {

            $scope.pontosMoveisGrid.data = pontosMoveis;

            /*
             * When Row of Table is clicked, rowSelectionChanged is invoked
            */
            if ($scope.gridApi) {
                $scope.gridApi.selection.on.rowSelectionChanged(null, function (row) {
                    $scope.voarPontoMovel(row.entity);
                });

                resizeTable();
            }
        }

        // Watch the Module Size
        $scope.$watch(
            function () {
                if (angular.element('#modulo-rastreamento')[0] != null) {
                    return angular.element('#modulo-rastreamento')[0].offsetHeight
                }
            },
            function (value) {
                resizeTable();
            }
        );

        $scope.setIconUrl = function (row) {
            var incidente = row.entity;
            if (incidente.status == "ABERTO") {
                return "/assets/images/IncidenteLegenda/s4c_ic_incident_open_fill_subtitle.svg";
            } else if (incidente.status == "FECHADO") {
                return "/assets/images/IncidenteLegenda/s4c_ic_incident_closed_fill_subtitle.svg";
            }
        };

        $scope.openDetalhamentoFromRow = function (row) {
            var incidente = row.entity;
            $scope.abrirDetalhamento(incidente);
        };

        function resizeTable() {
            if ($scope.gridApi) {

                if (angular.element('#modulo-rastreamento')[0]) {
                    var gridSize = $scope.gridApi.grid.gridHeight;
                    var moduleHeight = angular.element('#modulo-rastreamento')[0].clientHeight;

                    var gridHeight = moduleHeight - 45;
                    $scope.uiGridHeight = { height: gridHeight + 'px' };
                }
            }
        }

        /**
         * @method filterTab
         */
        $scope.filterTab = function (agencia) {
            $scope.moduleFilter.agencia = (agencia.nome === $scope.res('COMUM_TODOS')) ? '' : agencia.id;
            $scope.searchTable($scope.moduleFilter);
        };

        /**
         * @method searchTable
         */
        $scope.searchTable = function (filter) {
            var filterData = {};

            if (filter.nome !== '') {
                filterData.nome = filter.nome;
            }

            var pontosMoveisFiltered = $filter('filter')($scope.pontosMoveis, filterData);

            $scope.pontosMoveisGrid.data = pontosMoveisFiltered;
        };

        $scope.pontosMoveisGrid = {
            enableRowSelection: true,
            enableRowHeaderSelection: false,
            multiSelect: false,
            flatEntityAccess: true,
            fastWatch: true,
            noUnselect: true,
            columnDefs: $scope.fields
        };

        $scope.pontosMoveisGrid.onRegisterApi = function (gridApi) {
            $scope.gridApi = gridApi;
        };

        /**
         * @method parseToGrid
         * @param {*} incidente 
         */
        function parseToGrid(incidente) {
            incidente.statusIcon = (incidente.status === 'ABERTO') ? 'opened' : 'closed';

            if (incidente.inicio) {
                incidente.inicio = moment(incidente.inicio).format('DD/MM/YYYY - HH:mm');
            }

            incidente.CategoriaNome = incidente.CategoriaIncidente.nome;
            return incidente;
        }

        /**
         * @method verificaMenuCarregado
         * @param {*} incidentes 
         */
        function verificaMenuCarregado(incidentes) {
            if (!CamadasService.isLoaded) {
                CamadasService.isLoaded = true;
                setTimeout(function () {
                    verificaMenuCarregado(incidentes);
                }, 1000);
            } else {
                _updateCamadasService(incidentes);
            }
        }

        /**
         * @method _updateCamadasService
         * @param {*} incidentes 
         */
        function _updateCamadasService(incidentes) {

            var filterData = _getFilterData();
            var categorias = filterData.categorias;
            var statuses = filterData.statuses;

            var itensParaDesativar = [];

            _.each(categorias, function (categoria) {
                _.each(statuses, function (status) {
                    if (status.ativo && categoria.ativo) {

                        CamadasService.ativarSubMenuIncidente(categoria.id);

                    } else {
                        itensParaDesativar.push({
                            categoriaId: categoria.id,
                            status: status.nome
                        });
                    }
                });
            });

            _.each(itensParaDesativar, function (item) {
                CamadasService.desativarSubMenuStatusMsi(item.categoriaId, item.status, {
                    origem: 'filtro'
                });
            });
        }

        /**
         * @method exportToPdf
         */
        $scope.exportToPdf = function () {
            var ids = $scope.pontosMoveisGrid.data.map(function (incidente) {
                return incidente.id;
            });

            if (ids.length) {
                IncidentesService.getPdfReport(ids)
                    .then(function (data) {
                        var file = new Blob([data], { type: 'application/pdf' });
                        var fileURL = URL.createObjectURL(file);
                        var a = document.createElement("a");
                        document.body.appendChild(a);
                        a.style = "display: none";
                        a.href = fileURL;
                        a.download = $scope.res('Incidentes') + ".pdf";
                        a.click();

                        $mdDialog
                            .show($mdDialog.alert()
                                .title($scope.res('COMUM_SUCESSO'))
                                .content('Arquivo gerado com sucesso.')
                                .ok($scope.res('COMUM_OK')));
                    });
            }
        };

        $scope.fieldSelection = false;
        /**
         * @method toggleFieldSelection
         */
        $scope.toggleFieldSelection = function () {
            $scope.pontosMoveisGrid.columnDefs = $scope.fields.filter(function (column) {
                return column.active === true;
            });
            $scope.fieldSelection = !$scope.fieldSelection;
        };

        /**
         * @method parseIncidente
         * @param {*} incidente 
         */
        function parseIncidente(incidente) {

            if (incidente.inicio) {
                incidente.inicio = moment(moment(incidente.inicio).toDate());
            }

            if (incidente.fim) {
                incidente.fim = moment(moment(incidente.fim).toDate());
            }

            if (incidente.fim &&
                incidente.status === 'FECHADO' &&
                incidente.inicio) {

                if (moment().dayOfYear() - incidente.fim.dayOfYear() >= 1) {
                    incidente.icon = '/data-s4c/teste/ic_incidentes_grey_26px.svg';
                }
            }

            if (incidente.status && incidente.status === 'ABERTO') {
                incidente.icon = '/data-s4c/teste/ic_incidentes_red_26px.svg';
            }

            return incidente;
        }

        /**
         * @method _filtrarIncidente
         * @param {*} incidente 
         */
        function _filtrarIncidente(incidente) {
            return MsiFilter.getInstance('filtro-msi').filtrarIncidente(incidente);
        }

        /**
         * @method _filtrarIncidentes
         * @param {*} incidentes 
         */
        function _filtrarIncidentes(incidentes) {
            return _.chain(incidentes)
                .map(parseIncidente)
                .sortBy(function (incidente) {
                    if (incidente.status === 'ABERTO') {
                        return 0;
                    }

                    if (incidente.fim && moment().dayOfYear() - incidente.fim.dayOfYear() >= 1) {
                        return 2;
                    }

                    return 1;

                })
                .value();
        }

        /**
         * @method _setQueryStatus
         * @param {*} statuses 
         */
        function _setQueryStatus(statuses) {
            return { $in: statuses };
        }

        /**
         * @method _setStatuses
         * @param {*} statuses 
         */
        function _setStatuses(statuses) {
            if (statuses.length) {
                var arrFilter = [];
                if (statuses.indexOf(1) > -1 || statuses.indexOf(3) > -1) {
                    arrFilter.push("ABERTO");
                }
                if (statuses.indexOf(2) > -1) {
                    arrFilter.push("FECHADO");
                }

                return arrFilter;
            } else {
                return ["ABERTO"];
            }
        }

        /**
         * @method _setTimeWindow
         * @param {*} timeWindow 
         */
        function _setTimeWindow(timeWindow) {
            var newTimeWindow = {
                start: timeWindow.start,
                end: timeWindow.end
            };

            newTimeWindow.start = moment(newTimeWindow.start).startOf('day').format();
            newTimeWindow.end = moment(newTimeWindow.end).endOf('day').format();

            return newTimeWindow;
        }

        /**
         * @method _filtrarAtivos
         * @param {*} dataArr 
         * @param {*} filterString 
         */
        function _filtrarAtivos(dataArr, filterString) {
            return _.chain(dataArr)
                .filter('ativo')
                .map(filterString)
                .value();
        }

        /**
         * @method _setQueryGravidadeIncidenteId
         * @param {*} gravidades 
         */
        function _setQueryGravidadeIncidenteId(gravidades) {
            var ativos = _filtrarAtivos(gravidades, 'id');
            return (ativos.length) ? { $in: ativos } : null;
        }

        /**
         * @method _setQueryTipoIncidenteId
         * @param {*} tipoIncidentes 
         */
        function _setQueryTipoIncidenteId(tipoIncidentes) {
            var ativos = _filtrarAtivos(tipoIncidentes, 'id');
            return (ativos.length) ? { $in: ativos } : null;
        }

        /**
         * @method _setQueryTimeWindow
         * @param {*} timeWindow 
         */
        function _setQueryTimeWindow(timeWindow) {
            return {
                $between: [
                    timeWindow.start,
                    timeWindow.end
                ]
            };
        }

        /**
         * @method _setQueryCategoria
         * @param {*} categorias 
         */
        function _setQueryCategoria(categorias) {
            if (categorias.length) {
                return { $in: _filtrarAtivos(categorias, 'id') };
            }
            return;
        }

        /**
         * @method _setQuery
         * @param {*} filterData 
         */
        function _setQuery(filterData) {
            var data = {};
            var timeWindow = _setTimeWindow(filterData.timeWindow, _filtrarAtivos(filterData.statuses, 'id'));
            var statuses = _setStatuses(_filtrarAtivos(filterData.statuses, 'id'));

            data.status = _setQueryStatus(statuses);
            data.CategoriaIncidenteId = _setQueryCategoria(filterData.categorias);
            data.GravidadeIncidenteId = _setQueryGravidadeIncidenteId(filterData.gravidades);
            data.TipoIncidenteId = _setQueryTipoIncidenteId(filterData.tipoIncidentes);
            data.inicio = _setQueryTimeWindow(timeWindow);
            //data.limit = 50;

            // Deletes invalid filters
            for (var filtro in data) {
                if (data.hasOwnProperty(filtro) && (data[filtro] === null) || data[filtro] === undefined) {
                    delete data[filtro];
                }
            }

            return {
                where: data,
                include: 'CategoriaIncidente'
            };
        };


        /**
         * @method setQuery
         */
        function setQuery() {
            var filterData = _getFilterData();
            var data = {};
            var timeWindow = _setTimeWindow(filterData.timeWindow, _filtrarAtivos(filterData.statuses, 'id'));
            var statuses = _setStatuses(_filtrarAtivos(filterData.statuses, 'id'));

            data.status = _setQueryStatus(statuses);
            data.CategoriaIncidenteId = _setQueryCategoria(filterData.categorias);
            data.GravidadeIncidenteId = _setQueryGravidadeIncidenteId(filterData.gravidades);
            data.TipoIncidenteId = _setQueryTipoIncidenteId(filterData.tipoIncidentes);
            data.inicio = _setQueryTimeWindow(timeWindow);
            //data.limit = 50;

            // Deletes invalid filters
            for (var filtro in data) {
                if (data.hasOwnProperty(filtro) && (data[filtro] === null) || data[filtro] === undefined) {
                    delete data[filtro];
                }
            }

            return {
                where: data,
                include: {
                    model: 'GrupoUsuarios',
                    'as': 'GruposUsuarios',
                    include: {
                        model: 'Usuario'
                    },
                    where: {
                        id: {
                            $in: _.chain(filterData.gruposUSuarios)
                                .filter('ativo')
                                .map('id')
                                .value()
                        }
                    }
                },
                order: 'inicio DESC'

            };
        };

        /**
         * @method _getFilterData
         */
        function _getFilterData() {

            var filter = MsiFilter.getInstance('filtro-msi');

            return {
                categorias: filter.categorias,
                gruposUsuarios: filter.gruposUsuarios,
                tipoIncidentes: filter.tipoIncidentes,
                statuses: filter.statuses,
                gravidades: filter.gravidades,
                timeWindow: filter.dataRange
            };
        }

        $scope.incidenteAtivo = -1;

        /**
         * @method abrirDetalhamento
         */
        $scope.abrirDetalhamento = function (incidente) {
            if (typeof incidente.geojson === 'string') {
                incidente.geojson = JSON.parse(incidente.geojson);
            }

            DetalhamentoManager.abrirIncidente(incidente.id, {
                lat: incidente.geojson.coordinates[1],
                lng: incidente.geojson.coordinates[0]
            });
        };

        var lastPontoMovel;
        /**
         * @method voarPontoMovel
         */
        $scope.voarPontoMovel = function (pontoMovel) {

            if (pontoMovel == lastPontoMovel) {
                return;
            }

            lastPontoMovel = pontoMovel;

            PontoMovelManager.pontoMovelAtivo = pontoMovel;
            CamadasService.ativarMenuDoPontoMovel(pontoMovel.tipo.id);

        	/*$http.post(API_ENDPOINT + "obterPosicaoAtualER", pontoMovel.idElementoRastreavel)
            .then(function(result) {
            	
                $scope.elementoRastreavelInfo = result.data;
                PontoMovelManager.posicaoAtualER = result.data;
                var ponto = {
                    lat: $scope.elementoRastreavelInfo.latitude,
                    lng: $scope.elementoRastreavelInfo.longitude
                };
                
                MapaManager.desenharPontoMovel(pontoMovel, ponto);
                CamadasService.ativarMenuDoPontoMovel(pontoMovel.tipo.id);
                if ($scope.elementoRastreavelInfo){
                	PontoMovelManager.elementoRastreavel = $scope.elementoRastreavelInfo.elementoRastreavel;
                }
                    
            }, function (err) {
                $mdDialog
                    .show($mdDialog.alert()
                        .title($scope.res('COMUM_ERRO'))
                        .content(err.data.message)
                            .ok($scope.res('COMUM_OK')));
            });*/

        };

        /**
         * @method abrirDetalhes
         */
        $scope.abrirDetalhes = function (incidente) {
            MsiService.incidenteDetalhamento.incidente = incidente;
            MsiService.state.isVisible = true;
        };

        $scope.timestamp2string = timestamp2string;

        /**
         * @method timestamp2string
         * @param {*} timestamp 
         */
        function timestamp2string(timestamp) {
            if (timestamp === null) {
                return;
            }

            var date = new Date(timestamp);
            var mom = moment(date);
            var formattedDate = mom.format('DD/MM/YYYY - HH:mm');
            return formattedDate;
        }

        loadPontosMoveis();

        /**
         * @method gotoIncidente
         * @param {*} x 
         */
        function gotoIncidente(x) {

            $scope.incidenteAtivo = x;
            $anchorScroll();
        }

        /**
         * @method _timeSet
         */
        function _timeSet() {
            return {
                start: moment().subtract(1, 'day').startOf('day').format(),
                end: moment().endOf('day').format()
            }
        };

        /**
         * @method initFilter
         */
        function initFilter() {
            MsiFilter.getInstance('filtro-msi').dataRange = _timeSet();
        }

        $scope.$apirastreamento = {
            gotoIncidente: gotoIncidente,
            refreshPontosMoveis: loadPontosMoveis,
            setQuery: setQuery,
            initFilter: initFilter
        };

        MainState.registerDirective('rastreamento', $scope.$apirastreamento);
    }


    function s4cRastreamento() {
        return {
            restrict: 'EA',
            templateUrl: 'app/directives/rastreamento/rastreamento.html',
            scope: {},
            controller: rastreamentoController
        };
    }

    angular.module('s4c.components.rastreamento', [])
        .directive('s4cRastreamento', s4cRastreamento);
})();