public void InsertOrUpdate(EventoStagging operationEntry)
 {
     if (operationEntry.eventoStaggingId == default(int))
     {
         context.EventosStagging.Add(operationEntry);
     }
     else
     {
         context.Entry(operationEntry).State = EntityState.Modified;
     }
 }
 public bool Update(EventoStagging operationEntry)
 {
     try
     {
         context.Entry(operationEntry).State = EntityState.Modified;
         return true;
     }
     catch (Exception ex)
     {
         return false;
     }
 }
        protected void verificaOutrasOperacoes(EventoStagging eventoValidado)
        {


        }
        public static void processaFicheiro(Ficheiro ficheiro){

            ValorSistemaRepository valoresSistemaRepository = new ValorSistemaRepository();

            //List<ValorSistema> valSistema = valoresSistemaRepository.All.Where(v => v.tipologia == "ESTADO_EVENTO_STAGGING" || v.tipologia == "OPERACAO_EVENTO").ToList();

            //List<ValorSistema> estadosEvento = valSistema.Where(v => v.tipologia == "ESTADO_EVENTO_STAGGING").ToList();
            //List<ValorSistema> operacoesEvento = valSistema.Where(v => v.tipologia == "OPERACAO_EVENTO").ToList();

            List<ValorSistema> estadosEvento = valoresSistemaRepository.GetPorTipologia("ESTADO_EVENTO_STAGGING");
            List<ValorSistema> operacoesEvento = valoresSistemaRepository.GetPorTipologia("OPERACAO_EVENTO");
            List<ValorSistema> tiposErro = valoresSistemaRepository.GetPorTipologia("TIPO_ERRO");
            List<ValorSistema> estadosFicheiro = valoresSistemaRepository.GetPorTipologia("ESTADO_FICHEIRO");

            ReporteOcorrenciasMatricula reporte;

            XmlSerializer serializer = new XmlSerializer(typeof(ReporteOcorrenciasMatricula));
            using (FileStream fileStream = new FileStream(ficheiro.localizacao, FileMode.Open))
            {
                reporte = (ReporteOcorrenciasMatricula)serializer.Deserialize(fileStream);
            }

            if (reporte.Cabecalho.CodigoEstatistico != ficheiro.entidade.codigoEntidade)
            {
                ErroFicheiro erroFicheiro = new ErroFicheiro(){ dataValidacao = DateTime.Now, 
                                                                tipologiaId = tiposErro.Single(e => e.valor == "GENERICO").valorSistemaId,
                                                                descricao = "Ficheiro reportado pela entidade com código '" + ficheiro.entidade.codigoEntidade + "' e com registos relativos à entidade '" + reporte.Cabecalho.CodigoEstatistico + "'.",
                                                                ficheiroId = ficheiro.ficheiroId };

                ErroFicheiroException ex = new ErroFicheiroException();
                ex.errosFicheiro.Add(erroFicheiro);

                throw ex;
            }

            ReporteOcorrenciasFNMPAS reporteOcorrenciasFNMPAS = new ReporteOcorrenciasFNMPAS(reporte);
            reporteOcorrenciasFNMPAS.ordenaOcorrencias();
           

            for (int i = 0; i < reporteOcorrenciasFNMPAS.OcorrenciaOrdenada.Count(); i++)
            {
                ReporteOcorrenciasMatriculaOcorrenciaOrdenada ocorrencia = reporteOcorrenciasFNMPAS.OcorrenciaOrdenada[i];

                //evento Duplicado e esmagado com os novos dados. (C M - stagging/producao) (A - producao/stagging) 
                //Não foi ainda inserido na Base de dados nem houve delete logico do anterior. 
                //Fazer deletes logicos, e inserções após verificações.
                //Anulações podem necessitar logica adicional caso a validação falhe. (duplicar registo em stagging)
                EventoStagging evento = new EventoStagging();
                
                int codigoOperacaoId = 0;
                switch (ocorrencia.CodigoOperacao)
                {
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.C: codigoOperacaoId = operacoesEvento.Where(o=> o.valor =="C").Single().valorSistemaId; break;
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.M: codigoOperacaoId = operacoesEvento.Where(o=> o.valor =="M").Single().valorSistemaId; break;
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.A: codigoOperacaoId = operacoesEvento.Where(o=> o.valor =="A").Single().valorSistemaId; break;
                    default: codigoOperacaoId = operacoesEvento.Where(o => o.valor == "C").Single().valorSistemaId; break;
                }
                evento.esmagaDados(ocorrencia, ficheiro, codigoOperacaoId);

                evento.estadoEventoId = estadosEvento.Where(e => e.valor == "PENDENTE").Single().valorSistemaId;

                ficheiro.eventosStagging.Add(evento);
            }

            //EventoStaggingRepository eventosStaggingRepository = new EventoStaggingRepository();
            //eventosStaggingRepository.InsertOrUpdate(evento);
            //eventosStaggingRepository.Save();
        }
        public ResultResponse<EnvioOcorrenciasResult> Post([FromBody]ReporteOcorrenciasMatricula ocorrencias)
        {
            ResultResponse<EnvioOcorrenciasResult> resposta = new ResultResponse<EnvioOcorrenciasResult>();

            //List<ValorSistema> paramSistema = valoresSistemaRepository.All.Where(v => v.tipologia == "ESTADO_EVENTO_STAGGING"
            //                                                                    || v.tipologia == "OPERACAO_EVENTO"
            //                                                                    || v.tipologia == "PARAM_PASTA_FICHEIROS").ToList();
            //List<ValorSistema> estadosEvento = paramSistema.Where(v => v.tipologia == "ESTADO_EVENTO_STAGGING").ToList();
            //List<ValorSistema> operacoesEvento = paramSistema.Where(v => v.tipologia == "OPERACAO_EVENTO").ToList();
            //ValorSistema pastaUpload = paramSistema.Where(v => v.tipologia == "PARAM_PASTA_FICHEIROS").Single();

            List<ValorSistema> estadosEvento = valoresSistemaRepository.GetPorTipologia("ESTADO_EVENTO_STAGGING");
            List<ValorSistema> operacoesEvento = valoresSistemaRepository.GetPorTipologia("OPERACAO_EVENTO");
            ValorSistema pastaUpload = valoresSistemaRepository.GetPorTipologia("PARAM_PASTA_FICHEIROS").Single();

            
            if (ocorrencias == null || ocorrencias.Ocorrencia == null)
            {
                resposta.Success = false;
                resposta.ErrorMessage = "Erro na recepção de ocorrências. Mensagem mal formada.";
            }

            UserProfile user = null;

            if (WebSecurity.IsAuthenticated)
            {
                user = usersRepository.GetUserByIDIncludeEntidade(WebSecurity.CurrentUserId);
            }
            else
            {
                string username = string.Empty;

                IEnumerable<string> headerVals;
                if (Request.Headers.TryGetValues("Authorization", out headerVals))
                {
                    string authHeader = headerVals.FirstOrDefault();
                    char[] delims = { ' ' };
                    string[] authHeaderTokens = authHeader.Split(new char[] { ' ' });
                    if (authHeaderTokens[0].Contains("Basic"))
                    {
                        string decodedStr = BasicAuthorizeAttribute.DecodeFrom64(authHeaderTokens[1]);
                        string[] unpw = decodedStr.Split(new char[] { ':' });
                        username = unpw[0];
                    }
                    else
                    {
                        if (authHeaderTokens.Length > 1)
                            username = BasicAuthorizeAttribute.DecodeFrom64(authHeaderTokens[1]);
                    }
                }

                user = usersRepository.GetUserByUsernameIncludeEntidade(username);
            }

            if (user == null)
            {
                resposta.Success = false;
                resposta.ErrorMessage += "Erro de autenticação.";
            }

            var root = System.Configuration.ConfigurationManager.AppSettings["FilesUploadDestination"];
            //string root = System.Web.HttpContext.Current.Server.MapPath(destination);
            var provider = new MultipartFormDataStreamProvider(root);

            if (resposta.Success == false)
            {
                return resposta;
            }

            DateTime dataRecepcao = DateTime.Now;

            ReporteOcorrenciasFNMPAS reporteOcorrenciasFNMPAS = new ReporteOcorrenciasFNMPAS(ocorrencias);
            reporteOcorrenciasFNMPAS.ordenaOcorrencias();

            int nrOcorrencias = 0;
            for (int i = 0; i < reporteOcorrenciasFNMPAS.OcorrenciaOrdenada.Count(); i++)
            {
                ReporteOcorrenciasMatriculaOcorrenciaOrdenada ocorrencia = reporteOcorrenciasFNMPAS.OcorrenciaOrdenada[i];

                //evento Duplicado e esmagado com os novos dados. (C M - stagging/producao) (A - producao/stagging) 
                //Não foi ainda inserido na Base de dados nem houve delete logico do anterior. 
                //Fazer deletes logicos, e inserções após verificações.
                //Anulações podem necessitar logica adicional caso a validação falhe. (duplicar registo em stagging)
                EventoStagging evento = new EventoStagging();

                int codigoOperacaoId = 0;
                switch (ocorrencia.CodigoOperacao)
                {
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.C: codigoOperacaoId = operacoesEvento.Where(o => o.valor == "C").Single().valorSistemaId; break;
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.M: codigoOperacaoId = operacoesEvento.Where(o => o.valor == "M").Single().valorSistemaId; break;
                    case ReporteOcorrenciasMatriculaOcorrenciaCodigoOperacao.A: codigoOperacaoId = operacoesEvento.Where(o => o.valor == "A").Single().valorSistemaId; break;
                    default: codigoOperacaoId = operacoesEvento.Where(o => o.valor == "C").Single().valorSistemaId; break;
                }

                Ficheiro ficheiroVirtual = new Ficheiro { dataAlteracao = dataRecepcao, dataUpload = dataRecepcao, entidadeId = user.entidadeId };

                evento.esmagaDados(ocorrencia, ficheiroVirtual, codigoOperacaoId);
                evento.utilizadorReporte = user.UserName;

                evento.estadoEventoId = estadosEvento.Where(e => e.valor == "PENDENTE").Single().valorSistemaId;

                eventosStaggingRepository.InsertOrUpdate(evento);
                nrOcorrencias++;
            }

                eventosStaggingRepository.Save();
                resposta.Success = true;
                resposta.Result = new EnvioOcorrenciasResult { dataRecepcao = dataRecepcao, nrOcorrencias = nrOcorrencias, seguradora = user.entidade.nome };
            
            return resposta;
        }
 public EventoStagging Insert(EventoStagging operationEntry)
 {
     operationEntry.eventoStaggingId = default(int);
     context.EventosStagging.Add(operationEntry);
     return operationEntry;
 }
        public static bool validarEvento(EventoStagging eventoStagging, Mutex mutex = null)
        {
            if (!ValidacaoEventos.validarCampos(eventoStagging, mutex))
            {
                return false;
            }

            if (!ValidacaoEventos.validarNegocio(eventoStagging, mutex))
            {
                return false;
            }

            //throw new ErroEventoStaggingException();
            //TODO
            return true;
        }
        public static bool validarNegocio(EventoStagging eventoStagging, Mutex mutex = null)
        {
            ApoliceRepository apolicesRepository = new ApoliceRepository();
            ValorSistemaRepository valoresSistemaRepository = new ValorSistemaRepository();

            List<ValorSistema> tiposErro = valoresSistemaRepository.GetPorTipologia("TIPO_ERRO", mutex);
            List<ValorSistema> tiposAviso = valoresSistemaRepository.GetPorTipologia("TIPO_AVISO", mutex);

            int tipoErroGenerico = tiposErro.Where(e => e.valor == "GENERICO").Single().valorSistemaId;
            int tipoAvisoGenerico = tiposAviso.Where(e => e.valor == "GENERICO").Single().valorSistemaId;

            List<Apolice> listaApolices;

            DateTime dataInicio;
            DateTime dataFim;

            TimeSpan horaInicio;
            TimeSpan horaFim;

            DateTime.TryParseExact(eventoStagging.dataInicioCobertura, "yyyyMMdd", new CultureInfo("pt-PT"), DateTimeStyles.None, out dataInicio);
            DateTime.TryParseExact(eventoStagging.dataFimCobertura, "yyyyMMdd", new CultureInfo("pt-PT"), DateTimeStyles.None, out dataFim);
            TimeSpan.TryParseExact(eventoStagging.horaInicioCobertura, "hhmmss", new CultureInfo("pt-PT"), TimeSpanStyles.None, out horaInicio);
            TimeSpan.TryParseExact(eventoStagging.horaFimCobertura, "hhmmss", new CultureInfo("pt-PT"), TimeSpanStyles.None, out horaFim);

            dataInicio = dataInicio.Add(horaInicio);
            dataFim = dataFim.Add(horaFim);

            listaApolices = apolicesRepository.All.Include("veiculo").Where(a => a.dataInicio == dataInicio &&
                                 a.entidadeId == eventoStagging.entidadeId && a.veiculo.numeroMatricula == eventoStagging.matricula).ToList();

            //ERROS
            //Criação para uma chave de registo já existente. - check
            if (listaApolices != null && listaApolices.Count > 0 && eventoStagging.codigoOperacao == "C")
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                {
                    campo = "Chave",
                    descricao = "O registo de cobertura já existe. Não é possível efectuar nova criação.", 
                    tipologiaId = tipoErroGenerico , eventoStagging = eventoStagging });
            }

            //Data Fim (data + hora) menor ou igual que data de início. - check
            if(dataFim <= dataInicio){
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                {
                    campo = "DataFim",
                    descricao = "A data/hora de fim da cobertura tem de ser posterior à data/hora de início de cobertura.",
                    tipologiaId = tipoErroGenerico,
                    eventoStagging = eventoStagging
                });
            }

            //Datas de início inferiores a 01-01-1900. - check
            if (dataInicio < new DateTime(1900, 01, 01))
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                {
                    campo = "DataInício",
                    descricao = "A data de início da cobertura tem de ser posterior à data de 01-01-1900.",
                    tipologiaId = tipoErroGenerico,
                    eventoStagging = eventoStagging
                });
            }

            //Modificação e Anulação para uma chave de registo não existente - check
            if ((eventoStagging.codigoOperacao == "A" || eventoStagging.codigoOperacao == "M")
                && listaApolices.Count == 0)
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                {
                    campo = "Chave",
                    descricao = "O registo de cobertura não existe. Não é possível efectuar modificações ou anulações.",
                    tipologiaId = tipoErroGenerico,
                    eventoStagging = eventoStagging
                });
            }

            //Modificações com alteração de data/hora Fim. - check
            if (listaApolices.Count > 0)
            {
                if (eventoStagging.codigoOperacao == "M" &&
                    dataFim != listaApolices.First().dataFim)
                {
                    eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                    {
                        campo = "DataFim",
                        descricao = "Operações de modificação não podem alterar a data/hora de fim de cobertura.",
                        tipologiaId = tipoErroGenerico,
                        eventoStagging = eventoStagging
                    });
                }
            }

            //Anulação para uma data posterior à data fim planeada. - check
            if (listaApolices.Count > 0)
            {
                if (eventoStagging.codigoOperacao == "A" &&
                    dataFim > listaApolices.First().dataFimPlaneada)
                {
                    eventoStagging.errosEventoStagging.Add(new ErroEventoStagging
                    {
                        campo = "DataFim",
                        descricao = "Anulação não pode alterar a data/hora de fim de cobertura para data posterior à planeada na criação.",
                        tipologiaId = tipoErroGenerico,
                        eventoStagging = eventoStagging
                    });
                }
            }


            //AVISOS
            //Caso a matricula já se encontre associada a outra seguradora que se intercepte o periodo a reportar. - check
            //registos que originem mais que um seguro válido (inter ou intra seguradoras)
            if(eventoStagging.codigoOperacao == "C"){
                listaApolices = apolicesRepository.All.Include("veiculo").Where(a => a.veiculo.numeroMatricula == eventoStagging.matricula).ToList();
                List<Apolice> apolicesCruzadas = new List<Apolice>();

                foreach (Apolice ap in listaApolices)
                {
                    if ((dataInicio >= ap.dataInicio && dataInicio <= ap.dataFim) ||
                        (dataFim >= ap.dataInicio && dataFim <= ap.dataFim) ||
                        (dataInicio <= ap.dataInicio && dataFim >= ap.dataFim))
                    {
                        if (!(dataInicio == ap.dataInicio && eventoStagging.entidadeId == ap.entidadeId && eventoStagging.matricula == ap.veiculo.numeroMatricula))
                        {
                            apolicesCruzadas.Add(ap);
                        }
                    }
                }

                if (apolicesCruzadas.Count > 0)
                {
                    eventoStagging.avisosEventoStagging.Add(new Aviso
                    {
                        campo = "Matricula",
                        descricao = "O periodo de cobertura apresenta registos cruzados.",
                        tipologiaId = tipoAvisoGenerico,
                        eventoStagging = eventoStagging
                    });
                }
            }

            if (eventoStagging.errosEventoStagging.Count > 0)
            {
                return false;
            }

            return true;
        }
        public static bool validarCampos(EventoStagging eventoStagging, Mutex mutex = null)
        {
            ValorSistemaRepository valoresSistemaRepository = new ValorSistemaRepository();
            CategoriaRepository categoriasRepository = new CategoriaRepository();
            ConcelhoRepository concelhosRepository = new ConcelhoRepository();

            List<ValorSistema> tiposErro = valoresSistemaRepository.GetPorTipologia("TIPO_ERRO", mutex);
            List<ValorSistema> tiposAviso = valoresSistemaRepository.GetPorTipologia("TIPO_AVISO", mutex);

            int tipoErroGenerico = tiposErro.Where(e => e.valor == "GENERICO").Single().valorSistemaId;
            int tipoAvisoGenerico = tiposAviso.Where(e => e.valor == "GENERICO").Single().valorSistemaId;

            DateTime aux;
            int intAux;

            //ERROS
            //tem Operação válida
            if (eventoStagging.codigoOperacao == null)
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging { campo = "CodigoOperacao",
                    descricao = "Código de operação '" + eventoStagging.codigoOperacao + "' inválido.",
                                                                                tipologiaId = tipoErroGenerico,
                                                                                eventoStagging = eventoStagging
                });
            }
            //tem matrícula válida - check
            if (eventoStagging.matricula == null || !Regex.Match(eventoStagging.matricula, "[-\\/?#() A-Za-z0-9]+").Success)
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging { campo = "NumeroMatricula",
                    descricao = "Número de matrícula '" + eventoStagging.matricula + "' inválido.",
                                                                                tipologiaId = tipoErroGenerico,
                                                                                eventoStagging = eventoStagging
                });
            }
            //tem data inicio válida - check
           
            if (eventoStagging.dataInicioCobertura == null || eventoStagging.dataInicioCobertura == string.Empty || !DateTime.TryParseExact(eventoStagging.dataInicioCobertura, "yyyyMMdd", new CultureInfo("pt-PT"), DateTimeStyles.None, out aux))
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging { campo = "DataInicio",
                    descricao = "Data de início do período de cobertura '" + eventoStagging.dataInicioCobertura + "' inválida.",
                                                                                tipologiaId = tipoErroGenerico,
                                                                                eventoStagging = eventoStagging
                });
            }
            //tem data fim válida - check
            if (eventoStagging.dataFimCobertura == null || eventoStagging.dataFimCobertura == string.Empty || !DateTime.TryParseExact(eventoStagging.dataFimCobertura, "yyyyMMdd", new CultureInfo("pt-PT"), DateTimeStyles.None, out aux))
            {
                eventoStagging.errosEventoStagging.Add(new ErroEventoStagging { campo = "DataFim",
                    descricao = "Data de fim do período de cobertura '" + eventoStagging.dataInicioCobertura + "' inválida.",
                                                                                tipologiaId = tipoErroGenerico,
                                                                                eventoStagging = eventoStagging
                });
            }
            //sem numero de apolice e sem certificado provisório - check
            if (eventoStagging.nrApolice == null || eventoStagging.nrApolice == string.Empty)
            {
                if (eventoStagging.nrCertificadoProvisorio == null || eventoStagging.nrCertificadoProvisorio == string.Empty)
                {
                    eventoStagging.errosEventoStagging.Add(new ErroEventoStagging { campo = "NumeroApolice",
                        descricao = "Número de apólice ou Número de certificado provisório em falta.",
                                                                                    tipologiaId = tipoErroGenerico,
                                                                                    eventoStagging = eventoStagging
                    });
                }
            }

            //AVISOS
            //tem marca - check
            if (eventoStagging.marca == null || eventoStagging.marca == string.Empty)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "MarcaVeiculo",
                    descricao = "Marca de veiculo '"+eventoStagging.marca+"' inválida.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //tem modelo - check
            if (eventoStagging.modelo == null || eventoStagging.modelo == string.Empty)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "ModeloVeiculo",
                    descricao = "Modelo de veiculo '"+eventoStagging.modelo+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //tem ano construção válido - check
            if (eventoStagging.anoConstrucao == null || eventoStagging.anoConstrucao == string.Empty || !int.TryParse(eventoStagging.anoConstrucao, out intAux) /*|| intAux < 0 || intAux > (DateTime.Now.Year+2)*/)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "AnoConstrucaoVeiculo",
                    descricao = "Ano de construção do veiculo '"+eventoStagging.anoConstrucao+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //tem categoria válida - check
            if (eventoStagging.codigoCategoriaVeiculo == null || eventoStagging.codigoCategoriaVeiculo == string.Empty)
            {
                //TODO: verificar se a categoria existe. Forçar para categoria desconhecida caso não exista.
                eventoStagging.avisosEventoStagging.Add(new Aviso
                {
                    campo = "CódigoCategoriaVeiculo",
                    descricao = "Código de categoria do veiculo '" + eventoStagging.codigoCategoriaVeiculo + "' inválido.",
                    tipologiaId = tipoAvisoGenerico,
                    eventoStagging = eventoStagging
                });
            }
            else
            {
                List<Categoria> queryCategoria = categoriasRepository.All.Where(c => c.codigoCategoriaVeiculo == eventoStagging.codigoCategoriaVeiculo).ToList();
                if (queryCategoria.Count == 0)
                {
                    //TODO: verificar se a categoria existe. Forçar para categoria desconhecida caso não exista.
                    eventoStagging.avisosEventoStagging.Add(new Aviso
                    {
                        campo = "CódigoCategoriaVeiculo",
                        descricao = "Código de categoria do veiculo '" + eventoStagging.codigoCategoriaVeiculo + "' inválido.",
                        tipologiaId = tipoAvisoGenerico,
                        eventoStagging = eventoStagging
                    });
                }
            }
            //tem concelho de circulação habitual válido - check
            if (eventoStagging.codigoConcelhoCirculacao == null || eventoStagging.codigoConcelhoCirculacao == string.Empty)
            {
                //TODO: verificar se o concelho existe. Forçar para concelho desconhecido caso não exista.
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "ConcelhoCirculacao",
                    descricao = "Concelho de circulação '"+eventoStagging.codigoConcelhoCirculacao+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            else
            {
                List<Concelho> queryCategoria = concelhosRepository.All.Where(c => c.codigoConcelho == eventoStagging.codigoConcelhoCirculacao).ToList();
                if (queryCategoria.Count == 0)
                {
                    //TODO: verificar se a categoria existe. Forçar para categoria desconhecida caso não exista.
                    eventoStagging.avisosEventoStagging.Add(new Aviso
                    {
                        campo = "ConcelhoCirculacao",
                        descricao = "Concelho de circulação '" + eventoStagging.codigoConcelhoCirculacao + "' inválido.",
                        tipologiaId = tipoAvisoGenerico,
                        eventoStagging = eventoStagging
                    });
                }
            }
            //tem nome de tomador de seguro - check
            if (eventoStagging.nomeTomadorSeguro == null || eventoStagging.nomeTomadorSeguro == string.Empty)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "NomeTomador",
                    descricao = "Nome de tomador de seguro '"+eventoStagging.nomeTomadorSeguro+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //tem morada de tomador de seguro - check
            if (eventoStagging.moradaTomadorSeguro == null || eventoStagging.moradaTomadorSeguro == string.Empty)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "MoradaTomador",
                    descricao = "Morada do tomador de seguro '"+eventoStagging.moradaTomadorSeguro+"' inválida.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //TODO: talvez remover visto não estar na lista de validações
            //tem codigo postal válido do tomador de seguro
            if (eventoStagging.codigoPostalTomador == null || eventoStagging.codigoPostalTomador == string.Empty)
            {
                //TODO: verificar se o código postal existe.
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "CodigoPostalTomador",
                    descricao = "Código postal do tomador de seguro '" + eventoStagging.codigoPostalTomador + "' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //Tem NIF válido do tomador do seguro - check
            if (eventoStagging.nifTomadorSeguro == null || eventoStagging.nifTomadorSeguro == string.Empty || !ValidacaoEventos.NifValido(eventoStagging.nifTomadorSeguro))
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "NifTomador",
                    descricao = "Nif do tomador de seguro '"+eventoStagging.nifTomadorSeguro+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }
            //Tem número de identificação do tomador de seguro - check
            if (eventoStagging.nrIdentificacaoTomadorSeguro == null || eventoStagging.nrIdentificacaoTomadorSeguro == string.Empty)
            {
                eventoStagging.avisosEventoStagging.Add(new Aviso { campo = "NumeroIdentificacaoTomador",
                    descricao = "Número de identificação do tomador de seguro '"+eventoStagging.nrIdentificacaoTomadorSeguro+"' inválido.",
                                                                    tipologiaId = tipoAvisoGenerico,
                                                                    eventoStagging = eventoStagging
                });
            }

            if (eventoStagging.errosEventoStagging.Count > 0)
            {
                return false;
            }

            return true;
        }
        public static EventoStagging criarEventoStagging(EventoStagging eventoPendente, Mutex mutex = null)
        {
            ValorSistemaRepository valoresSistemaRepository = new ValorSistemaRepository();
            List<ValorSistema> tiposErro = valoresSistemaRepository.GetPorTipologia("TIPO_ERRO", mutex);

            EventoStagging novoEvento = null;

            if (eventoPendente.codigoOperacao == null)
            {
                throw new ErroEventoStaggingException { errosEventoStagging = new List<ErroEventoStagging> { new ErroEventoStagging { campo = "CodigoOperacao", descricao = "Código de Operação Inválido", tipologiaId = tiposErro.Where(e => e.valor == "GENERICO").Single().valorSistemaId } } };
            }

            try
            {              
                novoEvento = EventoStaggingFactory.duplicarEventoStagging(eventoPendente.matricula, (int)eventoPendente.entidadeId, eventoPendente.dataInicioCobertura, eventoPendente.horaInicioCobertura, eventoPendente.codigoOperacao, mutex);

                //Caso não exista registo em stagging duplica-se o Registo em Producao               
                //novoEvento = EventoStaggingFactory.duplicarEventoProducao(eventoPendente.matricula, (int)eventoPendente.entidadeId, eventoPendente.dataInicioCobertura, eventoPendente.horaInicioCobertura);
                
                //Caso este também não exista, trata-se de uma nova ocorrência.
                //Poderiamos concluir que se não é uma criação é um erro, mas validemos isto juntamente com as validações de negócio.
                if (novoEvento == null)
                {
                    novoEvento = new EventoStagging();

                    if (eventoPendente.ficheiroID != null)
                    {
                        novoEvento.dataReporte = eventoPendente.ficheiro.dataAlteracao;
                        novoEvento.dataUltimaAlteracaoErro = eventoPendente.ficheiro.dataAlteracao;
                    }
                }
            }
            catch (ErroEventoStaggingException erros)
            {
                novoEvento = new EventoStagging();
                if (eventoPendente.ficheiroID != null)
                {
                    novoEvento.dataReporte = eventoPendente.ficheiro.dataAlteracao;
                    novoEvento.dataUltimaAlteracaoErro = eventoPendente.ficheiro.dataAlteracao;
                }
                
                foreach (ErroEventoStagging erro in erros.errosEventoStagging)
                {
                    erro.eventoStagging = novoEvento;
                    novoEvento.errosEventoStagging.Add(erro);
                }
            }

            novoEvento.esmagaDados(eventoPendente);

            return novoEvento;
        }
        private void verificaOutrasOperacoes(EventoStagging eventoValidado)
        {
            EventoStaggingRepository eventosStaggingRepository = new EventoStaggingRepository();

            List<string> operacoesDebloquear = new List<string>();

            switch (eventoValidado.codigoOperacao)
            {
                case "C":
                    {
                        operacoesDebloquear.Add("M");
                        break;
                    }
                default: { return; }
            }

            List<EventoStagging> errosDesbloquear = eventosStaggingRepository.All.Where(e => e.entidadeId == eventoValidado.entidadeId && e.dataInicioCobertura == eventoValidado.dataInicioCobertura &&
                        e.horaInicioCobertura == eventoValidado.horaInicioCobertura && e.matricula == eventoValidado.matricula && e.estadoEvento.valor == "ERRO"
                        && operacoesDebloquear.Contains(e.codigoOperacao) && e.arquivado == false).OrderBy(e => e.dataUltimaAlteracaoErro).ToList();

            foreach (EventoStagging evento in errosDesbloquear)
            {
                evento.arquivado = true;
                evento.dataArquivo = DateTime.Now;
                evento.utilizadorArquivo = eventoValidado.utilizadorReporte;
                eventosStaggingRepository.InsertOrUpdate(evento);
                eventosStaggingRepository.Save();
            }
        }