Source: directives/incidenteFilter/incidenteFilter.service.js

/**
 * @ngdoc directives
 * @name incidentesFilterService
 * @module s4c.directives.IncidenteFilter.IncidenteFilterService
 *
 * @description Componente de acesso a api do Backend
 *
 *
 */
(function () {
    angular.module('s4c.components.incidentes')
        .factory('IncidenteFilter', ['Base', '$rootScope', 'localize', IncidenteFilter]);

    function IncidenteFilter(Base, $rootScope, localize) {
        //$scope.res = $rootScope.res;

        var service = {
            _filtros: {},
            getInstance: getInstance,
            limparFiltros: limparFiltros
        };

        /**
         * Retorna uma instancia do componente
         * 
         * @method getInstance
         * @param id {Object}
         * @param callback {Object}
         *
         */  
        function getInstance(id) {
            if (!service._filtros[id]) {
                service._filtros[id] = new Service()
            }

            return service._filtros[id];
        }

        /**
         * Desmarca todas as categorias selecionadas no filtro
         * 
         * @method limparFiltros
         *
         */ 
        function limparFiltros() {
            _.each(service._filtros, function (filtro) {
                _.each(filtro.categorias, function (categoria) {
                    categoria.ativo = false;
                });
            });
        }

        function Service() {
            var self = this;

            angular.extend(self, {
                on: on,
                trigger: trigger,
                filtrarIncidente: filtrarIncidente,
                ativarCategoria: ativarCategoria,
                desativarCategoria: desativarCategoria,
                toggleStatus: toggleStatus,
                categorias: [],
                prioridades: [],
                criticidades: [],
                statuses: [
                    { id: 1, nome: 'ABERTO', imgUrl: '/assets/images/IncidenteLegenda/s4c_ic_incident_open_fill_subtitle.svg', ativo: true },
                    { id: 2, nome: 'FECHADO', imgUrl: '/assets/images/IncidenteLegenda/s4c_ic_incident_closed_fill_subtitle.svg', ativo: false }
                ],
                events: {
                    'filterChanged': [],
                    'countByStatus': [],
                    'filterChangedMenu': []
                },
                origem: ''
            });

	        /**
	         * Listener de eventos
	         * 
	         * @method on
	         * @param eventName {Object}
	         * @param callback {Object}
	         *
	         */  
            function on(eventName, callback) {
                self.events[eventName].push(callback);
            }

	        /**
	         * Dispara um evento
	         * 
	         * @method trigger
	         * @param eventName {Object}
	         * @param args {Object}
	         *
	         */  
            function trigger(eventName, args) {
                _.each(self.events[eventName], function (callback) {
                    callback(args);
                });
            }

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

	        /**
	         * Valida se o Incidente filtrado está dentro do período de datas selecionado
	         * 
	         * @method _belongsTimeWindow
	         * @param incidente {Object}
	         * @param timeWindow {Object}
	         * @param statuses {Object}
	         *
	         */  
            function _belongsTimeWindow(incidente, timeWindow, statuses) {
                var incidenteInicio = moment(incidente.inicio);

                /* Hora inicial */
                if (!(incidenteInicio.isSame(moment(timeWindow.start)) ||
                    incidenteInicio.isAfter(moment(timeWindow.start)))
                ) {
                    return false;
                }

                /* Hora final */
                if (!(incidenteInicio.isSame(moment(timeWindow.end)) ||
                    incidenteInicio.isBefore(moment(timeWindow.end)))
                ) {
                    return false;
                }

                // Se estiver aberto mas somente fechado e aberto há mais de 24h estiver selecionado
                if (incidente.status === 'ABERTO' && statuses.indexOf(1) === -1 && statuses.length) {
                    if (!incidenteInicio.isBefore(moment(timeWindow.start))) {
                        return false;
                    }
                }

                return true;
            }

            // Same function on incidente.js -> refactory to one please.
	        /**
	         * Inicializa as datas de inicio e fim do filtro de Incidente
	         * 
	         * @method _setTimeWindow
	         * @param timeWindow {Object}
	         * @param statuses {Object}
	         *
	         */              
            function _setTimeWindow(timeWindow, statuses) {
                var newTimeWindow = {
                    start: timeWindow.start,
                    end: timeWindow.end
                };

                newTimeWindow.start = (!statuses.length || statuses.indexOf(3) > -1) ?
                    moment(newTimeWindow.start).subtract(1, 'day').format() :
                    moment(newTimeWindow.start).startOf('day').format();

                newTimeWindow.end = ((statuses.length === 1) && statuses.indexOf(3) > -1) ?
                    moment(newTimeWindow.start).format() :
                    moment(newTimeWindow.end).format();

                return newTimeWindow;
            }

            // Same function on incidente.js -> refactory to one please.
	        /**
	         * Cria uma lista de Status (Aberto e Fechado)
	         * 
	         * @method _setStatuses
	         * @param statuses {Object}
	         *
	         */              
            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"];
                }
            }

	        /**
	         * Executa o filtro de Incidentes
	         * 
	         * @method filtrarIncidente
	         * @param incidente {Object}
	         *
	         */   
            function filtrarIncidente(incidente) {
                if (!incidente.extras) {
                    return false;
                }

                if (incidente.extras.informacoes) {

                    var prioridade = _.find(incidente.extras.informacoes, function (informacao) {
                        return informacao.label === 'Prioridade';
                    });

                    var statuses = _filtrarAtivos(self.statuses, 'id'); //Statuses: 1. Aberto 2. Fechado 3. Aberto 24h
                    var prioridades = _filtrarAtivos(self.prioridades, 'texto');
                    var categorias = _filtrarAtivos(self.categorias, 'id');
                    var gruposUsuarios = _filtrarAtivos(self.GruposUsuarios, 'id');
                    var gravidades = _filtrarAtivos(self.gravidades, 'id');
                    var tipoIncidentes = _filtrarAtivos(self.tipoIncidentes, 'id');
                    var timeWindow = _setTimeWindow(self.dataRange, statuses);

                    var statusesNames = _setStatuses(statuses);

                    var contemCategoria = _.includes(categorias, incidente.CategoriaIncidenteId);
                    var contemPrioridade = !prioridade || _.includes(prioridades, prioridade.valor);
                    var contemGrupoUsuarios = !gruposUsuarios.length || _.intersection(gruposUsuarios, _.map(incidente.GruposUsuarios, 'id')).length;
                    var contemGravidades = !gravidades.length || (gravidades.indexOf(incidente.GravidadeIncidenteId) > -1);
                    var belongsTimeWindow = _belongsTimeWindow(incidente, timeWindow, statuses);
                    var contemTipoIncidentes = !tipoIncidentes.length || (tipoIncidentes.indexOf(incidente.TipoIncidente.id) > -1);
                    var contemStatuses = (statusesNames.indexOf(incidente.status) > -1);

                    return contemCategoria &&
                        contemPrioridade &&
                        contemGrupoUsuarios &&
                        contemGravidades &&
                        belongsTimeWindow &&
                        contemTipoIncidentes &&
                        contemStatuses;
                }

                return false;
            }

	        /**
	         * Busca por uma categoria na lista de categorias
	         * 
	         * @method _handleCategoria
	         * @param categoriaId {Integer} Identificador da categoria
	         * @param categorias {Array} Lista de categorias
	         * @param origem {String}
	         *
	         */    
            function _handleCategoria(categoriaId, categorias, origem) {
                var categoria = _.find(categorias, { id: categoriaId });
                if (categoria) {
                    categoria.ativo = true;
                }
                self.origem = origem;
            }

            var count = 0;
	        /**
	         * Ativa a categoria do Incidente
	         * 
	         * @method ativarCategoria
	         * @param categoriaId {Integer} Identificador da categoria
	         * @param origem {String}
	         *
	         */             
            function ativarCategoria(categoriaId, origem) {
                if (!self.categorias.length && count == 0) {

                    count++;
                    Base.obter('incidentes/categorias/').then(function (categorias) {

                        self.categorias = categorias;
                        _handleCategoria(categoriaId, categorias, origem);
                    });
                } else {
                    _handleCategoria(categoriaId, self.categorias, origem);
                }
            }

	        /**
	         * Desativa a categoria do Incidente
	         * 
	         * @method desativarCategoria
	         * @param categoriaId {Integer} Identificador da categoria
	         * @param origem {String}
	         *
	         */  
            function desativarCategoria(categoriaId, origem) {
                var categoria = _.find(self.categorias, { id: categoriaId });

                if (categoria)
                    categoria.ativo = false;

                self.origem = origem;
            }

	        /**
	         * Busca o status
	         * 
	         * @method toggleStatus
	         * @param nome {String} 
	         * @param valor {String}
	         *
	         */  
            function toggleStatus(nome, valor) {
                var status = _.find(self.statuses, { nome: nome });

                status.ativo = valor;
            }
        }

        return service;
    }
}());