Source: directives/msi-filter/msiFilter.service.js

/**
 * @ngdoc directives
 * @name MsiFilterService
 * @module s4c.directives.msi-filter.MsiFilterService
 *
 * @description
 * `MsiFilterService` Componente para acesso a api do backend e/ou comunicação entre controllers
 * 
 * 
 */
(function () {
    angular.module('s4c.components.msi')
        .factory('MsiFilter', MsiFilter);

    function MsiFilter() {

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

        /**
         * @method getInstance
         * @param {*} id 
         */
        function getInstance(id) {
            if (!service._filtros[id]) {
                service._filtros[id] = new Service()
            }

            return service._filtros[id];
        }

        /**
         * @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,
                categorias: [],
                prioridades: [],
                criticidades: [],
                events: {
                    'filterChanged': [],
                    'filterChangedMenu': [],
                    'moduloMsiFechado': []
                },
                origem: '',
                lastTableQueryFilter: null,
                lastMapQueryFilter: null
            });

            /**
             * @method on
             * @param {*} eventName 
             * @param {*} callback 
             */
            function on(eventName, callback) {
                if (self.events[eventName].length > 0) {
                    self.events[eventName][0] = callback;
                }
                else {
                    self.events[eventName].push(callback);
                }
            }

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

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

            /**
             * @method _belongsTimeWindow
             * @param {*} incidente 
             * @param {*} timeWindow 
             * @param {*} statuses 
             */
            function _belongsTimeWindow(incidente, timeWindow, statuses) {
                var incidenteInicio = moment(incidente.inicio).startOf('day');

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

                /* Hora final */
                if (!(incidenteInicio.isSame(moment(timeWindow.end).endOf('day')) ||
                    incidenteInicio.isBefore(moment(timeWindow.end).endOf('day')))
                ) {
                    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).endOf('day'))) {
                        return false;
                    }
                }

                return true;
            }

            /**
             * @method _setTimeWindow
             * @param {*} timeWindow 
             * @param {*} statuses 
             */
            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').startOf('day').format() :
                    moment(newTimeWindow.start).startOf('day').format();

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

                return newTimeWindow;
            }

            /**
             * @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 filtrarIncidente
             * @param {*} incidente 
             */
            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 contemPrioridade = !prioridade || _.includes(prioridades, prioridade.valor);
                    var contemCategoria = _.includes(categorias, incidente.CategoriaIncidenteId);
                    var contemGrupoUsuarios = !gruposUsuarios.length || _.intersection(gruposUsuarios, _.map(incidente.GruposUsuarios, 'id')).length;
                    var contemStatuses = (statusesNames.indexOf(incidente.status) > -1);
                    var contemGravidades = !gravidades.length || (gravidades.indexOf(incidente.GravidadeIncidenteId) > -1);
                    var contemTipoIncidentes = !tipoIncidentes.length || (tipoIncidentes.indexOf(incidente.TipoIncidente.id) > -1);

                    var belongsTimeWindow = _belongsTimeWindow(incidente, timeWindow, statuses);

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

                return false;
            }

            /**
             * @method ativarCategoria
             * @param {*} categoriaId 
             * @param {*} origem 
             */
            function ativarCategoria(categoriaId, origem) {
                var categoria = _.find(self.categorias, { id: categoriaId });

                categoria.ativo = true;
                self.origem = origem;
            }

            /**
             * @method desativarCategoria
             * @param {*} categoriaId 
             * @param {*} origem 
             */
            function desativarCategoria(categoriaId, origem) {
                var categoria = _.find(self.categorias, { id: categoriaId });

                if (categoria)
                    categoria.ativo = false;

                self.origem = origem;
            }

        }

        return service;
    }
}());