public void DeveRetornarCodigoDaUPCom17Digitos()
        {
            Int64 result   = UnidadeProducaoGenerator.GerarCodigoUnidadeProducao(3205200, 33, "16", 1);
            Int64 expected = 32052000033160001;

            Assert.AreEqual(expected, result);
        }
        public bool Salvar(UnidadeProducao caracterizacao)
        {
            try
            {
                if (!_validar.Salvar(caracterizacao))
                {
                    return(Validacao.EhValido);
                }

                #region Configurar Salvar

                Municipio municipio = _da.ObterMunicipioPropriedade(caracterizacao.Empreendimento.Id);

                if (!caracterizacao.PossuiCodigoPropriedade)
                {
                    if (caracterizacao.Id < 1)
                    {
                        int sequencial = _da.ObterSequenciaCodigoPropriedade();

                        caracterizacao.CodigoPropriedade = UnidadeProducaoGenerator.GerarCodigoPropriedade(municipio.Ibge, sequencial);
                    }
                    else
                    {
                        caracterizacao.CodigoPropriedade = ObterPorEmpreendimento(caracterizacao.Empreendimento.Id, true).CodigoPropriedade;
                    }
                }

                RequestJson requestJson                        = new RequestJson();
                ResponseJsonData <dynamic> resposta            = new ResponseJsonData <dynamic>();
                UnidadeProducao            caracterizacaoBanco = ObterPorEmpreendimento(caracterizacao.Empreendimento.Id);

                int ultimoCodigoUP = _da.ObterUltimoCodigoUP(caracterizacao.Empreendimento.Id);
                foreach (long item in caracterizacao.UnidadesProducao.Where(x => x.PossuiCodigoUP).Select(x => x.CodigoUP))
                {
                    int aux = Convert.ToInt32(item.ToString().Substring(14));
                    if (aux > ultimoCodigoUP)
                    {
                        ultimoCodigoUP = aux;
                    }
                }

                foreach (UnidadeProducaoItem item in caracterizacao.UnidadesProducao)
                {
                    int codigoIbge = 0;
                    resposta = requestJson.Executar <dynamic>(_configCoord.Obter <String>(ConfiguracaoCoordenada.KeyUrlObterMunicipioCoordenada) + "?easting=" + item.Coordenada.EastingUtm + "&northing=" + item.Coordenada.NorthingUtm);

                    if (resposta.Erros != null && resposta.Erros.Count > 0)
                    {
                        Validacao.Erros.AddRange(resposta.Erros);
                        return(Validacao.EhValido);
                    }

                    if (resposta.Data == null)
                    {
                        throw new Exception(Mensagem.Empreendimento.ErroConexaoMunicipioGeobases.ToString());
                    }

                    var objJson = resposta.Data;
                    if (objJson["EstaNoEstado"] && (objJson["Municipio"] == null || Convert.ToInt32(objJson["Municipio"]["IBGE"] ?? 0) == 0))
                    {
                        Validacao.Add(Mensagem.Mapas.MunicipioSemRetorno);
                    }

                    if (!Validacao.EhValido)
                    {
                        return(Validacao.EhValido);
                    }

                    if (objJson["Municipio"] != null)
                    {
                        codigoIbge = Convert.ToInt32(objJson["Municipio"]["IBGE"] ?? 0);
                    }

                    ListaValoresDa listaValoresDa = new ListaValoresDa();
                    item.Municipio = listaValoresDa.ObterMunicipio(codigoIbge);

                    if (!item.PossuiCodigoUP)
                    {
                        item.AnoAbertura = DateTime.Today.Year.ToString().Substring(2);

                        if (item.Id < 1)
                        {
                            ultimoCodigoUP++;

                            item.CodigoUP = UnidadeProducaoGenerator.GerarCodigoUnidadeProducao(
                                item.Municipio.Ibge
                                , caracterizacao.CodigoPropriedade
                                , item.AnoAbertura
                                , ultimoCodigoUP
                                );
                        }
                        else
                        {
                            item.CodigoUP = caracterizacaoBanco.UnidadesProducao.Single(x => x.Id == item.Id).CodigoUP;
                        }
                    }
                    else
                    {
                        item.AnoAbertura = item.CodigoUP.ToString().Substring(11, 2);
                    }

                    foreach (var aux in item.ResponsaveisTecnicos)
                    {
                        aux.CFONumero = aux.CFONumero.Split('-').GetValue(0).ToString();
                    }
                }

                #endregion

                if (caracterizacao.UnidadesProducao.Any(x => caracterizacao.UnidadesProducao.Count(y => y.CodigoUP == x.CodigoUP) > 1))
                {
                    Validacao.Add(Mensagem.UnidadeProducao.UnidadeProducaoItemIncorreto);
                    return(false);
                }

                foreach (var item in caracterizacao.UnidadesProducao)
                {
                    if (!UnidadeProducaoGenerator.CodigoUpHasCodigoPropriedade(caracterizacao.CodigoPropriedade, item.CodigoUP))
                    {
                        Validacao.Add(Mensagem.UnidadeProducao.CodigoUPNaoContemCodPropriedade(item.CodigoUP));
                        return(false);
                    }
                }

                GerenciadorTransacao.ObterIDAtual();

                using (BancoDeDados bancoDeDados = BancoDeDados.ObterInstancia())
                {
                    bancoDeDados.IniciarTransacao();

                    _da.Salvar(caracterizacao, bancoDeDados);

                    Validacao.Add(Mensagem.UnidadeProducao.SalvoSucesso);

                    bancoDeDados.Commit();
                }
            }
            catch (Exception e)
            {
                Validacao.AddErro(e);
            }

            return(Validacao.EhValido);
        }