Source: directives/incidente-enter/incidente-enter.js

/**
 * @ngdoc directives
 * @name incidentesEnter
 * @module s4c.directives.incidentesentender.incidenteEnter
 *
 * @description Componente para inclusão de novos incidentes
 *
 *
 */
(function () {
    'use strict';

    incidenteEnterCtrl.$inject = [
        '$scope',
        'IncidentesService',
        'IncidenteEnterManager',
        'MainState',
        'Geocode',
        'MapaService',
        'localize',
        'Poi',
        'CamadasService',
        'Usuario',
        'GrupoUsuarios',
        'BlackList',
        '$mdDialog',
        'PlanejamentoManager',
        'BaseConhecimentoManager',
        'Base',
        'PermissoesService'
    ];

    function incidenteEnterCtrl($scope, IncidentesService, IncidenteEnterManager,
        MainState, Geocode, MapaService, localize, Poi,
        CamadasService, Usuario, GrupoUsuarios, BlackList, $mdDialog, PlanejamentoManager, BaseConhecimentoManager, Base, PermissoesService) {

        $scope.GruposUsuarios = [];
        $scope.Usuarios = [];
        $scope.usuariosResponsaveis = [];

        /**
         * Carrega a lista de tipo de incidentes
         * 
         * @method getIncidenteTipos
         *
         *
         */   
        IncidentesService.getIncidenteTipos()
            .then(function (tipos) {
                $scope.incidenteTipos = tipos;
            });

        /**
         * Carrega a lista de gravidades de incidentes
         * 
         * @method getIncidenteGravidades
         *
         *
         */   
        IncidentesService.getIncidenteGravidades()
            .then(function (gravidades) {
                $scope.incidenteGravidades = gravidades;
            });

        /**
         * Carrega a lista de categorias de incidentes
         * 
         * @method getIncidenteCategorias
         *
         *
         */   
        IncidentesService.getIncidenteCategorias().then(function (categorias) {
            $scope.categorias = categorias;
        });

        /**
         * Verifica se a funcionalidade está na blacklist
         * 
         * @method isToShow
         *
         *
         */   
        $scope.isToShow = function (label) {
            return MainState.isToShow(label);
        }

        /**
         * Carrega a lista de usuários
         * 
         * @method obterShortUsers
         *
         *
         */ 
        Usuario.obterShortUsers()
            .then(function (usuarios) {
                $scope.usuariosResponsaveis = usuarios;
            });


     	/**
         * Carrega a blacklist
         * 
         * @method obter
         *
         *
         */ 
        BlackList.obter()
            .then(function (blacklist) {
                $scope.blackList = blacklist;
            })

        $scope.res = $scope.$root.res;
        $scope.now = moment();

        function updateNow() {
            $scope.now = moment();
        }

        $scope.selecao = {
            poiSelecionado: null
        };

        // O ponto no mapa
        var ponto;
        var defaultIncidente = {
            nome: '',
            descricao: '',
            endereco: '',
            inicio_enter: moment().format('DD/MM/YYYY HH:mm:ss'),
            extras: {
                informacoes: []
            },
            GruposUsuarios: []
        };

        var IncidenteIcon = L.Icon.Default.extend({
            options: {
                iconUrl: './bower_components/leaflet/dist/images/marker-icon.png',
                iconSize: [25, 41],
                shadowSize: [0, 0],     // size of the shadow
                iconAnchor: [12, 24],   // point of the icon which will correspond to marker's location
                shadowAnchor: [0, 0],   // the same for the shadow
                popupAnchor: [0, 0]
            }
        });

     	/**
         * Listener do campo endereço do formulário de Incidente
         * 
         * @method watch
         *
         *
         */ 
        $scope.$watch('incidente.endereco', function () {
            if (typeof $scope.incidente.endereco === 'object') {
                var pos = {
                    lat: $scope.incidente.endereco.geometry.location.lat(),
                    lng: $scope.incidente.endereco.geometry.location.lng()
                };
                _atualizarPosicaoMarker(pos);
                $scope.incidente.endereco = $scope.incidente.endereco.formatted_address;
            }
        });

     	/**
         * Atualiza a posição do marker
         * 
         * @method _atualizarPosicaoMarker
         * @param pos {Object} Coordenadas
         *
         */ 
        function _atualizarPosicaoMarker(pos) {
            var newPos = new L.LatLng(pos.lat, pos.lng);
            ponto.setLatLng(newPos);
            MapaService.setView(newPos, 17);
        }

     	/**
         * Converte as coordenadas para endereço
         * 
         * @method _geocodeLatlng
         *
         * @param latlng {Object} Coordenadas
         *
         */ 
        function _geocodeLatlng(latlng) {
            Geocode.obterEndereco({
                latitude: latlng.lat,
                longitude: latlng.lng
            }).then(function (data) {
                var rua = data.rua ? data.rua : '';
                var bairro = data.barrio ? data.barrio : '';
                var numero = data.numero ? data.numero : '';
                $scope.incidente.endereco = '' + rua + numero;
                $scope.incidente.bairro = '' + bairro; // Comes like this from the API
            });
        }

     	/**
         * Remove o ponto do mapa
         * 
         * @method _removerPonto
         *
         * @param ponto {Object} Coordenadas
         *
         */ 
        function _removerPonto(ponto) {
            if (!ponto) {
                return;
            }
            MapaService.removerCamada(ponto);
        }

     	/**
         * Limpa os dados do formulário
         * 
         * @method _limparDados
         *
         * @param ponto {Object} Coordenadas
         *
         */ 
        function _limparDados() {
            $scope.formIncidente.$setPristine();
            $scope.formIncidente.$setUntouched();
            $scope.selecao = {
                poiSelecionado: null,
                queryPois: ''
            };

            $scope.incidente = angular.copy(defaultIncidente);
            $scope.inicio_enter = moment().format('DD/MM/YYYY HH:mm:ss');
            $scope.incidente.inicio_enter = moment().format('DD/MM/YYYY HH:mm:ss');

            $scope.Usuarios = [];
            $scope.GruposUsuarios = [];
        }
        $scope.closeModal = function () {
            $mdDialog.hide();
        }

        $scope.chaveEstrangeiraPoi;
        
     	/**
         * Cria o marker pra ser colocado no mapa
         * 
         * @method abrirAlfinete
         *
         * @param marker {Object} Marker
         * @param chaveEstrangeiraPoi {String} 
         *
         */         
        function abrirAlfinete(marker, chaveEstrangeiraPoi) {
            _limparDados();
            _geocodeLatlng(marker.getLatLng());

            ponto = marker;
            marker.options.draggable = true;
            $scope.chaveEstrangeiraPoi = chaveEstrangeiraPoi;

            var incidenteIcon = new IncidenteIcon();
            marker.setIcon(incidenteIcon);
        }

     	/**
         * Abre o modulo de Base de Conhecimento ou Planejamento
         * 
         * @method abrir
         *
         * @param latlng {Object} Coordenadas
         * @param evt {String} Evento
         *
         */   
        function abrir(latlng, evt) {

            if (BaseConhecimentoManager.ativo || PlanejamentoManager.ativo) {

                var msgModuloAtivo = localize.getLocalizedString('COMUM_MENSAGEMMODULOATIVO');

                $mdDialog.show({
                    targetEvent: evt,
                    scope: $scope.$new(),
                    template: '<md-dialog>' +
                        '  <md-content>' + msgModuloAtivo + '</md-content>' +
                        '  <div class="md-actions">' +
                        '    <md-button ng-click="OpenAndClose();closeModal();">' + localize.getLocalizedString('COMUM_SIM') + '</md-button>' +
                        '    <md-button ng-click="closeIncidenteModal();closeModal()">' + localize.getLocalizedString('COMUM_NAO') + '</md-button>' +
                        '  </div>' +
                        '</md-dialog>'
                });
                _limparDados();
                _geocodeLatlng(latlng);
                _adicionarMarker(latlng);
            } else {
                _limparDados();
                _geocodeLatlng(latlng);
                _adicionarMarker(latlng);
            }
        }

  		/**
         * Fecha os modulos de Base de Conhecimento ou Planejamento
         * 
         * @method abrir
         *
         * @param latlng {Object} Coordenadas
         * @param evt {String} Evento
         *
         */   
        function OpenAndClose(latlng, isMarker) {

            if (BaseConhecimentoManager.ativo || PlanejamentoManager.ativo) {
                BaseConhecimentoManager.fechar();
                PlanejamentoManager.fechar();
            }
        }
        function closeIncidenteModal() {
            IncidenteEnterManager.fechar();
        }
        
        /**
         * Adiciona um marker no mapa
         * 
         * @method _adicionarMarker
         *
         * @param latlng {Object} Coordenadas
         *
         */  
        function _adicionarMarker(latLng) {
            var incidenteIcon = new IncidenteIcon();
            // Remover ponto existente, se houver
            _removerPonto(ponto);
            ponto = L.marker(latLng, {
                draggable: true,
                icon: incidenteIcon
            });

            MapaService.addMarker(ponto);

            ponto.on('dragend', function (event) {
                var marker = event.target;
                var position = marker.getLatLng();

                _geocodeLatlng(position);
            });
        }

        /**
         * Gera uma String aleatória
         * 
         * @method _randomString
         *
         * @param len {Object} Tamanho
         * @param charSet {Object} Conteúdo
         *
         */  
        function _randomString(len, charSet) {
            charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            var randomString = '';
            for (var i = 0; i < len; i++) {
                var randomPoz = Math.floor(Math.random() * charSet.length);
                randomString += charSet.substring(randomPoz, randomPoz + 1);
            }
            return randomString;
        }

        function fechar() {
            IncidenteEnterManager.fechar();
        }

        /**
         * Chamado quando o formulario é fechado
         * 
         * @method onClose
         *
         */  
        function onClose() {
            var MapaManager = MainState.getManager('MapaManager');
            _removerPonto(ponto);
            clearInterval(MapaManager.poiAtivo);
        }

        /**
         * Salva o formulário de Incidente
         * 
         * @method salvar
         *
         * @param incidente {Object} Incidente
         *
         */  
        function salvar(incidente) {

            if ($scope.enableButton == false) {
                return;
            }

            $scope.tentouEnviar = true;
            $scope.enableButton = false;

            if ($scope.formIncidente.$valid &&
                $scope.incidente.ResponsavelId != null) {
                var latlng = ponto.getLatLng();

                var filtroPermissao = {};
                filtroPermissao.objeto = "CRIAR_INCIDENTE";
                filtroPermissao.latitude = latlng.lat;
                filtroPermissao.longitude = latlng.lng;

                PermissoesService.verificarPermissaoAreaAtuacao(filtroPermissao)
                    .then(function (result) {
                        if (result) {
                            confirmarSalvar(incidente, latlng);
                        }
                        else {
                            $scope.enableButton = true;
                            $mdDialog
                                .show($mdDialog.alert()
                                    .title($scope.res('COMUM_AVISO'))
                                    .content($scope.res('PERMISSAO_AREAATUACAO_VERIFICACAO'))
                                    .ok($scope.res('COMUM_OK')));
                            return;
                        }
                    });
            } else {
                $scope.enableButton = true;
            }
        }

        $scope.enableButton = true;
        /**
         * Validação do formulário
         * 
         * @method confirmarSalvar
         *
         * @param incidente {Object} Incidente
         * @param latlng {Object} Coordenadas
         *
         */          
        function confirmarSalvar(incidente, latlng) {
            var UserInfo = MainState.getManager('UserInfo');

            //incidente.CategoriaId       = 63;
            incidente.chave_estrangeira = _randomString(8);
            incidente.latitude = latlng.lat;
            incidente.longitude = latlng.lng;
            incidente.status = 'ABERTO';
            incidente.inicio = moment(incidente.inicio_enter, 'DD/MM/YYYY HH:mm:ss').toDate().getTime();
            incidente.GruposUsuarios = $scope.GruposUsuarios;
            incidente.Usuarios = $scope.Usuarios;
            incidente.chaveEstrangeiraPoi = $scope.chaveEstrangeiraPoi;

            if (!incidente.GravidadeIncidenteId) {
                $scope.enableButton = true;
                return;
            }

            if (!incidente.CategoriaId) {
                $scope.enableButton = true;
                return;
            }

            if (!incidente.TipoIncidenteId) {
                $scope.enableButton = true;
                return;
            }


            incidente.extras = angular.extend(incidente.extras, {
                'observacoes': [],
                'origem': 'S4C'
            });

            incidente.extras.informacoes = incidente.extras.informacoes.concat([{
                'label': 'Prioridade',
                'valor': 3
            }, {
                'label': 'Autor',
                'valor': UserInfo.nome + ' (' + UserInfo.Perfils[0].nome + ')'
            }]);

            if ($scope.selecao.responsavel) {
                incidente.extras.informacoes.push({
                    'label': 'Responsável',
                    'valor': $scope.selecao.responsavel.nome
                })
            }

            IncidentesService.saveIncidente(incidente)
                .then(_onIncidenteSuccess)
                .then(fechar).then(function () {
                });
        }

        /**
         * Chamado caso o Incidente seja salvo sem problemas
         * 
         * @method _onIncidenteSuccess
         *
         * @param incidente {Object} Incidente
         *
         */    
        function _onIncidenteSuccess(incidente) {

            $scope.tentouEnviar = false;
            $scope.enableButton = true;

            $mdDialog.show(
                $mdDialog.alert()
                    .title(localize.getLocalizedString('COMUM_SUCESSO'))
                    .content(localize.getLocalizedString('INCIDENTE_MENSAGEMSUCESSO'))
                    .ariaLabel(localize.getLocalizedString('INCIDENTE_MENSAGEMSUCESSO'))
                    .ok(localize.getLocalizedString('COMUM_OK'))
            );
        }

        /**
         * Define que o campo foi clicado
         * 
         * @method touchTextArea
         *
         *
         */  
        function touchTextArea() {
            $scope.formIncidente.descricao = {
                $touched: true
            }
        }

        /**
         * Relaciona um Poi ao Incidente
         * 
         * @method relacionarPoi
         *
         *
         */    
        function relacionarPoi() {
            if ($scope.selecao.poiSelecionado) {
                $scope.incidente.PoiChaveEstrangeira = $scope.selecao.poiSelecionado.chave_estrangeira;
                var pos = {
                    lat: $scope.selecao.poiSelecionado.poiGeometrico.coordinates[1],
                    lng: $scope.selecao.poiSelecionado.poiGeometrico.coordinates[0]
                }
                _geocodeLatlng(pos);
                _atualizarPosicaoMarker(pos);
                MapaService.removerCamada(ponto);
                CamadasService.ativarMenuPoi($scope.selecao.poiSelecionado);
                $scope.selecao.queryPois = $scope.selecao.poiSelecionado.nome + ' '; // adicionando espaço para não exibir lista de pois novamente
            } else {
                $scope.incidente.PoiChaveEstrangeira = null;
                MapaService.obterPontoCentral()
                    .then(function (center) {
                        _adicionarMarker(center);
                    });
            }
        }

        /**
         * Obtem os dados do responsável pelo Incidente
         * 
         * @method selecionarResponsavel
         *
         *
         */  
        function selecionarResponsavel() {
            if ($scope.selecao.responsavel) {
                $scope.selecao.queryUsuarios = $scope.selecao.responsavel.nome + ' ';
                $scope.incidente.ResponsavelId = $scope.selecao.responsavel.id;
            } else {
                $scope.incidente.ResponsavelId = null;
            }
        }

        angular.extend($scope, {
            incidente: {
                inicio_enter: moment().format('DD/MM/YYYY HH:mm:ss')
            },
            incidenteTipos: [],
            salvar: salvar,
            relacionarPoi: relacionarPoi,
            touchTextArea: touchTextArea,
            OpenAndClose: OpenAndClose,
            closeIncidenteModal: closeIncidenteModal,
            selecionarResponsavel: selecionarResponsavel


        });

        MainState.registerDirective('incidenteEnter', {
            abrir: abrir,
            abrirAlfinete: abrirAlfinete,
            onClose: onClose,
            updateNow: updateNow
        });
    }

    function s4cIncidenteEnter() {
        return {
            restrict: 'E',
            scope: {},
            templateUrl: 'app/directives/incidente-enter/incidente-enter.html',
            controller: incidenteEnterCtrl
        };
    }


    //angular.module('s4c_components_incidentes', []).directive('s4cIncidenteEnter', s4cIncidenteEnter);
    angular.module('s4c.components.incidentes', []).directive('s4cIncidenteEnter', s4cIncidenteEnter);
}());