package br.com.centralit.citcorpore.negocio;

import java.io.File;
import java.io.FileInputStream;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import br.com.centralit.citcorpore.bean.CargaPortfolioServicoDTO;
import br.com.centralit.citcorpore.bean.CategoriaServicoDTO;
import br.com.centralit.citcorpore.bean.OcorrenciaServicoDTO;
import br.com.centralit.citcorpore.bean.PortfolioServicoDTO;
import br.com.centralit.citcorpore.bean.ServicoAutoRelacionamentoDTO;
import br.com.centralit.citcorpore.bean.ServicoDTO;
import br.com.centralit.citcorpore.util.Enumerados.AuditoriaAcoes;
import br.com.centralit.citcorpore.util.Enumerados.AuditoriaTipos;
import br.com.centralit.citcorpore.util.Enumerados.CamposCargaServicoPortfolio;
import br.com.centralit.citcorpore.util.Enumerados.CriticidadeServico;
import br.com.centralit.citcorpore.util.Enumerados.DemandaServicoNegocio;
import br.com.centralit.citcorpore.util.Enumerados.FaseServico;
import br.com.centralit.citcorpore.util.Enumerados.LogicExceptionCause;
import br.com.centralit.citcorpore.util.Enumerados.OcorrenciaServicoCategorias;
import br.com.centralit.citcorpore.util.Enumerados.RetornoFinanceiroServico;
import br.com.centralit.citcorpore.util.Enumerados.ServiceDemandType;
import br.com.centralit.citcorpore.util.Enumerados.ServiceSituation;
import br.com.centralit.citcorpore.util.Enumerados.SimNao;
import br.com.centralit.citcorpore.util.Enumerados.StatusServico;
import br.com.centralit.citcorpore.util.Enumerados.TipoCategoria;
import br.com.centralit.citcorpore.util.Enumerados.TipoDate;
import br.com.centralit.citcorpore.util.Enumerados.TipoDeInvestimento;
import br.com.centralit.citcorpore.util.Enumerados.TipoServico;
import br.com.centralit.citcorpore.util.Enumerados.ValoresDefaultImportacaoCargaServicoPortfolio;
import br.com.centralit.citcorpore.util.Util;
import br.com.centralit.citcorpore.util.WebUtil;
import br.com.citframework.excecao.LogicException;
import br.com.citframework.excecao.ServiceException;
import br.com.citframework.integracao.CrudDAO;
import br.com.citframework.service.CrudServiceImpl;
import br.com.citframework.service.ServiceLocator;
import br.com.citframework.util.Reflexao;
import br.com.citframework.util.UtilDatas;
import br.com.citframework.util.UtilI18N;
import br.com.citframework.util.UtilStrings;

public class ImportarCargaPortfolioServicoServiceEjb extends CrudServiceImpl implements ImportarCargaPortfolioServicoService {
	private Map<Integer, Integer> mapCamposCargaPortfolioServico;
	private Map<Integer, String> mapCamposDefaultCargaPortfolioServico;
	private List<String> listErrosImportacao;

	private ServicoService servicoService;
	private ServicoAutoRelacionamentoService servicoAutoRelacionamentoService;
	private PortfolioServicoService portfolioServicoService;
	private CategoriaServicoService categoriaServicoService;
	private OcorrenciaServicoService ocorrenciaServicoService;
	private OcorrenciaServicoDetalhesService ocorrenciaServicoDetalhesService;
	private OcorrenciaServicoRelacionadoService ocorrenciaServicoRelacionadoService;

	@Override
	public Collection<CargaPortfolioServicoDTO> gerarCargaXls(HttpServletRequest request, File carga) throws Exception {
		POIFSFileSystem fs;
		HSSFWorkbook wb;
		HSSFSheet sheet;
		HSSFSheet sheetDefault;
		HSSFRow rowHead;
		HSSFRow rowHeadDefault;
		HSSFRow row;

		int rows;

		List<CargaPortfolioServicoDTO> listCargaPortfolioServico = new ArrayList<>();
		List<String> nomesCamposObrigatoriosNaoEncontrados = new ArrayList<>();
		mapCamposCargaPortfolioServico = new HashMap<>();
		mapCamposDefaultCargaPortfolioServico = new HashMap<>();
		listErrosImportacao = new ArrayList<>();

		String idiomaPadrao;


		try {
			fs = new POIFSFileSystem(new FileInputStream(carga));
			wb = new HSSFWorkbook(fs);
			sheet = wb.getSheetAt(0);
			sheetDefault = wb.getSheetAt(1);

			rows = sheet.getPhysicalNumberOfRows();
			
			String nomeCampoDataAtual = UtilI18N.internacionaliza(request, ValoresDefaultImportacaoCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO.getChave());
			
			rowHead = sheet.getRow(0);

			if (rowHead != null) {
				int numCell = 0;
				int numRowDefault = 0;

				rowHeadDefault = sheetDefault.getRow(numRowDefault);
				Cell cellHeadDefaultIdioma = rowHeadDefault.getCell(1);
				idiomaPadrao = cellHeadDefaultIdioma.getStringCellValue();
				numRowDefault++;

				SimpleDateFormat dateFormat = UtilDatas.getSimpleDateFormatByTipoDataAndLanguage(TipoDate.DATE_DEFAULT, idiomaPadrao);
				String dataAtual = dateFormat.format(UtilDatas.getDataAtual());

				List<String> listCamposNaoObrigatorios = Arrays.asList(
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()
				);
				
				for (CamposCargaServicoPortfolio camposCargaServicoPortfolio : CamposCargaServicoPortfolio.values()) {
					Cell cellHead = rowHead.getCell(numCell);
					rowHeadDefault = sheetDefault.getRow(numRowDefault);
					Cell cellHeadDefault = null;
					boolean achouCampo = false;
					
					if(rowHeadDefault != null) {
						cellHeadDefault = rowHeadDefault.getCell(0);
					}

					String nomeCampo = UtilI18N.internacionaliza(request, camposCargaServicoPortfolio.getChave());
					if (cellHead != null && nomeCampo.equalsIgnoreCase(cellHead.getStringCellValue())) {
						achouCampo = true;
						mapCamposCargaPortfolioServico.put(camposCargaServicoPortfolio.getIdentificador(), numCell);
						numCell++;
					} else if (cellHeadDefault != null && nomeCampo.equalsIgnoreCase(cellHeadDefault.getStringCellValue())) {
						achouCampo = true;
						String valorDefault = rowHeadDefault.getCell(1).getStringCellValue();
						if (nomeCampoDataAtual != null && nomeCampoDataAtual.equalsIgnoreCase(valorDefault)) {
							valorDefault = dataAtual;
						}
						mapCamposDefaultCargaPortfolioServico.put(camposCargaServicoPortfolio.getIdentificador(), valorDefault);
						numRowDefault++;
					}
					
					if (!achouCampo && !listCamposNaoObrigatorios.contains(camposCargaServicoPortfolio.getChave())) {
						nomesCamposObrigatoriosNaoEncontrados.add(nomeCampo);
					}

					cellHead = rowHead.getCell(numCell);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.validacao.erroImportar"));
		} finally {
			idiomaPadrao = null;
		}

		if (!nomesCamposObrigatoriosNaoEncontrados.isEmpty()) {
			throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.colunasNaoEncontradas")+":;" + StringUtils.join(nomesCamposObrigatoriosNaoEncontrados, ";"), new Throwable(LogicExceptionCause.IMPORT_ERROR.getIdStr()));
		}

		for (int r = 1; r < rows+1; r++) {
			try {
				row = sheet.getRow(r);
				if (row != null) {
					CargaPortfolioServicoDTO cargaPortfolioServicoDTO = new CargaPortfolioServicoDTO();

					// Portfólio
					String nomePortfolio = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.PORTFOLIO_NOME);
					if (!UtilStrings.isNullOrEmpty(nomePortfolio)) {
						nomePortfolio = nomePortfolio.trim();
						cargaPortfolioServicoDTO.setCargaNomePortfolio(nomePortfolio);
					}

					// Nome Serviço
					String nomeServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_NOME);
					if (!UtilStrings.isNullOrEmpty(nomeServico)) {
						nomeServico = nomeServico.trim();
						cargaPortfolioServicoDTO.setCargaNomeServico(nomeServico);
					}

					// Categoria Serviço
					String categoriaServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CATEGORIA);
					if (!UtilStrings.isNullOrEmpty(categoriaServico)) {
						categoriaServico = categoriaServico.trim();
						cargaPortfolioServicoDTO.setCargaCategoriaNegocioServico(categoriaServico);
					}

					// Data Implantação Serviço
					String dataImplantacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO, true);
					if (!UtilStrings.isNullOrEmpty(dataImplantacaoServico)) {
						dataImplantacaoServico = dataImplantacaoServico.trim();
						Date sqlDateImplantacaoServico;

						try {
							sqlDateImplantacaoServico = UtilDatas.convertStringToSQLDate(TipoDate.DATE_DEFAULT, dataImplantacaoServico, idiomaPadrao);
						} catch (Exception e) {
							sqlDateImplantacaoServico = null;
						}

						if (sqlDateImplantacaoServico != null) {
							cargaPortfolioServicoDTO.setCargaDataImplantacaoServico(sqlDateImplantacaoServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO.getChave()));
						}
					}

					// Fase Serviço
					String faseServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_FASE, true);
					FaseServico enumFaseServico = null;
					if (!UtilStrings.isNullOrEmpty(faseServico)) {
						faseServico = faseServico.trim().toUpperCase();
						enumFaseServico = FaseServico.fromTipo(faseServico);
						if (enumFaseServico != null) {
							cargaPortfolioServicoDTO.setCargaFaseServico(faseServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_FASE.getChave()));
						}
					}

					// Status Serviço
					String statusServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_STATUS, true);
					if (!UtilStrings.isNullOrEmpty(statusServico)) {
						statusServico = statusServico.trim().toUpperCase();
						StatusServico enumStatusServico = StatusServico.fromTipo(statusServico.trim());
						if (enumStatusServico != null && enumFaseServico != null && StatusServico.fromFase(enumFaseServico).contains(enumStatusServico)) {
							cargaPortfolioServicoDTO.setCargaStatusServico(statusServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_STATUS.getChave()));
						}
					}

					// Campos de Classificação do Serviço
					if (enumFaseServico != null && FaseServico.ANALISAR.equals(enumFaseServico)) {
						
						// Criticidade
						String criticidadeClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE, true);
						if (!UtilStrings.isNullOrEmpty(criticidadeClassificacaoServico)) {
							criticidadeClassificacaoServico = criticidadeClassificacaoServico.trim();
							Integer idCriticidadeClassificacaoServico;
							try {
								idCriticidadeClassificacaoServico = (int) Double.parseDouble(criticidadeClassificacaoServico);
							} catch (Exception e) {
								idCriticidadeClassificacaoServico = null;
							}

							if (idCriticidadeClassificacaoServico != null) {
								CriticidadeServico enumCriticidadeServico = CriticidadeServico.fromItem(idCriticidadeClassificacaoServico);
								if (enumCriticidadeServico != null) {
									cargaPortfolioServicoDTO.setCargaCriticidadeClassificacaoServico(idCriticidadeClassificacaoServico);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave()));
							}
						}
						
						// Tipo de Investimento
						String tipoInvestimentoClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO);
						if (!UtilStrings.isNullOrEmpty(tipoInvestimentoClassificacaoServico)) {
							tipoInvestimentoClassificacaoServico = tipoInvestimentoClassificacaoServico.trim().toUpperCase();
							TipoDeInvestimento enumTipoDeInvestimento = TipoDeInvestimento.fromTipo(tipoInvestimentoClassificacaoServico);
							if (enumTipoDeInvestimento != null) {
								cargaPortfolioServicoDTO.setCargaTipoInvestimentoClassificacaoServico(tipoInvestimentoClassificacaoServico);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO.getChave()));
							}
						}

						// Demanda
						String demandaClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA);
						if (!UtilStrings.isNullOrEmpty(demandaClassificacaoServico)) {
							demandaClassificacaoServico = demandaClassificacaoServico.trim();
							Integer idDemanda;
							try {
								idDemanda = (int) Double.parseDouble(demandaClassificacaoServico);
							} catch (Exception e) {
								idDemanda = null;
							}

							if (idDemanda != null) {
								DemandaServicoNegocio enumDemanda = DemandaServicoNegocio.fromIdentificador(idDemanda);
								if (enumDemanda != null) {
									cargaPortfolioServicoDTO.setCargaDemandaClassificacaoServico(idDemanda);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave()));
							}
						}

						// Retorno Financeiro
						String retornoFinanceiroClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO);
						if (!UtilStrings.isNullOrEmpty(retornoFinanceiroClassificacaoServico)) {
							retornoFinanceiroClassificacaoServico = retornoFinanceiroClassificacaoServico.trim();
							Integer idRetornoFinanceiro;
							try {
								idRetornoFinanceiro = (int) Double.parseDouble(retornoFinanceiroClassificacaoServico);
							} catch (Exception e) {
								idRetornoFinanceiro = null;
							}
							
							if (idRetornoFinanceiro != null) {
								RetornoFinanceiroServico enumRetornoFinanceiro = RetornoFinanceiroServico.fromIdentificador(idRetornoFinanceiro);
								if (enumRetornoFinanceiro != null) {
									cargaPortfolioServicoDTO.setCargaRetornoFinanceiroClassificacaoServico(idRetornoFinanceiro);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()));
							}
						}
					}

					// Nome Serviço (Incidente/Requisição)
					String nomeServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_NOME);
					if (!UtilStrings.isNullOrEmpty(nomeServicoIncReq)) {
						nomeServicoIncReq = nomeServicoIncReq.trim();
						cargaPortfolioServicoDTO.setCargaNomeServicoIncReq(nomeServicoIncReq);
					}

					// Situação Serviço (Incidente/Requisição)
					String situacaoServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO, true);
					if (!UtilStrings.isNullOrEmpty(situacaoServicoIncReq)) {
						situacaoServicoIncReq = situacaoServicoIncReq.trim();
						Integer idSituacaoServicoIncReq;
						try {
							idSituacaoServicoIncReq = (int) Double.parseDouble(situacaoServicoIncReq);
						} catch (Exception e) {
							idSituacaoServicoIncReq = null;
						}

						if (idSituacaoServicoIncReq != null) {
							ServiceSituation enumServiceSituation = ServiceSituation.fromId(idSituacaoServicoIncReq);
							if (enumServiceSituation != null) {
								cargaPortfolioServicoDTO.setCargaSituacaoServicoIncReq(idSituacaoServicoIncReq);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO.getChave()));
							}
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO.getChave()));
						}
					}

					// Data Implantação (Incidente/Requisição)
					String dataImplantacaoServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DATA_IMPLANTACAO, true);
					if (!UtilStrings.isNullOrEmpty(dataImplantacaoServicoIncReq)) {
						dataImplantacaoServicoIncReq = dataImplantacaoServicoIncReq.trim();
						Date sqlDateImplantacaoServicoIncReq;

						try {
							sqlDateImplantacaoServicoIncReq = UtilDatas.convertStringToSQLDate(TipoDate.DATE_DEFAULT, dataImplantacaoServicoIncReq, idiomaPadrao);
						} catch (Exception e) {
							sqlDateImplantacaoServicoIncReq = null;
						}

						if (sqlDateImplantacaoServicoIncReq != null) {
							cargaPortfolioServicoDTO.setCargaDataImplantacaoServicoIncReq(sqlDateImplantacaoServicoIncReq);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DATA_IMPLANTACAO.getChave()));
						}
					}

					// Tipo de Demanda (Incidente/Requisição)
					String tipoDemandaServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA);
					if (!UtilStrings.isNullOrEmpty(tipoDemandaServicoIncReq)) {
						tipoDemandaServicoIncReq = tipoDemandaServicoIncReq.trim();
						Integer idTipoDemandaServicoIncReq;
						try {
							idTipoDemandaServicoIncReq = (int) Double.parseDouble(tipoDemandaServicoIncReq);
						} catch (Exception e) {
							idTipoDemandaServicoIncReq = null;
						}

						if (idTipoDemandaServicoIncReq != null) {
							if (ServiceDemandType.INCIDENT.getId().equals(idTipoDemandaServicoIncReq) || ServiceDemandType.REQUEST.getId().equals(idTipoDemandaServicoIncReq)) {
								cargaPortfolioServicoDTO.setCargaTipoDemandaServicoIncReq(idTipoDemandaServicoIncReq);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA.getChave()));
							}
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA.getChave()));
						}

					}

					// Categoria (Incidente/Requisição)
					String categoriaServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_CATEGORIA);
					if (!UtilStrings.isNullOrEmpty(categoriaServicoIncReq)) {
						categoriaServicoIncReq = categoriaServicoIncReq.trim();
						cargaPortfolioServicoDTO.setCargaCategoriaServicoIncReq(categoriaServicoIncReq);
					}

					// Disponpível pelo Portal (Incidente/Requisição)
					String dispPortalServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DISP_PORTAL, true);
					if (!UtilStrings.isNullOrEmpty(dispPortalServicoIncReq)) {
						dispPortalServicoIncReq = dispPortalServicoIncReq.trim().toUpperCase();
						if (dispPortalServicoIncReq.trim().equals(SimNao.SIM.getValorStr()) || dispPortalServicoIncReq.trim().equals(SimNao.NAO.getValorStr())) {
							cargaPortfolioServicoDTO.setCargaDispPortalServicoIncReq(dispPortalServicoIncReq);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DISP_PORTAL.getChave()));
						}
					}

					listCargaPortfolioServico.add(cargaPortfolioServicoDTO);
				} else {
					if(r != rows) {
						this.listErrosImportacao.add(this.getMsgErroNenhumValorInformado(request, r));
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.validacao.erroImportar"));
			}
		}

		if (listErrosImportacao != null && !listErrosImportacao.isEmpty()) {
			throw new LogicException(StringUtils.join(listErrosImportacao, ";"), new Throwable(LogicExceptionCause.IMPORT_ERROR.getIdStr()));
		}

		return listCargaPortfolioServico;
	}


	@Override
	public Collection<CargaPortfolioServicoDTO> gerarCargaXlsx(HttpServletRequest request, File carga) throws Exception {
		XSSFWorkbook wb;
		XSSFSheet sheet;
		XSSFSheet sheetDefault;
		XSSFRow rowHead;
		XSSFRow rowHeadDefault;
		XSSFRow row;

		int rows;
		
		List<CargaPortfolioServicoDTO> listCargaPortfolioServico = new ArrayList<>();
		List<String> nomesCamposObrigatoriosNaoEncontrados = new ArrayList<>();
		mapCamposCargaPortfolioServico = new HashMap<>();
		mapCamposDefaultCargaPortfolioServico = new HashMap<>();
		listErrosImportacao = new ArrayList<>();
		
		String idiomaPadrao;
		

		try {
			wb = new XSSFWorkbook(new FileInputStream(carga));
			sheet = wb.getSheetAt(0);
			sheetDefault = wb.getSheetAt(1);
			rows = sheet.getPhysicalNumberOfRows();
			
			String nomeCampoDataAtual = UtilI18N.internacionaliza(request, ValoresDefaultImportacaoCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO.getChave());
			
			rowHead = sheet.getRow(0);

			if (rowHead != null) {
				int numCell = 0;
				int numRowDefault = 0;

				rowHeadDefault = sheetDefault.getRow(numRowDefault);
				Cell cellHeadDefaultIdioma = rowHeadDefault.getCell(1);
				idiomaPadrao = cellHeadDefaultIdioma.getStringCellValue();
				numRowDefault++;

				SimpleDateFormat dateFormat = UtilDatas.getSimpleDateFormatByTipoDataAndLanguage(TipoDate.DATE_DEFAULT, idiomaPadrao);
				String dataAtual = dateFormat.format(UtilDatas.getDataAtual());

				List<String> listCamposNaoObrigatorios = Arrays.asList(
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave(),
						CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()
				);
				
				for (CamposCargaServicoPortfolio camposCargaServicoPortfolio : CamposCargaServicoPortfolio.values()) {
					Cell cellHead = rowHead.getCell(numCell);
					rowHeadDefault = sheetDefault.getRow(numRowDefault);
					Cell cellHeadDefault = null;
					boolean achouCampo = false;
					
					if(rowHeadDefault != null) {
						cellHeadDefault = rowHeadDefault.getCell(0);
					}

					String nomeCampo = UtilI18N.internacionaliza(request, camposCargaServicoPortfolio.getChave());
					if (cellHead != null && nomeCampo.equalsIgnoreCase(cellHead.getStringCellValue())) {
						achouCampo = true;
						mapCamposCargaPortfolioServico.put(camposCargaServicoPortfolio.getIdentificador(), numCell);
						numCell++;
					} else if (cellHeadDefault != null && nomeCampo.equalsIgnoreCase(cellHeadDefault.getStringCellValue())) {
						achouCampo = true;
						String valorDefault = rowHeadDefault.getCell(1).getStringCellValue();
						if (nomeCampoDataAtual != null && nomeCampoDataAtual.equalsIgnoreCase(valorDefault)) {
							valorDefault = dataAtual;
						}
						mapCamposDefaultCargaPortfolioServico.put(camposCargaServicoPortfolio.getIdentificador(), valorDefault);
						numRowDefault++;
					}
					
					if (!achouCampo && !listCamposNaoObrigatorios.contains(camposCargaServicoPortfolio.getChave())) {
						nomesCamposObrigatoriosNaoEncontrados.add(nomeCampo);
					}

					cellHead = rowHead.getCell(numCell);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.validacao.erroImportar"));
		} finally {
			idiomaPadrao = null;
		}

		if (!nomesCamposObrigatoriosNaoEncontrados.isEmpty()) {
			throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.colunasNaoEncontradas")+":;" + StringUtils.join(nomesCamposObrigatoriosNaoEncontrados, ";"), new Throwable(LogicExceptionCause.IMPORT_ERROR.getIdStr()));
		}

		for (int r = 1; r < rows+1; r++) {
			try {
				row = sheet.getRow(r);
				if (row != null) {
					CargaPortfolioServicoDTO cargaPortfolioServicoDTO = new CargaPortfolioServicoDTO();

					// Portfólio
					String nomePortfolio = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.PORTFOLIO_NOME);
					if (!UtilStrings.isNullOrEmpty(nomePortfolio)) {
						nomePortfolio = nomePortfolio.trim();
						cargaPortfolioServicoDTO.setCargaNomePortfolio(nomePortfolio);
					}

					// Nome Serviço
					String nomeServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_NOME);
					if (!UtilStrings.isNullOrEmpty(nomeServico)) {
						nomeServico = nomeServico.trim();
						cargaPortfolioServicoDTO.setCargaNomeServico(nomeServico);
					}

					// Categoria Serviço
					String categoriaServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CATEGORIA);
					if (!UtilStrings.isNullOrEmpty(categoriaServico)) {
						categoriaServico = categoriaServico.trim();
						cargaPortfolioServicoDTO.setCargaCategoriaNegocioServico(categoriaServico);
					}

					// Data Implantação Serviço
					String dataImplantacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO, true);
					if (!UtilStrings.isNullOrEmpty(dataImplantacaoServico)) {
						dataImplantacaoServico = dataImplantacaoServico.trim();
						Date sqlDateImplantacaoServico;

						try {
							sqlDateImplantacaoServico = UtilDatas.convertStringToSQLDate(TipoDate.DATE_DEFAULT, dataImplantacaoServico, idiomaPadrao);
						} catch (Exception e) {
							sqlDateImplantacaoServico = null;
						}

						if (sqlDateImplantacaoServico != null) {
							cargaPortfolioServicoDTO.setCargaDataImplantacaoServico(sqlDateImplantacaoServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_DATA_IMPLANTACAO.getChave()));
						}
					}

					// Fase Serviço
					String faseServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_FASE, true);
					FaseServico enumFaseServico = null;
					if (!UtilStrings.isNullOrEmpty(faseServico)) {
						faseServico = faseServico.trim().toUpperCase();
						enumFaseServico = FaseServico.fromTipo(faseServico);
						if (enumFaseServico != null) {
							cargaPortfolioServicoDTO.setCargaFaseServico(faseServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_FASE.getChave()));
						}
					}

					// Status Serviço
					String statusServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_STATUS, true);
					if (!UtilStrings.isNullOrEmpty(statusServico)) {
						statusServico = statusServico.trim().toUpperCase();
						StatusServico enumStatusServico = StatusServico.fromTipo(statusServico.trim());
						if (enumStatusServico != null && enumFaseServico != null && StatusServico.fromFase(enumFaseServico).contains(enumStatusServico)) {
							cargaPortfolioServicoDTO.setCargaStatusServico(statusServico);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_STATUS.getChave()));
						}
					}

					// Campos de Classificação do Serviço
					if (enumFaseServico != null && FaseServico.ANALISAR.equals(enumFaseServico)) {
						
						// Criticidade
						String criticidadeClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE, true);
						if (!UtilStrings.isNullOrEmpty(criticidadeClassificacaoServico)) {
							criticidadeClassificacaoServico = criticidadeClassificacaoServico.trim();
							Integer idCriticidadeClassificacaoServico;
							try {
								idCriticidadeClassificacaoServico = (int) Double.parseDouble(criticidadeClassificacaoServico);
							} catch (Exception e) {
								idCriticidadeClassificacaoServico = null;
							}

							if (idCriticidadeClassificacaoServico != null) {
								CriticidadeServico enumCriticidadeServico = CriticidadeServico.fromItem(idCriticidadeClassificacaoServico);
								if (enumCriticidadeServico != null) {
									cargaPortfolioServicoDTO.setCargaCriticidadeClassificacaoServico(idCriticidadeClassificacaoServico);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_CRITICIDADE.getChave()));
							}
						}
						
						// Tipo de Investimento
						String tipoInvestimentoClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO);
						if (!UtilStrings.isNullOrEmpty(tipoInvestimentoClassificacaoServico)) {
							tipoInvestimentoClassificacaoServico = tipoInvestimentoClassificacaoServico.trim().toUpperCase();
							TipoDeInvestimento enumTipoDeInvestimento = TipoDeInvestimento.fromTipo(tipoInvestimentoClassificacaoServico);
							if (enumTipoDeInvestimento != null) {
								cargaPortfolioServicoDTO.setCargaTipoInvestimentoClassificacaoServico(tipoInvestimentoClassificacaoServico);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_TIPO_INVESTIMENTO.getChave()));
							}
						}

						// Demanda
						String demandaClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA);
						if (!UtilStrings.isNullOrEmpty(demandaClassificacaoServico)) {
							demandaClassificacaoServico = demandaClassificacaoServico.trim();
							Integer idDemanda;
							try {
								idDemanda = (int) Double.parseDouble(demandaClassificacaoServico);
							} catch (Exception e) {
								idDemanda = null;
							}

							if (idDemanda != null) {
								DemandaServicoNegocio enumDemanda = DemandaServicoNegocio.fromIdentificador(idDemanda);
								if (enumDemanda != null) {
									cargaPortfolioServicoDTO.setCargaDemandaClassificacaoServico(idDemanda);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_DEMANDA.getChave()));
							}
						}

						// Retorno Financeiro
						String retornoFinanceiroClassificacaoServico = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO);
						if (!UtilStrings.isNullOrEmpty(retornoFinanceiroClassificacaoServico)) {
							retornoFinanceiroClassificacaoServico = retornoFinanceiroClassificacaoServico.trim();
							Integer idRetornoFinanceiro;
							try {
								idRetornoFinanceiro = (int) Double.parseDouble(retornoFinanceiroClassificacaoServico);
							} catch (Exception e) {
								idRetornoFinanceiro = null;
							}
							
							if (idRetornoFinanceiro != null) {
								RetornoFinanceiroServico enumRetornoFinanceiro = RetornoFinanceiroServico.fromIdentificador(idRetornoFinanceiro);
								if (enumRetornoFinanceiro != null) {
									cargaPortfolioServicoDTO.setCargaRetornoFinanceiroClassificacaoServico(idRetornoFinanceiro);
								} else {
									listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()));
								}
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_CLASSIFICACAO_RETORNO_FINANCEIRO.getChave()));
							}
						}
					}

					// Nome Serviço (Incidente/Requisição)
					String nomeServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_NOME);
					if (!UtilStrings.isNullOrEmpty(nomeServicoIncReq)) {
						nomeServicoIncReq = nomeServicoIncReq.trim();
						cargaPortfolioServicoDTO.setCargaNomeServicoIncReq(nomeServicoIncReq);
					}

					// Situação Serviço (Incidente/Requisição)
					String situacaoServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO, true);
					if (!UtilStrings.isNullOrEmpty(situacaoServicoIncReq)) {
						situacaoServicoIncReq = situacaoServicoIncReq.trim();
						Integer idSituacaoServicoIncReq;
						try {
							idSituacaoServicoIncReq = (int) Double.parseDouble(situacaoServicoIncReq);
						} catch (Exception e) {
							idSituacaoServicoIncReq = null;
						}

						if (idSituacaoServicoIncReq != null) {
							ServiceSituation enumServiceSituation = ServiceSituation.fromId(idSituacaoServicoIncReq);
							if (enumServiceSituation != null) {
								cargaPortfolioServicoDTO.setCargaSituacaoServicoIncReq(idSituacaoServicoIncReq);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO.getChave()));
							}
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_SITUACAO.getChave()));
						}
					}

					// Data Implantação (Incidente/Requisição)
					String dataImplantacaoServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DATA_IMPLANTACAO, true);
					if (!UtilStrings.isNullOrEmpty(dataImplantacaoServicoIncReq)) {
						dataImplantacaoServicoIncReq = dataImplantacaoServicoIncReq.trim();
						Date sqlDateImplantacaoServicoIncReq;

						try {
							sqlDateImplantacaoServicoIncReq = UtilDatas.convertStringToSQLDate(TipoDate.DATE_DEFAULT, dataImplantacaoServicoIncReq, idiomaPadrao);
						} catch (Exception e) {
							sqlDateImplantacaoServicoIncReq = null;
						}

						if (sqlDateImplantacaoServicoIncReq != null) {
							cargaPortfolioServicoDTO.setCargaDataImplantacaoServicoIncReq(sqlDateImplantacaoServicoIncReq);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DATA_IMPLANTACAO.getChave()));
						}
					}

					// Tipo de Demanda (Incidente/Requisição)
					String tipoDemandaServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA);
					if (!UtilStrings.isNullOrEmpty(tipoDemandaServicoIncReq)) {
						tipoDemandaServicoIncReq = tipoDemandaServicoIncReq.trim();
						Integer idTipoDemandaServicoIncReq;
						try {
							idTipoDemandaServicoIncReq = (int) Double.parseDouble(tipoDemandaServicoIncReq);
						} catch (Exception e) {
							idTipoDemandaServicoIncReq = null;
						}

						if (idTipoDemandaServicoIncReq != null) {
							if (ServiceDemandType.INCIDENT.getId().equals(idTipoDemandaServicoIncReq) || ServiceDemandType.REQUEST.getId().equals(idTipoDemandaServicoIncReq)) {
								cargaPortfolioServicoDTO.setCargaTipoDemandaServicoIncReq(idTipoDemandaServicoIncReq);
							} else {
								listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA.getChave()));
							}
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_TIPO_DEMANDA.getChave()));
						}

					}

					// Categoria (Incidente/Requisição)
					String categoriaServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_CATEGORIA);
					if (!UtilStrings.isNullOrEmpty(categoriaServicoIncReq)) {
						categoriaServicoIncReq = categoriaServicoIncReq.trim();
						cargaPortfolioServicoDTO.setCargaCategoriaServicoIncReq(categoriaServicoIncReq);
					}

					// Disponpível pelo Portal (Incidente/Requisição)
					String dispPortalServicoIncReq = this.getCampoCarga(request, row, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DISP_PORTAL, true);
					if (!UtilStrings.isNullOrEmpty(dispPortalServicoIncReq)) {
						dispPortalServicoIncReq = dispPortalServicoIncReq.trim().toUpperCase();
						if (dispPortalServicoIncReq.trim().equals(SimNao.SIM.getValorStr()) || dispPortalServicoIncReq.trim().equals(SimNao.NAO.getValorStr())) {
							cargaPortfolioServicoDTO.setCargaDispPortalServicoIncReq(dispPortalServicoIncReq);
						} else {
							listErrosImportacao.add(this.getMsgErroValorIncorreto(request, r, CamposCargaServicoPortfolio.SERVICO_INCREQ_DISP_PORTAL.getChave()));
						}
					}

					listCargaPortfolioServico.add(cargaPortfolioServicoDTO);
				} else {
					if(r != rows) {
						this.listErrosImportacao.add(this.getMsgErroNenhumValorInformado(request, r));
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new LogicException(UtilI18N.internacionaliza(request, "cargaPortfolioServico.validacao.erroImportar"));
			}
		}

		if (listErrosImportacao != null && !listErrosImportacao.isEmpty()) {
			throw new LogicException(StringUtils.join(listErrosImportacao, ";"), new Throwable(LogicExceptionCause.IMPORT_ERROR.getIdStr()));
		}

		return listCargaPortfolioServico;
	}

	private String getMsgErroGravar(HttpServletRequest request, Integer numRegistro, String chaveTipoRegistro, String chaveNomeCampo) {
		StringBuilder sb = new StringBuilder();
		sb.append(UtilI18N.internacionaliza(request, "citcorpore.comum.registro"));
		sb.append(" ");
		sb.append(numRegistro);
		sb.append(" | ");
		sb.append(UtilI18N.internacionaliza(request, chaveTipoRegistro));
		sb.append(" '");
		sb.append(UtilI18N.internacionaliza(request, chaveNomeCampo));
		sb.append("' ");
		sb.append(" - ");
		sb.append(UtilI18N.internacionaliza(request, "citcorpore.comum.erroAoGravar"));
		return sb.toString();
	}
	
	private String getMsgErroNenhumValorInformado(HttpServletRequest request, Integer numRow) {
		StringBuilder sb = new StringBuilder();
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.linha"));
		sb.append(" ");
		sb.append(numRow+1);
		sb.append(" | ");
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.nenhumValorInformado"));
		return sb.toString();
	}
	
	private String getHeadMsgErro(HttpServletRequest request, Integer numRow, String chaveNomeCampo) {
		StringBuilder sb = new StringBuilder();
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.linha"));
		sb.append(" ");
		sb.append(numRow+1);
		sb.append(" | ");
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.campo"));
		sb.append(" '");
		sb.append(UtilI18N.internacionaliza(request, chaveNomeCampo));
		sb.append("' ");
		return sb.toString();
	}
	
	private String getMsgErroValorIncorreto(HttpServletRequest request, Integer numRow, String chaveNomeCampo) {
		StringBuilder sb = new StringBuilder(this.getHeadMsgErro(request, numRow, chaveNomeCampo));
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.valorIncorreto"));
		sb.append(".");
		return sb.toString();
	}
	
	private String getMsgErroValorNaoInformado(HttpServletRequest request, Integer numRow, String chaveNomeCampo) {
		StringBuilder sb = new StringBuilder(this.getHeadMsgErro(request, numRow, chaveNomeCampo));
		sb.append(UtilI18N.internacionaliza(request, "cargaPortfolioServico.msg.valorNaoInformado"));
		sb.append(".");
		return sb.toString();
	}

	private String getCampoCarga(HttpServletRequest request, Row row, Integer numRow, CamposCargaServicoPortfolio campoCarga) {
		return this.getCampoCarga(request, row, numRow, campoCarga, false);
	}

	private String getCampoCarga(HttpServletRequest request, Row row, Integer numRow, CamposCargaServicoPortfolio campoCarga, boolean possuiValorDefault) {
		Integer numCell = mapCamposCargaPortfolioServico.get(campoCarga.getIdentificador());
		String valorCampo = null;
		if (numCell != null) {
			Cell cellCategoriaServico = row.getCell(numCell);
			if (cellCategoriaServico != null) {
				int tipoCell = cellCategoriaServico.getCellType();
				if(tipoCell == Cell.CELL_TYPE_STRING) {
					valorCampo = cellCategoriaServico.getStringCellValue();
				}

				if(tipoCell == Cell.CELL_TYPE_NUMERIC) {
					double valorCampoNumerico = cellCategoriaServico.getNumericCellValue();
					if(valorCampoNumerico != 0) {
						valorCampo = String.valueOf(valorCampoNumerico);
					}
				}
			}
		} else if (possuiValorDefault) {
			valorCampo = mapCamposDefaultCargaPortfolioServico.get(campoCarga.getIdentificador());
		}

		if (UtilStrings.isNullOrEmpty(valorCampo)) {
			listErrosImportacao.add(this.getMsgErroValorNaoInformado(request, numRow, campoCarga.getChave()));
			return null;
		}

		return valorCampo;
	}

	@Override
	public boolean gravarCargaPortfolioServico(HttpServletRequest request, Collection<CargaPortfolioServicoDTO> listCargaPortfolioServico) throws Exception {
		Map<String, Integer> listPortfolio = new HashMap<>();
		Map<String, Integer> listServicos = new HashMap<>();
		Map<String, ServicoDTO> listServicosIncReq = new HashMap<>();
		List<String> listErrosImportacao = new ArrayList<>();

		int linha = 1;
		for (CargaPortfolioServicoDTO cargaPortfolioServicoDTO : listCargaPortfolioServico) {
			Integer idPortfolio;
			if (listPortfolio.containsKey(cargaPortfolioServicoDTO.getCargaNomePortfolio())) {
				idPortfolio = listPortfolio.get(cargaPortfolioServicoDTO.getCargaNomePortfolio());
			} else {
				try {
					idPortfolio = this.gravarPortfolio(request, cargaPortfolioServicoDTO.getCargaNomePortfolio());
				} catch (Exception e) {
					idPortfolio = null;
					listErrosImportacao.add(this.getMsgErroGravar(request, linha, "gerenciaportfolio.portfolio", cargaPortfolioServicoDTO.getCargaNomePortfolio()));
					e.printStackTrace();
				}
				
				if(idPortfolio != null) {
					listPortfolio.put(cargaPortfolioServicoDTO.getCargaNomePortfolio(), idPortfolio);
				} else {
					continue;
				}
			}

			Integer idServicoNegocio;
			String keyServicoNegocio = cargaPortfolioServicoDTO.getCargaNomeServico()+"|"+cargaPortfolioServicoDTO.getCargaNomePortfolio();
			keyServicoNegocio = keyServicoNegocio.trim();
			if (listServicos.containsKey(keyServicoNegocio)) {
				idServicoNegocio = listServicos.get(keyServicoNegocio);
			} else {
				try {
					idServicoNegocio = this.gravarServico(request, idPortfolio, cargaPortfolioServicoDTO);
				} catch (Exception e) {
					idServicoNegocio = null;
					listErrosImportacao.add(this.getMsgErroGravar(request, linha, "gerenciaportfolio.servicoNegocio", cargaPortfolioServicoDTO.getCargaNomeServico()));
					e.printStackTrace();
				}
				
				if(idServicoNegocio != null) {
					listServicos.put(keyServicoNegocio, idServicoNegocio);
				} else {
					continue;
				}
			}

			ServicoDTO servicoIncReq;
			String keyServicoIncReq = cargaPortfolioServicoDTO.getCargaNomeServicoIncReq()+"|"+cargaPortfolioServicoDTO.getCargaNomeServico()+"|"+cargaPortfolioServicoDTO.getCargaNomePortfolio()+"|"+cargaPortfolioServicoDTO.getCargaTipoDemandaServicoIncReq();
			keyServicoIncReq = keyServicoIncReq.trim();
			if (listServicosIncReq.containsKey(keyServicoIncReq)) {
				servicoIncReq = listServicosIncReq.get(keyServicoIncReq);
				this.vincularServicoIncidenteRequisicao(request, idServicoNegocio, servicoIncReq);
			} else {
				try {
					servicoIncReq = this.gravarServicoIncidenteRequisicao(request, idPortfolio, idServicoNegocio, cargaPortfolioServicoDTO);
				} catch (Exception e) {
					servicoIncReq = null;
					listErrosImportacao.add(this.getMsgErroGravar(request, linha, "cargaPortfolioServico.incidenteRequisicao", cargaPortfolioServicoDTO.getCargaNomeServicoIncReq()));
					e.printStackTrace();
				}
				
				if(servicoIncReq != null) {
					listServicosIncReq.put(keyServicoIncReq, servicoIncReq);
				} else {
					continue;
				}
			}

			linha++;
		}

		if (listErrosImportacao != null && !listErrosImportacao.isEmpty()) {
			throw new LogicException(StringUtils.join(listErrosImportacao, ";"), new Throwable(LogicExceptionCause.IMPORT_ERROR.getIdStr()));
		}

		return true;
	}

	private Integer gravarPortfolio(HttpServletRequest request, String nomePortfolio) throws Exception {
		PortfolioServicoDTO portfolioServicoDTO = new PortfolioServicoDTO();

		portfolioServicoDTO.setDescPortfolioServico(nomePortfolio);
		portfolioServicoDTO.setDataInicio(UtilDatas.getDataAtual());
		portfolioServicoDTO = this.getPortfolioServicoService().create(portfolioServicoDTO);

		if (portfolioServicoDTO != null)
			return portfolioServicoDTO.getIdPortfolioServico();

		return null;
	}

	private Integer gravarServico(HttpServletRequest request, Integer idPortfolio, CargaPortfolioServicoDTO cargaPortfolioServicoDTO) throws Exception {
		ServicoDTO servicoDTO = new ServicoDTO();

		servicoDTO.setDispPortal(SimNao.NAO.getValorStr());
		servicoDTO.setIdEmpresa(WebUtil.getIdEmpresa(request));
		servicoDTO.setIdSituacaoServico(new Integer(0));

		servicoDTO.setIdPortfolioServico(idPortfolio);
		servicoDTO.setNomeServico(cargaPortfolioServicoDTO.getCargaNomeServico());
		servicoDTO.setDataInicio(cargaPortfolioServicoDTO.getCargaDataImplantacaoServico());
		servicoDTO.setFaseServico(cargaPortfolioServicoDTO.getCargaFaseServico());
		servicoDTO.setStatusServico(cargaPortfolioServicoDTO.getCargaStatusServico());
		servicoDTO.setTipoServico(TipoServico.SERVICO_NEGOCIO.getIdentificador());
		
		if(FaseServico.ANALISAR.getIdentificador().equalsIgnoreCase(cargaPortfolioServicoDTO.getCargaFaseServico())) {
			servicoDTO.setCriticidadeServico(cargaPortfolioServicoDTO.getCargaCriticidadeClassificacaoServico());
			servicoDTO.setTipoDeInvestimento(cargaPortfolioServicoDTO.getCargaTipoInvestimentoClassificacaoServico());
			servicoDTO.setDemandaServico(cargaPortfolioServicoDTO.getCargaDemandaClassificacaoServico());
			servicoDTO.setRetornoFinanceiroServico(cargaPortfolioServicoDTO.getCargaRetornoFinanceiroClassificacaoServico());
		}

		CategoriaServicoDTO categoriaServicoDTO = new CategoriaServicoDTO();
		categoriaServicoDTO.setIdEmpresa(WebUtil.getIdEmpresa(request));
		categoriaServicoDTO.setDataInicio(UtilDatas.getDataAtual());
		categoriaServicoDTO.setNomeCategoriaServico(cargaPortfolioServicoDTO.getCargaCategoriaNegocioServico());
		categoriaServicoDTO.setTipoCategoria(TipoCategoria.CATEGORIA_NEGOCIO.getIdentificador());

		Integer idCategoriaNegocio = getCategoriaServicoService().getIdCategoriaSeExiste(categoriaServicoDTO);
		if (idCategoriaNegocio == null) {
			categoriaServicoDTO = getCategoriaServicoService().create(categoriaServicoDTO);
			idCategoriaNegocio = categoriaServicoDTO.getIdCategoriaServico();
		}

		servicoDTO.setIdCategoriaServico(idCategoriaNegocio);

		servicoDTO = this.getServicoService().create(servicoDTO);

		if (servicoDTO != null && servicoDTO.getIdServico() != null) {
			// Auditoria
			OcorrenciaServicoDTO ocorrenciaServicoDTO = this.createAuditoriaAutomatica(servicoDTO.getIdServico(), OcorrenciaServicoCategorias.DETALHES_SERVICO.getIdentificador(), request);
			this.getOcorrenciaServicoDetalhesService().createOcorrenciaServicoDetalhes(ocorrenciaServicoDTO.getIdOcorrenciaServico(), AuditoriaAcoes.IMPORTADO.getIdentificador());
			return servicoDTO.getIdServico();
		}

		return null;
	}

	private ServicoDTO gravarServicoIncidenteRequisicao(HttpServletRequest request, Integer idPortfolio, Integer idServicoNegocio, CargaPortfolioServicoDTO cargaPortfolioServicoDTO) throws Exception {
		ServicoDTO servicoDTO = new ServicoDTO();

		if (idServicoNegocio != null) {

			servicoDTO.setIdPortfolioServico(idPortfolio);
			servicoDTO.setNomeServico(cargaPortfolioServicoDTO.getCargaNomeServicoIncReq());
			servicoDTO.setDataInicio(cargaPortfolioServicoDTO.getCargaDataImplantacaoServicoIncReq());
			servicoDTO.setIdSituacaoServico(cargaPortfolioServicoDTO.getCargaSituacaoServicoIncReq());
			servicoDTO.setIdTipoDemandaServico(cargaPortfolioServicoDTO.getCargaTipoDemandaServicoIncReq());
			servicoDTO.setDispPortal(cargaPortfolioServicoDTO.getCargaDispPortalServicoIncReq());
			servicoDTO.setIncidenteCritico(SimNao.NAO.getValorStr());
			
			if(ServiceDemandType.INCIDENT.getId().equals(cargaPortfolioServicoDTO.getCargaTipoDemandaServicoIncReq())) {
				servicoDTO.setTipoServico(TipoServico.SERVICO_INCIDENTE.getIdentificador());
			}
			
			if(ServiceDemandType.REQUEST.getId().equals(cargaPortfolioServicoDTO.getCargaTipoDemandaServicoIncReq())) {
				servicoDTO.setTipoServico(TipoServico.SERVICO_REQUISICAO.getIdentificador());
			}

			servicoDTO.setIdEmpresa(WebUtil.getIdEmpresa(request));
			servicoDTO.setDataInicio(UtilDatas.getDataAtual());
			
			CategoriaServicoDTO categoriaServicoDTO = new CategoriaServicoDTO();
			categoriaServicoDTO.setIdEmpresa(WebUtil.getIdEmpresa(request));
			categoriaServicoDTO.setDataInicio(UtilDatas.getDataAtual());
			categoriaServicoDTO.setNomeCategoriaServico(cargaPortfolioServicoDTO.getCargaCategoriaServicoIncReq());
			categoriaServicoDTO.setTipoCategoria(TipoCategoria.CATEGORIA_INCIDENTE_REQUISICAO.getIdentificador());

			Integer idCategoriaIncReq = getCategoriaServicoService().getIdCategoriaSeExiste(categoriaServicoDTO);
			if (idCategoriaIncReq == null) {
				categoriaServicoDTO = getCategoriaServicoService().create(categoriaServicoDTO);
				idCategoriaIncReq = categoriaServicoDTO.getIdCategoriaServico();
			}

			servicoDTO.setIdCategoriaServico(idCategoriaIncReq);
			
			servicoDTO = this.getServicoService().create(servicoDTO);


			if (servicoDTO != null && servicoDTO.getIdServico() != null) {
				this.vincularServicoIncidenteRequisicao(request, idServicoNegocio, servicoDTO);

				return servicoDTO;
			}
		}

		return null;
	}

	private void vincularServicoIncidenteRequisicao(HttpServletRequest request, Integer idServicoNegocio, ServicoDTO servicoRelacionar) throws Exception {
		ServicoAutoRelacionamentoDTO servicoAutoRelacionamentoDTO = new ServicoAutoRelacionamentoDTO();

		Reflexao.copyPropertyValues(servicoRelacionar, servicoAutoRelacionamentoDTO);
		servicoAutoRelacionamentoDTO.setIdServicoRelacionado(idServicoNegocio);
		servicoAutoRelacionamentoDTO.setDataInicio(UtilDatas.getDataAtual());

		servicoAutoRelacionamentoDTO = this.getServicoAutoRelacionamentoService().create(servicoAutoRelacionamentoDTO);
		
		if (servicoAutoRelacionamentoDTO != null && servicoAutoRelacionamentoDTO.getIdServicoAutoRelacionamento() != null) {
			// Auditoria
			String categoriaServico;
			String tipoServico;
			
			if(ServiceDemandType.INCIDENT.getId().equals(servicoRelacionar.getIdTipoDemandaServico())) {
				categoriaServico = OcorrenciaServicoCategorias.INCIDENTES.getIdentificador();
				tipoServico = TipoServico.SERVICO_INCIDENTE.getIdentificador();
			} else {
				categoriaServico = OcorrenciaServicoCategorias.REQUISICAO_SERVICOS.getIdentificador();
				tipoServico = TipoServico.SERVICO_REQUISICAO.getIdentificador();
			}
			
			OcorrenciaServicoDTO ocorrenciaServicoDTO = this.createAuditoriaAutomatica(idServicoNegocio, categoriaServico, request);
			getOcorrenciaServicoRelacionadoService().createOcorrenciaServicoRelacionado(ocorrenciaServicoDTO.getIdOcorrenciaServico(), Util.listStrToListInteger(servicoRelacionar.getIdServico().toString()), AuditoriaAcoes.IMPORTADO.getIdentificador(),
					tipoServico);
		}
	}
	
	private OcorrenciaServicoDTO createAuditoriaAutomatica(Integer idServico, String categoriaOcorrencia, HttpServletRequest request) throws Exception {
		OcorrenciaServicoDTO ocorrenciaServicoDTO = new OcorrenciaServicoDTO();

		ocorrenciaServicoDTO.setIdServico(idServico);
		ocorrenciaServicoDTO.setTipoOcorrencia(AuditoriaTipos.AUTOMATICO.getIdentificador());
		ocorrenciaServicoDTO.setCategoriaOcorrencia(categoriaOcorrencia);
		ocorrenciaServicoDTO.setDataCriacao(UtilDatas.getDataHoraAtual());
		ocorrenciaServicoDTO.setNomeUsuario(WebUtil.getUsuario(request).getNomeUsuario());

		ocorrenciaServicoDTO = getOcorrenciaServicoService().create(ocorrenciaServicoDTO);

		return ocorrenciaServicoDTO;
	}

	@Override
	protected CrudDAO getDao() {
		// TODO Auto-generated method stub
		return null;
	}

	private PortfolioServicoService getPortfolioServicoService() throws ServiceException {
		if (portfolioServicoService == null) {
			portfolioServicoService = (PortfolioServicoService) ServiceLocator.getInstance().getService(PortfolioServicoService.class, null);
		}
		return portfolioServicoService;
	}

	private ServicoService getServicoService() throws ServiceException {
		if (servicoService == null) {
			servicoService = (ServicoService) ServiceLocator.getInstance().getService(ServicoService.class, null);
		}
		return servicoService;
	}

	private ServicoAutoRelacionamentoService getServicoAutoRelacionamentoService() throws ServiceException {
		if (servicoAutoRelacionamentoService == null) {
			servicoAutoRelacionamentoService = (ServicoAutoRelacionamentoService) ServiceLocator.getInstance().getService(ServicoAutoRelacionamentoService.class, null);
		}
		return servicoAutoRelacionamentoService;
	}

	private CategoriaServicoService getCategoriaServicoService() throws ServiceException {
		if (categoriaServicoService == null) {
			categoriaServicoService = (CategoriaServicoService) ServiceLocator.getInstance().getService(CategoriaServicoService.class, null);
		}

		return categoriaServicoService;
	}
	
	private OcorrenciaServicoService getOcorrenciaServicoService() throws ServiceException {
		if (ocorrenciaServicoService == null) {
			ocorrenciaServicoService = (OcorrenciaServicoService) ServiceLocator.getInstance().getService(OcorrenciaServicoService.class, null);
		}
		return ocorrenciaServicoService;
	}

	private OcorrenciaServicoDetalhesService getOcorrenciaServicoDetalhesService() throws ServiceException {
		if (ocorrenciaServicoDetalhesService == null) {
			ocorrenciaServicoDetalhesService = (OcorrenciaServicoDetalhesService) ServiceLocator.getInstance().getService(OcorrenciaServicoDetalhesService.class, null);
		}
		return ocorrenciaServicoDetalhesService;
	}
	
	private OcorrenciaServicoRelacionadoService getOcorrenciaServicoRelacionadoService() throws ServiceException {
		if (ocorrenciaServicoRelacionadoService == null) {
			ocorrenciaServicoRelacionadoService = (OcorrenciaServicoRelacionadoService) ServiceLocator.getInstance().getService(OcorrenciaServicoRelacionadoService.class, null);
		}
		return ocorrenciaServicoRelacionadoService;
	}
}
