package com.rjconsultores.ventaboletos.utilerias.exportacaofiscal;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.utilerias.MoneyHelper;
import com.rjconsultores.ventaboletos.utilerias.UtiliteriasFiscal;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoCCF;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoCFC;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoICF;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoECFTipoPRC;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoBPS;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoDBP;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoPAR;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoRMD;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoSeqBPS;
import com.rjconsultores.ventaboletos.utilerias.exportacaofiscal.vo.ExportacaoRMDTipoSeqDBP;

@Service("exportacaoFiscal")
public class ExportacaoFiscal {
	private static final Logger log = LogManager.getLogger(ExportacaoFiscal.class);
	
	private static String VAZIO = "";
	private static String SEPARADOR = "|";
	
	public ExportacaoFiscal() {
		
	}

	public File gerarArquivoECF(final List<String> tempos, String nomeArquivo, final Date dataInicial, final Date dataFinal, final String estado, final String nomeEmpresa, final List<ExportacaoECFTipoCFC> listaRegistroECFTipoCFC, 
			final List<ExportacaoECFTipoCCF> listaRegistroECFTipoCCF, final List<ExportacaoECFTipoICF> listaRegistroECFTipoICF, final List<ExportacaoECFTipoPRC> listaRegistroECFTipoPRC) {
		try {
//			String nomeArquivo = "fiscal_vendas_impressas_" + DateUtil.getStringDate(Calendar.getInstance().getTime(), "yyyyMMddhhmmss");

			File arquivo = File.createTempFile(nomeArquivo + "-", ".fs");

			PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(arquivo), Constantes.UTF_8));

//			for (String tempo : tempos) {
//				writer.print("-- " + tempo + UtiliteriasFiscal.QUEBRA_LINHA);
//			}

			adicionarRegistroECFTipoCAB(writer, dataInicial, dataFinal, nomeEmpresa, nomeArquivo);
//			adicionarRegistroECFTipoCFC(writer, listaRegistroECFTipoCFC);
//			adicionarRegistroECFTipoCCF(writer, listaRegistroECFTipoCCF);
//			adicionarRegistroECFTipoICF(writer, listaRegistroECFTipoICF);
//			adicionarRegistroECFTipoPRC(writer, listaRegistroECFTipoPRC);
			adicionarRegistroECF(writer, listaRegistroECFTipoCFC, listaRegistroECFTipoCCF, listaRegistroECFTipoICF, listaRegistroECFTipoPRC);
			
			writer.close();
			
			return arquivo;

		} catch (IOException e) {
			log.error( e.getMessage(), e);
		}

		return null;
	}
	
	private void adicionarRegistroECFTipoCAB(final PrintWriter writer, final Date dataInicial, final Date dataFinal, final String nomeEmpresa, final String arquivo) {
		StringBuilder sb = new StringBuilder();
		sb.append("CAB").append(SEPARADOR);
		sb.append("116").append(SEPARADOR);
		sb.append("TotalBus").append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(new Date())).append(SEPARADOR);
		sb.append(formataCaracter(nomeEmpresa, false, 15)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataInicial)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataFinal)).append(SEPARADOR);
		sb.append(arquivo).append(SEPARADOR);
		sb.append("N");
		
		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}

//	@SuppressWarnings("unused")
//	private void adicionarRegistroECFTipoCFC(PrintWriter writer, final List<ExportacaoECFTipoCFC> listaRegistroECFTipoCFC) {
//		for (ExportacaoECFTipoCFC registro : listaRegistroECFTipoCFC) {
//			adicionarLinhaCFC(writer, registro);
//		}
//	}
//
//	@SuppressWarnings("unused")
//	private void adicionarRegistroECFTipoCCF(PrintWriter writer, final List<ExportacaoECFTipoCCF> listaRegistroECFTipoCCF) {
//		for (ExportacaoECFTipoCCF registro : listaRegistroECFTipoCCF) {
//			adicionarLinhaCCF(writer, registro);
//		}
//	}
//	
//	@SuppressWarnings("unused")
//	private void adicionarRegistroECFTipoICF(PrintWriter writer, final List<ExportacaoECFTipoICF> listaRegistroECFTipoICF) {
//		for (ExportacaoECFTipoICF registro : listaRegistroECFTipoICF) {
//			adicionarLinhaICF(writer, registro);
//		}
//	}
//
//	@SuppressWarnings("unused")
//	private void adicionarRegistroECFTipoPRC(PrintWriter writer, final List<ExportacaoECFTipoPRC> listaRegistroECFTipoPRC) {
//		for (ExportacaoECFTipoPRC registro : listaRegistroECFTipoPRC) {
//			adicionarLinhaPRC(writer, registro);
//		}
//	}
	
	private void adicionarRegistroECF(PrintWriter writer, final List<ExportacaoECFTipoCFC> listaRegistroECFTipoCFC, final List<ExportacaoECFTipoCCF> listaRegistroECFTipoCCF, 
			List<ExportacaoECFTipoICF> listaRegistroECFTipoICF, List<ExportacaoECFTipoPRC> listaRegistroECFTipoPRC) {
		Map<String, List<ExportacaoECFTipoCCF>> groupCCF = new HashMap<String, List<ExportacaoECFTipoCCF>>(); 
		Map<String, List<ExportacaoECFTipoICF>> groupICF = new HashMap<String, List<ExportacaoECFTipoICF>>(); 
		Map<String, List<ExportacaoECFTipoPRC>> groupPRC = new HashMap<String, List<ExportacaoECFTipoPRC>>(); 

		List<ExportacaoECFTipoCCF> itensCCF = new ArrayList<ExportacaoECFTipoCCF>();
		List<ExportacaoECFTipoICF> itensICF = new ArrayList<ExportacaoECFTipoICF>();
		List<ExportacaoECFTipoPRC> itensPRC = new ArrayList<ExportacaoECFTipoPRC>();
		
		for (ExportacaoECFTipoCCF registro : listaRegistroECFTipoCCF) {
			itensCCF = new ArrayList<ExportacaoECFTipoCCF>();
			
			if (groupCCF.containsKey(registro.getEcf() + "|" + registro.getDataEmissao())) {
				itensCCF.addAll(groupCCF.get(registro.getEcf() + "|" + registro.getDataEmissao()));
			}
			
			itensCCF.add(registro);
			
			groupCCF.put(registro.getEcf() + "|" + registro.getDataEmissao(), itensCCF);
		}
		
		for (ExportacaoECFTipoICF registro : listaRegistroECFTipoICF) {
			itensICF = new ArrayList<ExportacaoECFTipoICF>();
			
			if (groupICF.containsKey(registro.getEcf() + "|" + registro.getDataEmissao())) {
				itensICF.addAll(groupICF.get(registro.getEcf() + "|" + registro.getDataEmissao()));
			}
			
			itensICF.add(registro);
			
			groupICF.put(registro.getEcf() + "|" + registro.getDataEmissao(), itensICF);
		}
		
		for (ExportacaoECFTipoPRC registro : listaRegistroECFTipoPRC) {
			itensPRC = new ArrayList<ExportacaoECFTipoPRC>();
			
			if (groupPRC.containsKey(registro.getEcf() + "|" + registro.getDataEmissao())) {
				itensPRC.addAll(groupPRC.get(registro.getEcf() + "|" + registro.getDataEmissao()));
			}
			
			itensPRC.add(registro);
			
			groupPRC.put(registro.getEcf() + "|" + registro.getDataEmissao(), itensPRC);
		}
		
		int linhas = 2;
		
		Map<String, BigDecimal> valoresBaseCalculoICMS = new HashMap<String, BigDecimal>(0); 
		
		Map<Integer, BigDecimal> totalBaseCalculoICMS = new HashMap<Integer, BigDecimal>(0); 
		
		for (ExportacaoECFTipoCFC registro : listaRegistroECFTipoCFC) {
			adicionarLinhaCFC(writer, registro);
			
			linhas++;

			if (registro.getEstabelecimentoECF() == null) {
				log.info("- Estabelecimento da ECF indefinido para a ECF [" + registro.getEcf() + "]");
			}

			if (registro.getNumeroIdentificacaoECF() == null) {
				log.info("- número de Identificaçãoo da ECF indefinido para a ECF [" + registro.getEcf() + "]");
			}
			
			itensCCF = groupCCF.get(registro.getEcf() + "|" + registro.getDataEmissao());
			
			totalBaseCalculoICMS.clear();
			valoresBaseCalculoICMS.clear();
			
			if (itensCCF != null) {
				for (ExportacaoECFTipoCCF itemCCF : itensCCF) {
					BigDecimal baseCalculoICMS = BigDecimal.ZERO;
					BigDecimal valorBaseCalculoICMS = itemCCF.getValorBaseCalculoICMS() == null ? BigDecimal.ZERO : itemCCF.getValorBaseCalculoICMS();
					
					String key = itemCCF.getEcf() + "|" + itemCCF.getUfDestino() + "|" + itemCCF.getMunicipioOrigem();
					
					if (valoresBaseCalculoICMS.containsKey(key)) {
						baseCalculoICMS = valoresBaseCalculoICMS.get(key);
					}
					
					baseCalculoICMS = baseCalculoICMS.add(valorBaseCalculoICMS.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					
					valoresBaseCalculoICMS.put(key, baseCalculoICMS);
					
					adicionarLinhaCCF(writer, itemCCF);
					
					linhas++;
					
					BigDecimal valor = BigDecimal.ZERO;
					
					if (totalBaseCalculoICMS.containsKey(itemCCF.getMunicipioOrigem())) {
						valor = totalBaseCalculoICMS.get(itemCCF.getMunicipioOrigem());
					}
					
					valor = valor.add(valorBaseCalculoICMS.setScale(2, BigDecimal.ROUND_HALF_EVEN));
					
					totalBaseCalculoICMS.put(itemCCF.getMunicipioOrigem(), valor);
				}
			}
			
			BigDecimal valorBaseCalculoICMS = BigDecimal.ZERO;
			
			itensICF = groupICF.get(registro.getEcf() + "|" + registro.getDataEmissao());
			
			if (itensICF != null) {
				for (ExportacaoECFTipoICF itemICF : itensICF) {
					valorBaseCalculoICMS = BigDecimal.ZERO;
					
					if (valoresBaseCalculoICMS.containsKey(itemICF.getEcf() + "|" + itemICF.getUfDestino() + "|" + itemICF.getMunicipioOrigem())) {
						valorBaseCalculoICMS = valoresBaseCalculoICMS.get(itemICF.getEcf() + "|" + itemICF.getUfDestino() + "|" + itemICF.getMunicipioOrigem());
					}					
					
					adicionarLinhaICF(writer, itemICF, valorBaseCalculoICMS);
					
					linhas++;
				}
			}
			
			itensPRC = groupPRC.get(registro.getEcf() + "|" + registro.getDataEmissao());
			
			if (itensPRC != null) {
				for (ExportacaoECFTipoPRC itemPRC : itensPRC) {
					adicionarLinhaPRC(writer, itemPRC, totalBaseCalculoICMS);
					
					linhas++;
				}
			}
		}
		
		writer.print("TRA|" + linhas + UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarLinhaCFC(PrintWriter writer, ExportacaoECFTipoCFC registro) {
		String estabelecimento = registro.getEstabelecimento();
		String dataEmissao = registro.getDataEmissao(); 
		String numeroIdentificacaoECF = registro.getNumeroIdentificacaoECF();
		Integer cooReducaoZ = registro.getCooReducaoZ();
		Integer cooInicial = registro.getCooInicial();
		Integer cooFinal = registro.getCooFinal();
		Integer contadorReducao = registro.getContadorReducao();
		Integer cro = registro.getCro();
		BigDecimal valorTotal = registro.getValorTotal();
		BigDecimal valorIsentas = registro.getValorIsentas();
		String estabelecimentoECF = registro.getEstabelecimentoECF();
		String infoPadraoBilhetePassagem = registro.getInfoPadraoBilhetePassagem();
		String numeroSerie = registro.getNumeroSerie(); 
		
		StringBuilder sb = new StringBuilder();
		sb.append("CFC").append(SEPARADOR);
		sb.append(formataCaracter(estabelecimento, false, 4)).append(SEPARADOR);
		sb.append(formataCaracter(dataEmissao, true, 8)).append(SEPARADOR);
		sb.append(formataCaracter(numeroIdentificacaoECF, false, 3)).append(SEPARADOR);
		sb.append(formataNumerico(cooReducaoZ, true, 6)).append(SEPARADOR);
		sb.append(formataNumerico(cooInicial, true, 6)).append(SEPARADOR);
		sb.append(formataNumerico(cooFinal, true, 6)).append(SEPARADOR);
		sb.append(formataNumerico(contadorReducao, true, 6)).append(SEPARADOR);
		sb.append(formataNumerico(cro, true, 6)).append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 12
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 13
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 14
		sb.append(formataValor(valorIsentas, 15)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 16
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 17
		sb.append("N").append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 25)).append(SEPARADOR); // Posição 19
		sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 20
		sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 21
		sb.append(formataCaracter(VAZIO, false, 6)).append(SEPARADOR); // Posição 22
		sb.append(formataCaracter(VAZIO, false, 2)).append(SEPARADOR); // Posição 23
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 26
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 27
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 28
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 29
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 30
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 31
		sb.append("").append(SEPARADOR); // Posição 32
		sb.append("V").append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 34
		sb.append(formataCaracter(estabelecimentoECF, false, 4)).append(SEPARADOR);
		sb.append(formataCaracter(infoPadraoBilhetePassagem, false, 8));
		/*sb.append(formataCaracter(numeroSerie, false, 6))*/;

		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarLinhaCCF(PrintWriter writer, ExportacaoECFTipoCCF item) {
		Integer coo = item.getCoo();
		BigDecimal valorServico = item.getValorServico(); 
		BigDecimal descontoGlobal = item.getDescontoGlobal();
		Integer codigoParticipante = item.getCodigoParticipante();
		Integer situacaoCOO = item.getSituacaoCOO(); // 0 - Documento Regular; 2 - Documento Cancelado
		BigDecimal acrescimo = item.getAcrescimo();
		String ufOrigem = item.getUfOrigem();
		String municipioOrigem = item.getMunicipioOrigem() == null ? null : item.getMunicipioOrigem().toString();
		String ufDestino = item.getUfDestino();
		Integer cfop = item.getCfop(); // IM=5357; serviço IE= 6357
		Integer codigoSituacaoTribColunaB = item.getCodigoSituacaoTribColunaB(); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
		BigDecimal valorTotal = item.getValorTotal(); 
		Integer tributacaoICMS = item.getTributacaoICMS(); // 1 - Demais; 2 - Região Metropolitanao ou seja, quando o campo CSTB for "40", esse campo deve vir "2". Do contrário, deve vir "1"
		BigDecimal valorBaseCalculoICMS = item.getValorBaseCalculoICMS(); 
		BigDecimal aliquotaICMS = item.getAliquotaICMS();
		String numFolioSistema = item.getNumFolioSistema();
		
		if (municipioOrigem != null && municipioOrigem.length() > 5) {
			municipioOrigem = municipioOrigem.substring(municipioOrigem.length() - 5, municipioOrigem.length());
		}
		
		StringBuilder sb = new StringBuilder();
		sb.append("CCF").append(SEPARADOR);
		sb.append(formataNumerico(coo, true, 6)).append(SEPARADOR);
		sb.append(formataValor(valorServico, 15)).append(SEPARADOR);
		sb.append(descontoGlobal == null ? "" : formataValor(descontoGlobal, 15)).append(SEPARADOR);
		sb.append(codigoParticipante == null ? "" : formataNumerico(codigoParticipante, true, 15)).append(SEPARADOR);
		sb.append(formataNumerico(situacaoCOO, true, 1)).append(SEPARADOR);
		sb.append(acrescimo == null ? "" : formataValor(acrescimo, 15)).append(SEPARADOR);
		sb.append(formataCaracter(ufOrigem, true, 2)).append(SEPARADOR);
		sb.append(formataNumerico(municipioOrigem, true, 5)).append(SEPARADOR);
		sb.append(formataCaracter(ufDestino, true, 2)).append(SEPARADOR);
		sb.append(formataNumerico(cfop, true, 4)).append(SEPARADOR);
		sb.append("0").append(SEPARADOR);
		sb.append(codigoSituacaoTribColunaB == 0 ? "00" : formataNumerico(codigoSituacaoTribColunaB, true, 2)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 1)).append(SEPARADOR); // Posição 14
		sb.append(formataCaracter(VAZIO, false, 1)).append(SEPARADOR); // Posição 15
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataNumerico(tributacaoICMS, true, 1)).append(SEPARADOR);
		sb.append(valorBaseCalculoICMS == null ? "" : formataValor(valorBaseCalculoICMS, 15)).append(SEPARADOR);
		sb.append(formataValor(aliquotaICMS, 5)).append(SEPARADOR);
		sb.append("01").append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 5)).append(SEPARADOR); // Posição 22
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 23
		sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 24
		sb.append("01").append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 5)).append(SEPARADOR); // Posição 27
		sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 28
		sb.append(formataCaracter(VAZIO, false, 3)); // Posição 29

		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarLinhaICF(PrintWriter writer, ExportacaoECFTipoICF item, BigDecimal valorBaseCalculoICMS) {
		BigDecimal valorTotal = item.getValorTotal();
		String ufDestino = item.getUfDestino();
		Integer cfop = item.getCfop(); // IM=5357; serviço IE= 6357
		// BigDecimal valorBaseCalculoICMS = item.getValorBaseCalculoICMS();
		BigDecimal aliquotaICMS = item.getAliquotaICMS();
		BigDecimal valorICMSIsento = item.getValorICMSIsento();
		// BigDecimal valorICMSOutros = item.getValorICMSOutros();

		// BigDecimal valorICMSDebitado = item.getValorICMSDebitado();
		BigDecimal valorICMSDebitado = BigDecimal.ZERO;
		if (item.getAliquotaICMS() != null) {
			BigDecimal aTributacao_importacao = MoneyHelper.dividir(item.getAliquotaICMS(), BigDecimal.valueOf(100d));
			valorICMSDebitado = MoneyHelper.multiplicar(valorBaseCalculoICMS, aTributacao_importacao);
		}

		BigDecimal difValorTotalICMS = valorTotal.subtract(valorBaseCalculoICMS);

		Integer codigoSituacaoTribColunaB = item.getCodigoSituacaoTribColunaB(); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
		String ufOrigem = item.getUfOrigem();
		String municipioOrigem = item.getMunicipioOrigem() == null ? null : item.getMunicipioOrigem().toString();

		if (municipioOrigem != null && municipioOrigem.length() > 5) {
			municipioOrigem = municipioOrigem.substring(municipioOrigem.length() - 5, municipioOrigem.length());
		}

		if (item.getRedutorBaseCalculoIcms() == null) {
			valorBaseCalculoICMS = valorTotal;
		}
		
		StringBuilder sb = new StringBuilder();
		sb.append("ICF").append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataCaracter(ufDestino, true, 2)).append(SEPARADOR);
		sb.append(formataNumerico(cfop, true, 4)).append(SEPARADOR);
		sb.append(formataValor(valorBaseCalculoICMS, 15)).append(SEPARADOR);
		sb.append(formataValor(aliquotaICMS, 5)).append(SEPARADOR);
		sb.append(formataValor(valorICMSDebitado, 15)).append(SEPARADOR);
		sb.append(formataValor(valorICMSIsento, 15)).append(SEPARADOR);
		sb.append(formataValor(difValorTotalICMS, 15)).append(SEPARADOR);
		sb.append("N").append(SEPARADOR);
		sb.append("N").append(SEPARADOR);
		sb.append("N").append(SEPARADOR);
		sb.append("0").append(SEPARADOR);
		sb.append(codigoSituacaoTribColunaB == 0 ? "00" : formataNumerico(codigoSituacaoTribColunaB, true, 2)).append(SEPARADOR);
		sb.append(formataCaracter(VAZIO, false, 1)).append(SEPARADOR); // Posição 15
		sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 16
		sb.append("N").append(SEPARADOR);
		sb.append("N").append(SEPARADOR);
		sb.append(formataCaracter(ufOrigem, true, 2)).append(SEPARADOR);
		sb.append(formataNumerico(municipioOrigem, true, 5));
		
		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarLinhaPRC(PrintWriter writer, ExportacaoECFTipoPRC item, Map<Integer, BigDecimal> totalBaseCalculoICMS) {
		String ufOrigem = item.getUfOrigem();
		String municipioOrigem = item.getMunicipioOrigem() == null ? null : item.getMunicipioOrigem().toString();
		BigDecimal valorTotal = item.getValorTotal();
		BigDecimal valorBaseCalculoICMS = totalBaseCalculoICMS.containsKey(item.getMunicipioOrigem()) ? totalBaseCalculoICMS.get(item.getMunicipioOrigem()) : item.getValorBaseCalculoICMS();
		BigDecimal valorICMS = BigDecimal.ZERO;
		// BigDecimal valorICMS = item.getValorICMS();

		if (municipioOrigem != null && municipioOrigem.length() > 5) {
			municipioOrigem = municipioOrigem.substring(municipioOrigem.length() - 5, municipioOrigem.length());
		}

		if (item.getTributacao() != null && item.getTributacao().compareTo(BigDecimal.ZERO) > 0) {
			valorICMS = MoneyHelper.multiplicar(valorBaseCalculoICMS, item.getTributacao());
		}

		StringBuilder sb = new StringBuilder();
		sb.append("PRC").append(SEPARADOR);
		sb.append(formataCaracter(ufOrigem, true, 2)).append(SEPARADOR);
		sb.append(formataNumerico(municipioOrigem, true, 5)).append(SEPARADOR);
		sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
		sb.append(formataValor(valorBaseCalculoICMS, 15)).append(SEPARADOR);
		sb.append(formataValor(valorICMS, 15));
		
		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}
	
	public File gerarArquivoRMD(final Date dataInicial, final Date dataFinal, String nomeArquivo, final String nomeEmpresa, List<ExportacaoRMDTipoPAR> listaRegistroRMDTipoPAR, 
			List<ExportacaoRMDTipoRMD> listaRegistroRMDTipoRMD, List<ExportacaoRMDTipoBPS> listaRegistroRMDTipoBPS, List<ExportacaoRMDTipoDBP> listaRegistroRMDTipoDBP,
			List<ExportacaoRMDTipoSeqBPS> listaRegistroRMDTipoSeqBPS) {
		try {
//			String nomeArquivo = "fiscal_vendas_manual_" + DateUtil.getStringDate(Calendar.getInstance().getTime(), "yyyyMMddhhmmss");

			File arquivo = File.createTempFile(nomeArquivo + "-", ".fs");

			PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(arquivo), Constantes.UTF_8));

			adicionarRegistroRMDTipoCAB(writer, dataInicial, dataFinal, nomeEmpresa, nomeArquivo);
			adicionarRegistroRMDTipoPAR(writer, listaRegistroRMDTipoPAR);
			adicionarRegistroRMDTipoRMD(writer, listaRegistroRMDTipoRMD);
//			adicionarRegistroRMDTipoBPS(writer, listaRegistroRMDTipoBPS);
//			adicionarRegistroRMDTipoDBP(writer, listaRegistroRMDTipoDBP);
			adicionarRegistroRMDTipoSeqBPS(writer, listaRegistroRMDTipoSeqBPS);
			
			int linhas = listaRegistroRMDTipoPAR.size() + listaRegistroRMDTipoRMD.size() + 1 + 1;

			for (ExportacaoRMDTipoSeqBPS seq : listaRegistroRMDTipoSeqBPS) {
				linhas++;
				
				linhas = linhas + seq.getListaDBP().size(); 
			}
			
			writer.print("TRA|" + linhas + UtiliteriasFiscal.QUEBRA_LINHA);
			
			writer.close();

			return arquivo;

		} catch (IOException e) {
			log.error( e.getMessage(), e);
		}

		return null;
	}
	
	private void adicionarRegistroRMDTipoCAB(PrintWriter writer, Date dataInicial, Date dataFinal, String nomeEmpresa, String nomeArquivo) {
		StringBuilder sb = new StringBuilder();
		sb.append("CAB").append(SEPARADOR);
		sb.append("116").append(SEPARADOR);
		sb.append("TotalBus").append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(new Date())).append(SEPARADOR);
		sb.append(formataCaracter(nomeEmpresa, false, 15)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataInicial)).append(SEPARADOR);
		sb.append(new SimpleDateFormat("yyyyMMdd").format(dataFinal)).append(SEPARADOR);
		sb.append(nomeArquivo).append(SEPARADOR);
		sb.append("N");
		
		writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
	}

	private void adicionarRegistroRMDTipoPAR(PrintWriter writer, List<ExportacaoRMDTipoPAR> listaRegistroRMDTipoPAR) {
		for (ExportacaoRMDTipoPAR registro : listaRegistroRMDTipoPAR) {
			Integer codigoParticipante = registro.getCodigoParticipante();
			Integer codigoEstabelecimento = registro.getCodigoEstabelecimento();
			String nomeParticipante = registro.getNomeParticipante();
			String ufParticipante = registro.getUfParticipante();
			String cpfParticipante = registro.getCpfParticipante();
			String ieParticipante = registro.getIeParticipante();
			String logradouro = registro.getLogradouro();
			String numero = registro.getNumero();
			String complemento = registro.getComplemento();
			String bairro = registro.getBairro();
			Integer cep = registro.getCep();

			StringBuilder sb = new StringBuilder();
			sb.append("PAR").append(SEPARADOR);
			sb.append(formataNumerico(codigoEstabelecimento, true, 9)).append(SEPARADOR);
			sb.append(formataCaracter(nomeParticipante, false, 60)).append(SEPARADOR);
			sb.append(formataCaracter(ufParticipante, false, 2)).append(SEPARADOR);
			sb.append(formataCaracter(cpfParticipante, true, 14)).append(SEPARADOR);
			sb.append(formataCaracter(ieParticipante, true, 14)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 20)).append(SEPARADOR); // Posição 7
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("0").append(SEPARADOR);
			sb.append(formataCaracter(logradouro, false, 60)).append(SEPARADOR);
			sb.append(formataNumerico(numero, true, 6)).append(SEPARADOR);
			sb.append(formataCaracter(complemento, false, 60)).append(SEPARADOR);
			sb.append("0").append(SEPARADOR);
			sb.append(formataCaracter(bairro, false, 50)).append(SEPARADOR);
			sb.append(formataNumerico(cep, true, 8)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 5)).append(SEPARADOR); // Posição 23
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 24
			sb.append(formataCaracter(VAZIO, false, 9)).append(SEPARADOR); // Posição 25
			sb.append(formataCaracter(VAZIO, false, 14)).append(SEPARADOR); // Posição 26
			sb.append("N").append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 28
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 29
			sb.append("1058").append(SEPARADOR);
			sb.append("N").append(SEPARADOR);
			sb.append("1").append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 60)).append(SEPARADOR); // Posição 33
			sb.append("N").append(SEPARADOR); // Posição 34
			sb.append("N").append(SEPARADOR); // Posição 35
			sb.append(formataCaracter(VAZIO, false, 7)); // Posição 36
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
		}
	}

	private void adicionarRegistroRMDTipoRMD(PrintWriter writer, List<ExportacaoRMDTipoRMD> listaRegistroRMDTipoRMD) {
		for (ExportacaoRMDTipoRMD registro : listaRegistroRMDTipoRMD) {
			Integer codigoEstabelecimento = registro.getCodigoEstabelecimento();
			String numeroAIDF = registro.getNumeroAIDF();
			String serieAIDF = registro.getSerieAIDF();
			String subSerieAIDF = registro.getSubSerieAIDF();
			Long numeroBilheteAIDF = registro.getNumeroBilheteAIDF();
			Long numeroFormularioAIDF = registro.getNumeroFormularioAIDF();
			String dataEmissao = registro.getDataEmissao();
			Boolean cancelado = registro.getCancelado();
			// Integer codigoParticipante = registro.getCodigoParticipante();
			String codigoContabil = registro.getCodigoContabil();

			StringBuilder sb = new StringBuilder();
			sb.append("RMD").append(SEPARADOR);
			// sb.append(String.format("%04d", cancelado ? codigoParticipante : codigoEstabelecimento)).append(SEPARADOR);
			sb.append(String.format("%04d", codigoEstabelecimento)).append(SEPARADOR);
			sb.append(formataNumerico(numeroAIDF, true, 25)).append(SEPARADOR);
			sb.append(formataCaracter(serieAIDF, false, 3)).append(SEPARADOR);
			sb.append(formataCaracter(subSerieAIDF, false, 3)).append(SEPARADOR);
			sb.append(String.format("%06d", numeroBilheteAIDF)).append(SEPARADOR);
			sb.append(String.format("%06d", numeroFormularioAIDF)).append(SEPARADOR);
			sb.append(formataCaracter(dataEmissao, false, 6)).append(SEPARADOR);
			sb.append(cancelado ? "S" : "N").append(SEPARADOR);
			sb.append("").append(SEPARADOR); // Posição 10
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 11
			sb.append(formataCaracter(VAZIO, false, 4)).append(SEPARADOR); // Posição 12
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 13
			sb.append(formataCaracter(VAZIO, false, 5)).append(SEPARADOR); // Posição 14
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 15
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 16
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 17
			sb.append(cancelado ? "" : formataNumerico(codigoEstabelecimento, true, 9)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 19
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 20
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 21
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 22
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 23
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 24
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 25
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 26
			sb.append(cancelado ? "" : "01").append(SEPARADOR);
			sb.append(cancelado ? "" : "01").append(SEPARADOR);
			sb.append(formataCaracter(codigoContabil, false, 15)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 9)).append(SEPARADOR); // Posição 30
			sb.append(formataCaracter(VAZIO, false, 9)).append(SEPARADOR); // Posição 31
			sb.append(formataCaracter(VAZIO, false, 9)).append(SEPARADOR); // Posição 32
			sb.append(formataCaracter(VAZIO, false, 8)).append(SEPARADOR); // Posição 33
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 34
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 35
			sb.append(formataCaracter("N", false, 3)); // Posição 36
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
		}
	}

	@Deprecated
	private void adicionarRegistroRMDTipoBPS(PrintWriter writer, List<ExportacaoRMDTipoBPS> listaRegistroRMDTipoBPS) {
		for (ExportacaoRMDTipoBPS registro : listaRegistroRMDTipoBPS) {
			Integer codigoEstabelecimento = registro.getCodigoEstabelecimento();
			String especie = registro.getEspecie();
			Long numeroAIDF = registro.getNumeroAIDF();
			String serieAIDF = registro.getSerieAIDF();
			String subSerieAIDF = registro.getSubSerieAIDF();
			Long numeroInicial = registro.getNumeroInicial();
			Long numeroFinal = registro.getNumeroFinal();
			Integer quantidadeCancelados = registro.getQuantidadeCancelados();
			String dataEmissao = registro.getDataEmissao();
			BigDecimal valorTotal = registro.getValorTotal(); 
			Boolean resumoMovimentoDiario = registro.getResumoMovimentoDiario();
			Long numeroAIDFRMD = registro.getNumeroAIDFRMD();
			String serieAIDFRMD = registro.getSerieAIDFRMD();
			String subSerieAIDFRMD = registro.getSubSerieAIDFRMD();
			Integer numeroRMD = registro.getNumeroRMD();
			
			StringBuilder sb = new StringBuilder();
			sb.append("BPS").append(SEPARADOR);
			sb.append(String.format("%04d", codigoEstabelecimento)).append(SEPARADOR);
			sb.append(formataCaracter(especie, false, 5)).append(SEPARADOR);
			sb.append(formataNumerico(numeroAIDF, true, 25)).append(SEPARADOR);
			sb.append(formataCaracter(serieAIDF, false, 3)).append(SEPARADOR);
			sb.append(formataCaracter(subSerieAIDF, false, 3)).append(SEPARADOR);
			sb.append(formataNumerico(numeroInicial, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(numeroFinal, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(quantidadeCancelados, true, 9)).append(SEPARADOR);
			sb.append(formataNumerico(numeroInicial, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(numeroFinal, true, 6)).append(SEPARADOR);
			sb.append(formataCaracter(dataEmissao, true, 8)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(resumoMovimentoDiario == null ? "" : resumoMovimentoDiario ? "S" : "N").append(SEPARADOR);
			sb.append(formataNumerico(numeroAIDFRMD, true, 25)).append(SEPARADOR);
			sb.append(formataCaracter(serieAIDFRMD, false, 3)).append(SEPARADOR);
			sb.append(formataCaracter(subSerieAIDFRMD, false, 3)).append(SEPARADOR);
			sb.append(formataNumerico(numeroRMD, true, 6)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 21
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 22
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 23
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 24
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 25
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 26
			sb.append("").append(SEPARADOR); // Posição 27
			sb.append("01").append(SEPARADOR);
			sb.append("01").append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 30
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 31
			sb.append(formataCaracter(VAZIO, false, 8)); // Posição 32
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
		}
	}

	@Deprecated
	private void adicionarRegistroRMDTipoDBP(PrintWriter writer, List<ExportacaoRMDTipoDBP> listaRegistroRMDTipoDBP) {
		for (ExportacaoRMDTipoDBP registro : listaRegistroRMDTipoDBP) {
			String ufDestino = registro.getUfDestino();
			Integer cfop = registro.getCfop(); // IM=5357; serviço IE= 6357
			BigDecimal valorTotal = registro.getValorTotal(); 
			BigDecimal valorBaseCalculoICMS = registro.getValorBaseCalculoICMS(); 
			BigDecimal aliquotaICMS = registro.getAliquotaICMS();
			BigDecimal valorICMS = registro.getValorICMS(); 
			BigDecimal valorICMSIsento = registro.getValorICMSIsento(); 
			BigDecimal valorICMSOutros = registro.getValorICMSOutros(); 
			Integer codigoSituacaoTribColunaB = registro.getCodigoSituacaoTribColunaB(); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			String ufOrigem = registro.getUfOrigem();
			Integer municipioestadoOrigem = registro.getMunicipioOrigem();
			
			String municipioOrigem = municipioestadoOrigem.toString();
			
			if (municipioOrigem.length() > 5) {
				municipioOrigem = municipioOrigem.substring(municipioOrigem.length() - 5, municipioOrigem.length());
			}

			StringBuilder sb = new StringBuilder();
			sb.append("DBP").append(SEPARADOR);
			sb.append(formataCaracter(ufDestino, true, 2)).append(SEPARADOR);
			sb.append(formataNumerico(cfop, true, 4)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataValor(valorBaseCalculoICMS, 15)).append(SEPARADOR);
			sb.append(formataValor(aliquotaICMS, 5)).append(SEPARADOR);
			sb.append(formataValor(valorICMS, 15)).append(SEPARADOR);
			sb.append(formataValor(valorICMSIsento, 15)).append(SEPARADOR);
			sb.append(formataValor(valorICMSOutros, 15)).append(SEPARADOR);
			sb.append(codigoSituacaoTribColunaB == 0 ? "00" : formataNumerico(codigoSituacaoTribColunaB, true, 2)).append(SEPARADOR);
			sb.append(formataCaracter(ufOrigem, true, 2)).append(SEPARADOR);
			sb.append(municipioOrigem).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 3)); // Posição 13
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
		}
	}
	
	private void adicionarRegistroRMDTipoSeqBPS(PrintWriter writer, List<ExportacaoRMDTipoSeqBPS> listaRegistroRMDTipoBPS) {
		for (ExportacaoRMDTipoSeqBPS registro : listaRegistroRMDTipoBPS) {
			Integer codigoEstabelecimento = registro.getCodigoEstabelecimento();
			String especie = registro.getEspecie();
			String numeroAIDF = registro.getNumeroAIDF();
			String serieAIDF = registro.getSerieAIDF();
			String subSerieAIDF = registro.getSubSerieAIDF();
			Long numeroInicial = registro.getNumeroInicial();
			Long numeroFinal = registro.getNumeroFinal();
			Integer quantidadeCancelados = registro.getQuantidadeCancelados();
			String dataEmissao = registro.getDataEmissao();
			BigDecimal valorTotal = registro.getValorTotal(); 
			Boolean resumoMovimentoDiario = registro.getResumoMovimentoDiario();
			String numeroAIDFRMD = registro.getNumeroAIDFRMD();
			String serieAIDFRMD = registro.getSerieAIDFRMD();
			String subSerieAIDFRMD = registro.getSubSerieAIDFRMD();
			Integer numeroRMD = registro.getNumeroRMD();
			String infoPadraoBilhetePassagem = registro.getInfoPadraoBilhetePassagem();

			StringBuilder sb = new StringBuilder();
			sb.append("BPS").append(SEPARADOR);
			sb.append(String.format("%04d", codigoEstabelecimento)).append(SEPARADOR);
			sb.append(formataCaracter(especie, false, 5)).append(SEPARADOR);
			sb.append(formataNumerico(numeroAIDF, true, 25)).append(SEPARADOR);
			sb.append(formataCaracter(serieAIDF, false, 3)).append(SEPARADOR);
			sb.append(formataCaracter(subSerieAIDF, false, 3)).append(SEPARADOR);
			sb.append(formataNumerico(numeroInicial, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(numeroFinal, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(quantidadeCancelados, true, 9)).append(SEPARADOR);
			sb.append(formataNumerico(numeroInicial, true, 6)).append(SEPARADOR);
			sb.append(formataNumerico(numeroFinal, true, 6)).append(SEPARADOR);
			sb.append(formataCaracter(dataEmissao, true, 8)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(resumoMovimentoDiario == null ? "" : resumoMovimentoDiario ? "S" : "N").append(SEPARADOR);
			sb.append(formataNumerico(numeroAIDFRMD, true, 25)).append(SEPARADOR);
			sb.append(formataCaracter(serieAIDFRMD, false, 3)).append(SEPARADOR);
			sb.append(formataCaracter(subSerieAIDFRMD, false, 3)).append(SEPARADOR);
			sb.append(String.format("%06d", numeroRMD)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 21
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 22
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 23
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 24
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 25
			sb.append(formataCaracter(VAZIO, false, 15)).append(SEPARADOR); // Posição 26
			sb.append("").append(SEPARADOR); // Posição 27
			sb.append("01").append(SEPARADOR);
			sb.append("01").append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 30
			sb.append(formataCaracter(VAZIO, false, 3)).append(SEPARADOR); // Posição 31
			sb.append(formataCaracter(infoPadraoBilhetePassagem, false, 8));
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);

			adicionarRegistroRMDTipoSeqDBP(writer, registro.getListaDBP());
		}
	}

	private void adicionarRegistroRMDTipoSeqDBP(PrintWriter writer, List<ExportacaoRMDTipoSeqDBP> listaRegistroRMDTipoDBP) {
		for (ExportacaoRMDTipoSeqDBP registro : listaRegistroRMDTipoDBP) {
			String ufDestino = registro.getUfDestino();
			Integer cfop = registro.getCfop(); // IM=5357; serviço IE= 6357
			BigDecimal valorTotal = registro.getValorTotal(); 
			BigDecimal valorBaseCalculoICMS = registro.getValorBaseCalculoICMS(); 
			BigDecimal aliquotaICMS = registro.getAliquotaICMS();
			BigDecimal valorICMS = registro.getValorICMS(); 
			BigDecimal valorICMSIsento = registro.getValorICMSIsento(); 
//			BigDecimal valorICMSOutros = registro.getValorICMSOutros();
			
			BigDecimal difValorTotalICMS = valorTotal.subtract(valorBaseCalculoICMS);
			
			Integer codigoSituacaoTribColunaB = registro.getCodigoSituacaoTribColunaB(); // 00 - tributação normal; 20 - tributação com redução na base de calculo; 40 - isentos
			String ufOrigem = registro.getUfOrigem();
			Integer municipioestadoOrigem = registro.getMunicipioOrigem();
			
			String municipioOrigem = municipioestadoOrigem.toString();
			
			if (municipioOrigem.length() > 5) {
				municipioOrigem = municipioOrigem.substring(municipioOrigem.length() - 5, municipioOrigem.length());
			}

			StringBuilder sb = new StringBuilder();
			sb.append("DBP").append(SEPARADOR);
			sb.append(formataCaracter(ufDestino, true, 2)).append(SEPARADOR);
			sb.append(formataNumerico(cfop, true, 4)).append(SEPARADOR);
			sb.append(formataValor(valorTotal, 15)).append(SEPARADOR);
			sb.append(formataValor(valorBaseCalculoICMS, 15)).append(SEPARADOR);
			sb.append(formataValor(aliquotaICMS, 5)).append(SEPARADOR);
			sb.append(formataValor(valorICMS, 15)).append(SEPARADOR);
			sb.append(formataValor(valorICMSIsento, 15)).append(SEPARADOR);
			sb.append(formataValor(difValorTotalICMS, 15)).append(SEPARADOR);
			sb.append(codigoSituacaoTribColunaB == 0 ? "00" : formataNumerico(codigoSituacaoTribColunaB, true, 2)).append(SEPARADOR);
			sb.append(formataCaracter(ufOrigem, true, 2)).append(SEPARADOR);
			sb.append(municipioOrigem).append(SEPARADOR);
			sb.append(formataCaracter(VAZIO, false, 3)); // Posição 13
			
			writer.print(sb.toString() + UtiliteriasFiscal.QUEBRA_LINHA);
		}
	}

	private String formataCaracter(String valor, boolean removeMascara, int tamanho) {
		if (valor == null) {
			valor = "";
		} 

//		if (removeMascara) {
//			valor = valor.replace("-", "").replace(".", "").replace("/", "");
//		}
//		
//		if (valor.length() > tamanho) {
//			valor = valor.substring(0, tamanho);
//		}
//		
//		return String.format("%1$-" + tamanho + "s", valor);
		
		return valor;
	}
	
	private String formataNumerico(final String valor, final boolean removeMascara, final int tamanho) {
		String retorno = StringUtils.trim(valor);

		if (retorno == null) {
			retorno = "0";
		}
		
//		if (removeMascara) {
//			retorno = retorno.replace("-", "").replace(".", "").replace("/", "");
//		}
//		
//		retorno = retorno.replace(".", "").replace(",","");
//		
//		if (tamanho > 0) {
//			if (retorno.length() > tamanho) {
//				retorno = retorno.substring(retorno.length() - tamanho, retorno.length());
//			}
//			
//			return StringUtils.leftPad(retorno, tamanho, "0");
//		}
		
		return retorno;
	}	
	
	private String formataNumerico(final Long valor, final boolean removeMascara, final int tamanho) {
//		if (valor == null) {
//			return formataCaracter(" ", true, tamanho);
//		} else {
//			return formataNumerico(valor.toString(), removeMascara, tamanho);
//		}
		if (valor == null) {
			return "0";
		} else {
			return formataNumerico(valor.toString(), removeMascara, tamanho);
		}
	}
	
	private String formataNumerico(final Integer valor, final boolean removeMascara, final int tamanho) {
//		if (valor == null) {
//			return formataCaracter(" ", true, tamanho);
//		} else {
//			return formataNumerico(valor.toString(), removeMascara, tamanho);
//		}
		if (valor == null) {
			return "0";
		} else {
			return formataNumerico(valor.toString(), removeMascara, tamanho);
		}
	}
	
	private String formataValor(final BigDecimal valor, final int tamanho) {
//		if (valor == null) {
//			return formataCaracter(" ", true, tamanho);
//		} else {
//			return formataNumerico(valor.setScale(2).toString(), false, tamanho);
//		}
		if (valor == null) {
			return "0";
		} else {
			return valor.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
		}
	}
}
