Advertisement
Guest User

Untitled

a guest
Jan 25th, 2017
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 40.77 KB | None | 0 0
  1. /*
  2.  * Faturamento.java
  3.  */
  4. package gicron.bss;
  5.  
  6. import com.microsoft.sqlserver.jdbc.SQLServerException;
  7. import gi.Config;
  8. import gi.cliente.ClienteArquivo;
  9. import gi.empresa.Empresa;
  10. import gi.util.ConfigFile;
  11. import gi.util.DateUtil;
  12. import gi.util.Format;
  13. import gi.util.NativeDB;
  14. import gicron.Cron;
  15. import gicron.bean.Assinatura;
  16. import gicron.bean.AssinaturaServico;
  17. import gicron.bean.CallVSC;
  18. import gicron.bean.DescontoAgendado;
  19. import gicron.bean.Duplicata;
  20. import gicron.bean.FormaPgto;
  21. import gicron.bean.Minutagem;
  22. import gicron.bean.Obj;
  23. import gicron.bean.Titulo;
  24. import gicron.bean.TituloServico;
  25. import gicron.bean.Vencimento;
  26. import giejb.GIModulo;
  27. import giejb.core.GenericRemote;
  28. import java.io.BufferedWriter;
  29. import java.io.FileWriter;
  30. import java.math.BigDecimal;
  31. import java.math.BigInteger;
  32. import java.util.Collections;
  33. import java.util.Date;
  34. import java.util.HashSet;
  35. import java.util.LinkedList;
  36. import java.util.List;
  37. import java.util.Set;
  38.  
  39. /**
  40.  *
  41.  * @author britto
  42.  */
  43. public class Faturamento extends Cron {
  44.  
  45.     private NativeDB dbVSC;
  46.  
  47.     /**
  48.      * Argumentos da Rotina
  49.      *
  50.      * @return argumentos da rotina
  51.      */
  52.     @Override
  53.     protected String getArgs() {
  54.         String s = this.getClass() + "\n\tArgs: bss.Faturamento d m y"
  55.                 + "\n\td\tDia de fechamento"
  56.                 + "\n\tm\tMês de fechamento"
  57.                 + "\n\ty\tAno de fechamento";
  58.         return s;
  59.     }
  60.  
  61.     List<Minutagem> tiposLigacao;
  62.    
  63.     private List<Minutagem> tiposLigacao() throws Exception {
  64.         String sql = "SELECT null minutos, codigo, grupo FROM ossgi.ligacaotipo";
  65.         List<Minutagem> l = db().getList(sql, Minutagem.class);
  66.         return l;
  67.     }
  68.    
  69.     /**
  70.      * Executa a Rotina
  71.      *
  72.      * @param args
  73.      * @throws java.lang.Exception
  74.      */
  75.     @Override
  76.     protected void Exec(String[] args) throws Exception {
  77.         GenericRemote r = super.getRemote(GIModulo.GI_CORE, GenericRemote.class);
  78.         try {
  79.             Date dia = new Date();
  80.             Integer d, m, y;
  81.             switch (args.length) {
  82.                 case 2:
  83.                     d = Integer.parseInt(args[1]);
  84.                     m = dia.getMonth();
  85.                     y = dia.getYear();
  86.                     break;
  87.                 case 3:
  88.                     d = Integer.parseInt(args[1]);
  89.                     m = Integer.parseInt(args[2]) - 1;
  90.                     y = dia.getYear();
  91.                     break;
  92.                 case 4:
  93.                     d = Integer.parseInt(args[1]);
  94.                     m = Integer.parseInt(args[2]) - 1;
  95.                     y = Integer.parseInt(args[3]) - 1900;
  96.                     break;
  97.                 default:
  98.                     d = dia.getDate();
  99.                     m = dia.getMonth();
  100.                     y = dia.getYear();
  101.             }
  102.             dia = new Date(y, m, d);
  103.             super.log("Iniciando faturamento de: " + Format.maskData(dia)); // Output para controle de execução.
  104.  
  105.             // Carrega configurações
  106.             setVSC(); // Carrega as infomações para acesso à VSC (telefonia)
  107.             String historicoTaxa = r.getConfig(Config.FINANCEIRO_TAXA).getValor(); // somente para geração da fatura
  108.             Integer descontoId = Integer.parseInt(r.getConfig(Config.FINANCEIRO_DESCONTO_ASSINATURA).getValor());
  109.             String historicoLigacao = r.getConfig(Config.FINANCEIRO_LIGACAO).getValor();
  110.             Integer unidadeLigacaoId = Integer.parseInt(r.getConfig(Config.FINANCEIRO_LIGACAO_UNIDADE).getValor());
  111.             Integer descontoLigacaoId = Integer.parseInt(r.getConfig(Config.FINANCEIRO_DESCONTO_LIGACAO).getValor());
  112.             Integer arquivoTipoId = Integer.parseInt(r.getConfig(Config.ARQUIVO_TIPO_EXTRATO).getValor());
  113.             List<Empresa> empresas = r.findAll(Empresa.class, "nome", Boolean.TRUE);
  114.  
  115.             // Lista Vencimentos e Formas de pagamento
  116.             List<Vencimento> vencimentos = vencimentos(dia);
  117.             List<FormaPgto> formasPgto = formasPgto();
  118.             tiposLigacao = tiposLigacao();
  119.  
  120.             for (Vencimento v : vencimentos) { // Para cada vencimento
  121.                 super.log("Vencimento: " + v.getId() + " - Fech." + v.getFechamento() + " Venc." + v.getDia());
  122.  
  123.                 for (FormaPgto f : formasPgto) { // Para cada forma de pagamento
  124.                     gicron.bean.Faturamento fat = faturamentoInit(dia, v, f); // Inicializa o faturamento
  125.                     if (!faturado(fat)) { // Não fatura novamente
  126.                         fat = saveFaturamento(fat);
  127.                         Set<Integer> clienteIds = new HashSet();
  128.  
  129.                         List<Assinatura> assinaturas = assinaturas(v.getId(), f.getId());
  130.                         super.log("\tFormaPgto: " + f.getNome() + "\t(" + assinaturas.size() + ")\tFat:" + fat.getId() + " \tde:" + Format.maskData(fat.getInicio()) + " a " + Format.maskData(fat.getFim()));
  131.                        
  132.                         Integer numero = getNum(f.getContaId(), f.getId()); // Número da fatura
  133.  
  134.                         for (Assinatura a : assinaturas) { // Percorre as assinaturas
  135.                             //super.log("\t\tAssinatura:" + a.getId() + "/" + a.getClienteId() + "\t" + a.getValidade());
  136.                             if (a.getCtrlNumber() != null) {
  137.                                 // Criar título mesmo sem valor
  138.                                 super.log("\t\t\tConsultar telefonia: " + a.getCtrlNumber());
  139.                                 saveLigacao(fat, a, historicoLigacao, unidadeLigacaoId, descontoLigacaoId, arquivoTipoId); // Salva título com valor das ligações
  140.                             }
  141.  
  142.                             if (f.getTaxa().floatValue() > 0) {
  143.                                 saveTaxa(fat, a, historicoTaxa, f.getTaxa()); // Salva taxa de envio de boleto
  144.                             }
  145.                             for (AssinaturaServico s : a.getServicos()) { // Gera títulos para os serviços prestados
  146.                                 saveTitulo(fat, a, s, descontoId);
  147.                             }
  148.                             if (a.getSepararduplicata()) {
  149.                                 numero++; // Próximo número do documento
  150.                                 saveDuplicata(fat, numero, a.getClienteId(), a.getId(), f); //Gerar Duplicata separado por assinatura
  151.                             } else {
  152.                                 clienteIds.add(a.getClienteId()); // adiciona cliente para gerar duplicata com títulos gerados e em aberto
  153.                             }
  154.                             updateValidade(a, fat.getFim()); // Atualiza validade da assinatura
  155.                         }
  156.  
  157.                         // Gerar Duplicatas
  158.                         System.out.println("Gerando duplicatas");
  159.                         for (Integer clienteId : clienteIds) {
  160.                             numero++; // Próximo número do documento
  161.                             saveDuplicata(fat, numero, clienteId, f);
  162.                             System.out.print(".");
  163.                         }
  164.                         System.out.println("Duplicatas salvas.");
  165.                         // Atualiza número de duplicatas da conta bancária
  166.                         db().exec("UPDATE bssgi.bancoconta SET numduplicata = ? WHERE id = ?", numero, f.getContaId()); // Atualiza número da fatura
  167.                         db().exec("UPDATE bssgi.duplicata d INNER JOIN bssgi.tituloreceber t ON (t.duplicata_id = d.id) SET t.quitado = 1 , d.cancelada = 1 WHERE d.valor = 0.00 AND d.faturamento_id = ?", fat.getId()); // Atualiza títulos e duplicatas zeradas
  168.  
  169.                         //Atualiza valor do faturamento
  170.                         Obj total = db().getFirst("SELECT SUM(valor) AS obj FROM bssgi.duplicata WHERE faturamento_id = ?", Obj.class, fat.getId());
  171.                         if (total.getObj() != null) {
  172.                             db().exec("UPDATE bssgi.faturamento SET valor = ? WHERE id = ?", total.getObj(), fat.getId());
  173.                         }
  174.  
  175.                         gerarNotas(fat, empresas);// Gerar Notas Fiscais
  176.                         gerarReciboSVA(fat, empresas);//Gerar Recibo SVA
  177.                     }
  178.                 }
  179.             }
  180.             db().close(Boolean.FALSE);
  181.             if (dbVSC != null) {
  182.                 dbVSC.close(Boolean.FALSE);
  183.             }
  184.         } catch (Exception e) { // Caso haja algum problema executa rollback
  185.             db().close(Boolean.TRUE);
  186.             throw e;
  187.         }
  188.     }
  189.  
  190.     /**
  191.      * Criar notas fiscais das faturas geradas
  192.      *
  193.      * @param fat
  194.      * @param empresas
  195.      * @throws Exception
  196.      */
  197.     private void gerarNotas(gicron.bean.Faturamento fat, List<Empresa> empresas) throws Exception {
  198.         String sql = "SELECT s.id servicoId, t.id tituloId, a.cfop_id cfopId, f.id fiscalId, f.tipoutilizacao tipo, f.classificacao, c.nome historico, f.aliquota, f.comporbc bc, t.valor, t.desconto "
  199.                 + "FROM bssgi.tituloreceber t "
  200.                 + "INNER JOIN bssgi.assinaturaservico a ON (a.id = t.assinaturaservico_id) "
  201.                 + "INNER JOIN bssgi.unidade u ON (u.id = a.unidade_id) "
  202.                 + "INNER JOIN bssgi.servico s ON (s.id = a.servico_id) "
  203.                 + "INNER JOIN bssgi.servicoclassificacao c ON (c.id = s.servicoclassificacao_id) "
  204.                 + "INNER JOIN bssgi.servicofiscal f ON (f.servicoclassificacao_id = c.id AND u.empresa_id = f.empresa_id) "
  205.                 + "WHERE c.id NOT IN (4,6) AND t.duplicata_id = ? AND u.empresa_id = ?"; //servicoclassificao tem que ser diferente de locação de equipamentos/locação de espaço
  206.  
  207.         List<Duplicata> l = db().getList("SELECT id, cliente_id clienteId FROM bssgi.duplicata WHERE faturamento_id = ?", Duplicata.class, fat.getId());
  208.         for (Duplicata d : l) {
  209.             for (Empresa e : empresas) {
  210.                 List<TituloServico> titulos = db().getList(sql, TituloServico.class, d.getId(), e.getId());
  211.  
  212.                 if (!titulos.isEmpty()) { // Gerar pré-notas
  213.                     BigDecimal valor = BigDecimal.ZERO; //Valor da Nota
  214.  
  215.                     for (TituloServico t : titulos) {
  216.                         valor = valor.add(t.total());
  217.                     }
  218.  
  219.                     db().exec("INSERT INTO bssgi.notafiscal (processamento,dia,tipo,emitida,cancelada,enviada,duplicata_id,cfop_id,empresa_id,cliente_id,servicofiscal_id,valor,situacao) "
  220.                             + "VALUES (NOW(), NOW(), 'Serviço', 0, 0, 0, ?, ?, ?, ?, ?, ?, ?)",
  221.                             d.getId(), // duplicata_id
  222.                             titulos.get(0).getCfopId(), // cfop_id
  223.                             e.getId(), // empresa_id
  224.                             d.getClienteId(), // cliente_id
  225.                             titulos.get(0).getFiscalId(), // servicofiscal_id
  226.                             valor, // valor
  227.                             "N"); // situacao
  228.  
  229.                     Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  230.                     for (TituloServico t : titulos) { // Salva os itens da nota
  231.                         db().exec("INSERT INTO bssgi.notafiscalitem (notafiscal_id,tituloreceber_id,historico,aliquota,basecalculo,valor,desconto,tipoutilizacao,classificacao,servico_id) "
  232.                                 + "VALUES (?,?,?,?,?,?,?,?,?,?)",
  233.                                 id.getObj(), // notafiscal_id
  234.                                 t.getTituloId(), // tituloreceber_id
  235.                                 t.getHistorico(), // historico
  236.                                 t.getAliquota(), // aliquota
  237.                                 (t.getBc()) ? t.total() : BigDecimal.ZERO, // basecalculo
  238.                                 t.getValor(), // valor
  239.                                 t.getDesconto(), // desconto
  240.                                 t.getTipo(), // tipoutilizacao
  241.                                 t.getClassificacao(),// Classificacao
  242.                                 t.getServicoId());  // Código do servio
  243.                     }
  244.                 }
  245.             }
  246.         }
  247.     }
  248.    
  249.     /**
  250.      * Criar notas de fatura a partir dos servicos de locacao
  251.      *
  252.      * @param fat
  253.      * @param empresas
  254.      * @throws Exception
  255.      */
  256.     private void gerarReciboSVA(gicron.bean.Faturamento fat, List<Empresa> empresas) throws Exception {
  257.         String sql = "SELECT s.id servicoId, t.id tituloId, a.cfop_id cfopId, f.id fiscalId, f.tipoutilizacao tipo, f.classificacao, s.nome historico, f.aliquota, f.comporbc bc, t.valor, t.desconto "
  258.                    + "FROM bssgi.tituloreceber t "
  259.                    + "INNER JOIN bssgi.assinaturaservico a ON (a.id = t.assinaturaservico_id) "
  260.                    + "INNER JOIN bssgi.unidade u ON (u.id = a.unidade_id) "
  261.                    + "INNER JOIN bssgi.servico s ON (s.id = a.servico_id) "
  262.                    + "INNER JOIN bssgi.servicoclassificacao c ON (c.id = s.servicoclassificacao_id) "
  263.                    + "INNER JOIN bssgi.servicofiscal f ON (f.servicoclassificacao_id = c.id AND u.empresa_id = f.empresa_id) "
  264.                    + "WHERE c.id IN (1,4,6) AND f.modelofiscal = 25 AND t.duplicata_id = ? AND u.empresa_id = ?";
  265.  
  266.         List<Duplicata> l = db().getList("SELECT id, cliente_id clienteId FROM bssgi.duplicata WHERE faturamento_id = ?", Duplicata.class, fat.getId());
  267.         System.out.println("Gravando notas fatura");
  268.         for (Duplicata d : l) {
  269.             for (Empresa e : empresas) {
  270.                 List<TituloServico> titulos = db().getList(sql, TituloServico.class, d.getId(), e.getId());
  271.                
  272. //                super.log("\t\t\tDuplicata: " + d.getId() + " empresa: " + e.getNome());
  273. //                super.log("\t\t\tTitulos a gerar recibo: " + titulos.size());
  274.                
  275.                 if (!titulos.isEmpty()) { // Gerar pré-notas
  276.                     System.out.print(".");
  277.                    
  278.                     BigDecimal valor = BigDecimal.ZERO; //Valor da Nota
  279.  
  280.                     for (TituloServico t : titulos) {
  281.                         valor = valor.add(t.total());
  282.                     }
  283.                    
  284. //                    super.log("\t\t\tgravando nota de fatura");
  285.                    
  286.                     Obj num = db().getFirst("SELECT MAX(numero) AS obj FROM bssgi.notafatura WHERE empresa_id =  ?", Obj.class, e.getId());
  287.                     Integer numero = (Integer) num.getObj();
  288.                     if(numero != null)
  289.                         numero++;
  290.                     else
  291.                         numero = 1;
  292.                    
  293.                     db().exec("INSERT INTO bssgi.notafatura (processamento,dataemissao,dataentradasaida,empresa_id,cliente_id,servicofiscal_id,duplicata_id,numero,vencimento,valor,tipo) "
  294.                             + "VALUES (NOW(), NOW(),  NOW(), ?, ?, ?, ?, ?, ?, ?, ?)",
  295.                             e.getId(), // empresa_id
  296.                             d.getClienteId(), // cliente_id
  297.                             titulos.get(0).getFiscalId(), // servicofiscal_id
  298.                             d.getId(), // duplicata_id
  299.                             numero, //numero fatura
  300.                             fat.getVencimento(), //vencimento
  301.                             valor,
  302.                             "Locação"); // valor
  303.                    
  304. //                    super.log("\t\t\tgravando itens");
  305.                    
  306.                     Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  307.                     for (TituloServico t : titulos) { // Salva os itens da nota
  308.                        
  309.                         db().exec("INSERT INTO bssgi.notafaturaitem (notafatura_id,tituloreceber_id,servico_id,codigo,descricao,unidade,quantidade,valorunitario,valortotal) "
  310.                                 + "VALUES (?,?,?,?,?,?,?,?,?)",
  311.                                 id.getObj(), // notafatura_id
  312.                                 t.getTituloId(), // tituloreceber_id
  313.                                 t.getServicoId(), // servico_id
  314.                                 "", // codigo(indefinido)
  315.                                 t.getHistorico(), // historico (nome do servico)
  316.                                 "UN", // unidade
  317.                                 1, // quantidade
  318.                                 t.total(), // valor unitario
  319.                                 t.total()); // valor total
  320.                     }
  321.                 }
  322.             }
  323.         }
  324.         System.out.println("Notas fatura salvas.");
  325.     }
  326.  
  327.     /**
  328.      * Carrega o último número gerado para duplicatas da conta corrente
  329.      *
  330.      * @param contaId
  331.      * @return
  332.      * @throws Exception
  333.      */
  334.     private Integer getNum(Integer contaId) throws Exception {
  335.         Obj num = db().getFirst("SELECT numduplicata AS obj FROM bssgi.bancoconta WHERE id = ?", Obj.class, contaId);
  336.         return (Integer) num.getObj();
  337.     }
  338.    
  339.     private Integer getNum(Integer contaId, Integer formaPgtoId) throws Exception {
  340.         Obj max = db().getFirst("SELECT MAX(numero) AS obj FROM bssgi.duplicata WHERE formapgto_id = ?", Obj.class, formaPgtoId);
  341.         Obj num = db().getFirst("SELECT numduplicata AS obj FROM bssgi.bancoconta WHERE id = ?", Obj.class, contaId);
  342.        
  343.         //Problema com numeros duplicados
  344.         if(max.getObj() != null) {
  345.             if( ((Integer) max.getObj()) > (Integer) num.getObj()) {
  346.                 return (Integer) max.getObj();
  347.             }
  348.         }
  349.        
  350.         return (Integer) num.getObj();
  351.     }
  352.  
  353.     /**
  354.      * Atualiza a validade da assinatura
  355.      *
  356.      * @param a
  357.      * @param fim
  358.      * @throws Exception
  359.      */
  360.     private void updateValidade(Assinatura a, Date fim) throws Exception {
  361.         if (a.getValidade().before(fim)) {
  362.             a.setValidade((Date) fim.clone());
  363.             a.getValidade().setDate(a.getValidade().getDate() + 1);
  364.             db().exec("UPDATE bssgi.assinatura SET validade = ?, diassuspenso = 0 WHERE id = ?",
  365.                     a.getValidade(),
  366.                     a.getId());
  367.         }
  368.     }
  369.  
  370.     /**
  371.      * Cria nova duplicata com os títulos do vencimento corrente separado por
  372.      * assinatura
  373.      *
  374.      * @param fat
  375.      * @param numero
  376.      * @param clienteId
  377.      * @param assinaturaId
  378.      * @param f
  379.      * @throws Exception
  380.      */
  381.     private void saveDuplicata(gicron.bean.Faturamento fat, Integer numero, Integer clienteId, Long assinaturaId, FormaPgto f) throws Exception {
  382.         BigDecimal valor = BigDecimal.ZERO; //Valor da Duplicata
  383.  
  384.         List<Titulo> titulos = titulos(clienteId, assinaturaId, fat.getVencimento()); // Listar Títulos
  385.         for (Titulo t : titulos) {
  386.             valor = valor.add(t.total());
  387.         }
  388.  
  389.         String sql = "INSERT INTO bssgi.duplicata (formapgto_id,cliente_id,vencimento,valor,numero,valorpago,cancelada,faturamento_id,vencimento_original,processamento,status_remessa) "
  390.                 + "VALUES (?, ?, ?, ?, ?, 0.0, 0, ?, ?, NOW(),'NOVA')";
  391.  
  392.         db().exec(sql,
  393.                 f.getId(),
  394.                 clienteId,
  395.                 fat.getVencimento(),
  396.                 valor,
  397.                 numero,
  398.                 fat.getId(),
  399.                 fat.getVencimento());
  400.  
  401.         Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  402.         for (Titulo t : titulos) { // atualiza os títulos da duplicata
  403.             db().exec("UPDATE bssgi.tituloreceber SET duplicata_id = ? WHERE id = ?", id.getObj(), t.getId());
  404.         }
  405.     }
  406.  
  407.     /**
  408.      * Cria nova duplicata com os títulos do vencimento corrente
  409.      *
  410.      * @param fat
  411.      * @param numero
  412.      * @param clienteId
  413.      * @param f
  414.      * @throws Exception
  415.      */
  416.     private void saveDuplicata(gicron.bean.Faturamento fat, Integer numero, Integer clienteId, FormaPgto f) throws Exception {
  417.         BigDecimal valor = BigDecimal.ZERO; //Valor da Duplicata
  418.  
  419.         List<Titulo> titulos = titulos(clienteId, fat.getVencimento()); // Listar Títulos
  420.        
  421.         if(titulos.isEmpty()){ //caso não haja titulos
  422.             return;
  423.         }
  424.        
  425.         for (Titulo t : titulos) {
  426.             valor = valor.add(t.total());
  427.         }
  428.  
  429.         String sql = "INSERT INTO bssgi.duplicata (formapgto_id,cliente_id,vencimento,vencimento_original,valor,numero,valorpago,cancelada,faturamento_id,status_remessa) "
  430.                 + "VALUES (?, ?, ?, ?, ?, ?, 0.0, 0, ?,'NOVA')";
  431.  
  432.         db().exec(sql,
  433.                 f.getId(),
  434.                 clienteId,
  435.                 fat.getVencimento(),
  436.                 fat.getVencimento(),
  437.                 valor,
  438.                 numero,
  439.                 fat.getId());
  440.  
  441.         Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  442.         for (Titulo t : titulos) { // atualiza os títulos da duplicata
  443.             db().exec("UPDATE bssgi.tituloreceber SET duplicata_id = ? WHERE id = ?", id.getObj(), t.getId());
  444.         }
  445.     }
  446.  
  447.     /**
  448.      * Lista os títulos não faturados do cliente para o vencimento informado
  449.      *
  450.      * @param clienteId
  451.      * @param vencimento
  452.      * @return
  453.      * @throws Exception
  454.      */
  455.     private List<Titulo> titulos(Integer clienteId, Date vencimento) throws Exception {
  456.         String sql = "SELECT id, assinatura_id assinaturaId, assinaturaservico_id assinaturaServicoId, cliente_id clienteId, "
  457.                 + "unidade_id unidadeId, inicio, fim, vencimento, historico, valor, desconto, juros, credito "
  458.                 + "FROM bssgi.tituloreceber WHERE cliente_id = ? AND vencimento = ? and duplicata_id IS NULL";
  459.         List<Titulo> l = db().getList(sql, Titulo.class, clienteId, vencimento);
  460.         return l;
  461.     }
  462.  
  463.     /**
  464.      * Lista os títulos não faturados do cliente para o vencimento informado
  465.      *
  466.      * @param clienteId
  467.      * @param assinaturaId
  468.      * @param vencimento
  469.      * @return
  470.      * @throws Exception
  471.      */
  472.     private List<Titulo> titulos(Integer clienteId, Long assinaturaId, Date vencimento) throws Exception {
  473.         String sql = "SELECT id, assinatura_id assinaturaId, assinaturaservico_id assinaturaServicoId, cliente_id clienteId, "
  474.                 + "unidade_id unidadeId, inicio, fim, vencimento, historico, valor, desconto, juros, credito "
  475.                 + "FROM bssgi.tituloreceber WHERE cliente_id = ? AND assinatura_id = ? AND vencimento = ? and duplicata_id IS NULL";
  476.         List<Titulo> l = db().getList(sql, Titulo.class, clienteId, assinaturaId, vencimento);
  477.         return l;
  478.     }
  479.  
  480.     /**
  481.      * Cria nova taxa de boleto
  482.      *
  483.      * @param fat
  484.      * @param a
  485.      * @param historicoTaxa
  486.      * @param valor
  487.      * @throws Exception
  488.      */
  489.     private void saveTaxa(gicron.bean.Faturamento fat, Assinatura a, String historicoTaxa, BigDecimal valor) throws Exception {
  490.         String sql = "INSERT INTO bssgi.tituloreceber (cliente_id, processamento, inicio, vencimento, "
  491.                 + "historico, valor, desconto, juros, credito, valorpago, quitado, unidade_id, negociado) VALUES (?, NOW(), ?, ?, ?, ?, 0.0, 0.0, 0.0, 0.0, 0, ?, 0)";
  492.         db().exec(sql,
  493.                 a.getClienteId(),
  494.                 a.getValidade(),
  495.                 fat.getVencimento(),
  496.                 historicoTaxa,
  497.                 valor,
  498.                 a.getUnidadeId());
  499.     }
  500.  
  501.     public Boolean chamadaMesmoTipo(CallVSC c, Minutagem m){
  502.         if(c.getTipo().equals(m.getCodigo())){
  503.             return true;
  504.         }else{ // Verifica no grupo
  505.             for (Minutagem ligacao : tiposLigacao) {
  506.                 if(c.getTipo().equals(ligacao.getCodigo())
  507.                         && m.getCodigo().equals(ligacao.getGrupo())){
  508.                     return true;
  509.                 }
  510.             }
  511.         }
  512.         return false;
  513.     }
  514.    
  515.     /**
  516.      * Cria título e salva o extrato de ligações realizadas
  517.      *
  518.      * @param fat Faturamento corrente
  519.      * @param a Assinatura do cliente
  520.      * @param historicoLigacao
  521.      * @param unidadeLigacaoId Unidade que receberá
  522.      * @param descontoLigacaoId
  523.      * @param arquivoTipoId
  524.      * @throws Exception
  525.      */
  526.     private void saveLigacao(gicron.bean.Faturamento fat, Assinatura a, String historicoLigacao, Integer unidadeLigacaoId, Integer descontoLigacaoId, Integer arquivoTipoId) throws Exception {
  527.         BigDecimal total = BigDecimal.ZERO;
  528.         BigDecimal desc = BigDecimal.ZERO;
  529.  
  530.         List<CallVSC> l = ligacoes(a, fat);
  531.  
  532.         if (l != null) {
  533.             for (CallVSC c : l) {
  534.                 total = total.add(c.getValor());
  535.             }
  536.  
  537.             for (Minutagem m : a.getMinutagens()) {
  538.                 Integer franquia = 0;
  539.                 for (CallVSC c : l) {
  540.                     if (chamadaMesmoTipo(c,m) && franquia <= m.getMinutos()) {
  541.                         franquia += c.getDuracao() / 60;// Divide por 60 por que a Procedure retorna duração em segundos e a franquia é configurada em minutos
  542.                         desc = desc.add(c.getValor());
  543.                         c.setValor(BigDecimal.ZERO); // Zera a ligação dentro da franquia
  544.                     }
  545.                 }
  546.             }
  547.  
  548.             // Salva arquivo CSV
  549.             String csv = "momento,origem,destino,tipo,descricao,duracao,valor,userCode,transactionId\n";
  550.             String nome = (new Date()).getTime() + "-extrato.csv";
  551.             for (CallVSC c : l) {
  552.                 //csv += c.getMomento() + "," + c.getOrigem() + "," + c.getDestino() + "," + c.getTipo() + "," + c.getDescricao() + "," + c.getDuracao() + "," + c.getValor() + "," + c.getUserCode() + "," + c.getTransactionId() + "\n";
  553.                 csv += c.getMomento() + "," + c.getOrigem() + "," + c.getDestino() + "," + c.getTipo() + "," + c.getDescricao() + "," + c.getDuracao() + "," + c.getValor() + ",00000," + c.getTransactionId() + "\n";
  554.             }
  555.             try (BufferedWriter out = new BufferedWriter(new FileWriter(ClienteArquivo.PATH + nome))) {
  556.                 out.write(csv);
  557.             }
  558.  
  559.             String sql = "INSERT INTO bssgi.clientearqv (cliente_id,tipoarqv_id,momento,nome,extensao,arquivo,ativo) VALUES (?,?,NOW(),?,'text/csv',?,1)";
  560.             db().exec(sql,
  561.                     a.getClienteId(),
  562.                     arquivoTipoId,
  563.                     Format.maskData(fat.getInicio()) + " - " + Format.maskData(fat.getFim()),
  564.                     nome);
  565.  
  566.             AssinaturaServico s = null;
  567.             for (AssinaturaServico as : a.getServicos()) { // Gera títulos para os serviços prestados
  568.                 if (as.getTipo().equals(gi.comercial.Servico.TIPO_TELEFONE)) {
  569.                     s = as;
  570.                     break;
  571.                 }
  572.             }
  573.  
  574.             // Salva o título
  575.             sql = "INSERT INTO bssgi.tituloreceber (assinatura_id, assinaturaservico_id, cliente_id, processamento, inicio, fim, vencimento, "
  576.                     + "historico, valor, desconto, juros, credito, valorpago, quitado, unidade_id, negociado) VALUES (?,?,?, NOW(), ?, ?, ?, ?, ?, ?, 0.0, 0.0, 0.0, 0, ?, 0)";
  577.             db().exec(sql,
  578.                     a.getId(),
  579.                     (s == null) ? null : s.getId(),
  580.                     a.getClienteId(),
  581.                     a.getValidade(),
  582.                     fat.getFim(),
  583.                     fat.getVencimento(),
  584.                     historicoLigacao,
  585.                     total,
  586.                     desc,
  587.                     unidadeLigacaoId);
  588.  
  589.             // Salva o desconto
  590.             if (desc.floatValue() > 0) {
  591.                 Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  592.                 db().exec("INSERT INTO bssgi.desconto (descontotipo_id,tituloreceber_id,momento,valor,excluido) VALUES (?,?,NOW(),?,0)",
  593.                         descontoLigacaoId,
  594.                         id.getObj(),
  595.                         desc);
  596.             }
  597.         }
  598.     }
  599.  
  600.     /**
  601.      * Salva novo título
  602.      *
  603.      * @param fat
  604.      * @param a
  605.      * @param s
  606.      * @param descontoId
  607.      * @throws Exception
  608.      */
  609.     private void saveTitulo(gicron.bean.Faturamento fat, Assinatura a, AssinaturaServico s, Integer descontoId) throws Exception {
  610.         String sql = "INSERT INTO bssgi.tituloreceber (assinaturaservico_id, cliente_id, processamento, inicio, fim, vencimento, "
  611.                 + "historico, valor, desconto, juros, credito, valorpago, quitado, unidade_id, assinatura_id, negociado) VALUES (?, ?, NOW(), ?, ?, ?, ?, ?, ?, 0.0, 0.0, 0.0, 0, ?, ?, 0)";
  612.  
  613. //        Date fim = fat.getFim();
  614.         Integer diasSuspenso = a.getDiassuspenso();
  615.         if(a.getSuspensao() != null){
  616.                  if(a.getValidade().compareTo(a.getSuspensao()) < 0){
  617.                      diasSuspenso += DateUtil.dias(a.getSuspensao(), fat.getFim());
  618.                  }else{
  619.                      return; // Não fatura que está suspenso a muitos dias
  620.                  }
  621.         }
  622.        
  623.         BigDecimal desconto = BigDecimal.ZERO;
  624.         if (s.getDescontoLimite() != null && s.getDescontoLimite().before(fat.getVencimento())) {
  625.             db().exec("UPDATE bssgi.assinaturaservico SET desconto = 0, descontolimite = NULL WHERE id = ?", s.getId());
  626.         } else {
  627.             desconto = gi.financeiro.Faturamento.proporcionalValidade(a.getValidade(), fat.getInicio(), fat.getFim(), s.getDesconto());
  628.             desconto = desconto.subtract(gi.financeiro.Faturamento.proporcional(diasSuspenso, fat.getInicio(), fat.getFim(), s.getDesconto()));
  629.             desconto = (desconto.floatValue() < 0) ? BigDecimal.ZERO : desconto;
  630.         }
  631.  
  632.         BigDecimal valor = gi.financeiro.Faturamento.proporcionalValidade(a.getValidade(), fat.getInicio(), fat.getFim(), s.getValor());
  633.  
  634. //        super.log("ASSINATURA " + a.getId());
  635. //        super.log("DIAS SUSPENSO " + a.getDiassuspenso());
  636. //        super.log("VALIDADE " + a.getValidade());
  637. //        super.log("INICIO FAT " + fat.getInicio());
  638. //        super.log("FIM FAT " + fat.getFim());
  639.        
  640.         db().exec(sql,
  641.                 s.getId(),
  642.                 a.getClienteId(),
  643.                 a.getValidade(),
  644.                 fat.getFim(),
  645.                 fat.getVencimento(),
  646.                 s.getNome(),
  647.                 valor,
  648.                 desconto,
  649.                 s.getUnidadeId(),
  650.                 a.getId());
  651.         Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  652.  
  653.         if (desconto.floatValue() > 0) {
  654.             db().exec("INSERT INTO bssgi.desconto (descontotipo_id,tituloreceber_id,momento,valor,excluido) VALUES (?,?,NOW(),?,0)",
  655.                     descontoId,
  656.                     id.getObj(),
  657.                     desconto);
  658.         }
  659.  
  660.         // Desconto de dias suspensos
  661.         if(diasSuspenso > 0){
  662.             BigDecimal desc = gi.financeiro.Faturamento.proporcional(diasSuspenso, fat.getInicio(), fat.getFim(), s.getValor());
  663.             db().exec("INSERT INTO bssgi.desconto (descontotipo_id,tituloreceber_id,momento,valor,excluido) VALUES (?,?,NOW(),?,0)",
  664.                     4, // Desconto Suspensão - (DÉBITO/TEMPORÁRIA)
  665.                     id.getObj(),
  666.                     desc);
  667.            
  668.             db().exec("UPDATE bssgi.tituloreceber SET desconto = desconto + ? WHERE id = ?", desc, id.getObj());
  669.         }
  670.  
  671.         // Analisa o desconto agendado
  672.         sql = "SELECT id, descontotipo_id descontoTipoId, valor, usuario_id usuarioId FROM bssgi.descontoagendado WHERE assinaturaservico_id = ? AND vencimento = ? AND excluido = 0 AND processado = 0";
  673.         List<DescontoAgendado> l = db().getList(sql, DescontoAgendado.class, s.getId(), fat.getVencimento());
  674.         if (!l.isEmpty()) {
  675.             BigDecimal valorTitulo = valor.add(desconto.negate());
  676.  
  677.             List<DescontoAgendado> lproc = new LinkedList<>();
  678.             for (DescontoAgendado d : l) {
  679.                 if (valorTitulo.add(d.getValor().negate()).floatValue() < BigDecimal.ZERO.floatValue()) { // agenda para o próximo faturamento
  680.                     Date vencimentoProximo = (Date) fat.getVencimento().clone();
  681.                     vencimentoProximo.setMonth(vencimentoProximo.getMonth() + 1);
  682.                     db().exec("UPDATE bssgi.descontoagendado SET vencimento = ? WHERE id = ?", vencimentoProximo, d.getId());
  683.                 } else { // Se o valor for maior que zero processa o desconto agendado.
  684.                     lproc.add(d);
  685.                     valorTitulo = valorTitulo.add(d.getValor().negate());
  686.                 }
  687.             }
  688.             for (DescontoAgendado d : lproc) {
  689.                 db().exec("INSERT INTO bssgi.desconto (descontotipo_id,tituloreceber_id,momento,valor,excluido,usuario_id) VALUES (?,?,NOW(),?,0,?)",
  690.                         d.getDescontoTipoId(),
  691.                         id.getObj(),
  692.                         d.getValor(),
  693.                         d.getUsuarioId());
  694.                 db().exec("UPDATE bssgi.tituloreceber SET desconto = desconto + ? WHERE id = ?", d.getValor(), id.getObj());
  695.                 db().exec("UPDATE bssgi.descontoagendado SET processado = 1 WHERE id = ?", d.getId());
  696.             }
  697.         }
  698.  
  699.     }
  700.  
  701.     /**
  702.      * Salva o novo faturamento
  703.      *
  704.      * @param fat Faturamento inicializado
  705.      * @return
  706.      * @throws Exception
  707.      */
  708.     private gicron.bean.Faturamento saveFaturamento(gicron.bean.Faturamento fat) throws Exception {
  709.         String sql = "INSERT INTO bssgi.faturamento (vencimento_id,formapgto_id,processamento,inicio,fim,valor) "
  710.                 + "VALUES (?, ?, NOW(), ?, ?, 0.0)";
  711.         db().exec(sql,
  712.                 fat.getVencimentoId(),
  713.                 fat.getFormaPgtoId(),
  714.                 fat.getInicio(),
  715.                 fat.getFim());
  716.  
  717.         Obj id = db().getFirst("SELECT LAST_INSERT_ID() AS obj", Obj.class);
  718.         fat.setId(((BigInteger) id.getObj()).intValue());
  719.         return fat;
  720.     }
  721.  
  722.     /**
  723.      * Inicializa o faturamento para o vencimento e forma de pagamento
  724.      *
  725.      * @param dia Dia do fechamento
  726.      * @param v Vencimento
  727.      * @param f Forma de pagamento
  728.      * @return Novo faturamento
  729.      * @throws Exception
  730.      */
  731.     private gicron.bean.Faturamento faturamentoInit(Date dia, Vencimento v, FormaPgto f) throws Exception {
  732.         gicron.bean.Faturamento fat = new gicron.bean.Faturamento();
  733.         fat.setVencimento(new Date(dia.getYear(), dia.getMonth(), v.getDia()));
  734.  
  735.         Date fim = (Date) fat.getVencimento().clone();
  736.         fim.setDate(v.getFechamento());
  737.         if (v.getDia() < v.getFechamento()) { // fechamento no mês anterior
  738.             fat.getVencimento().setMonth(fat.getVencimento().getMonth() + 1);
  739.         }
  740.         Date inicio = (Date) fim.clone();
  741.         inicio.setMonth(inicio.getMonth() - 1);
  742.         fim.setDate(v.getFechamento() - 1); // fatura um mês até ontem
  743.  
  744.         fat.setInicio(inicio);
  745.         fat.setFim(fim);
  746.         fat.setFormaPgtoId(f.getId());
  747.         fat.setVencimentoId(v.getId());
  748.  
  749.         return fat;
  750.     }
  751.  
  752.     /**
  753.      * Verifica se existe outro faturamento com os dados criados
  754.      *
  755.      * @param fat Fatuamento criado
  756.      * @return
  757.      * @throws Exception
  758.      */
  759.     private Boolean faturado(gicron.bean.Faturamento fat) throws Exception {
  760.         String sql = "SELECT id, vencimento_id vencimentoId, formapgto_id formaPgtoId, inicio, fim, valor, null vencimento FROM bssgi.faturamento WHERE vencimento_id = ? AND formapgto_id = ? AND inicio = ? AND fim = ?";
  761.         gicron.bean.Faturamento f = db().getFirst(sql, gicron.bean.Faturamento.class, fat.getVencimentoId(), fat.getFormaPgtoId(), fat.getInicio(), fat.getFim());
  762.         return f != null;
  763.     }
  764.  
  765.     /**
  766.      * Lista vencimentos no dia de fechamento informado
  767.      *
  768.      * @param dia
  769.      * @return
  770.      * @throws Exception
  771.      */
  772.     private List<Vencimento> vencimentos(Date dia) throws Exception {
  773.         List<Obj> ids = db().getList("SELECT DISTINCT(a.vencimento_id) obj FROM bssgi.assinatura a INNER JOIN bssgi.assinaturasituacao s ON (a.assinaturasituacao_id = s.id) WHERE !s.cancelado", Obj.class);
  774.  
  775.         String sql = "SELECT * FROM bssgi.vencimento WHERE fechamento = ? AND id in (?)";
  776.         List<Vencimento> l = db().getList(sql, Vencimento.class, dia.getDate(), ids);
  777.         if (l.isEmpty()) {
  778.             System.err.println("FATURAMENTO: Nenhum fechamento para: " + Format.maskData(dia));
  779.             System.exit(1);
  780.         }
  781.         return l;
  782.     }
  783.  
  784.     /**
  785.      * Lista formas de pagamento disponíveis no sistema
  786.      *
  787.      * @return
  788.      * @throws Exception
  789.      */
  790.     private List<FormaPgto> formasPgto() throws Exception {
  791.         String sql = "SELECT f.id, f.nome, b.bancoconta_id contaId, b.taxa FROM bssgi.formapgto f "
  792.                 + "INNER JOIN bssgi.formapgtoboleto b ON (f.id = b.id) "; // Boletos
  793.         List<FormaPgto> l = db().getList(sql, FormaPgto.class);
  794.  
  795.         sql = "SELECT f.id, f.nome, b.bancoconta_id contaId, 0.0 taxa FROM bssgi.formapgto f "
  796.                 + "INNER JOIN bssgi.formapgtodebito b ON (f.id = b.id) "; // Débitos
  797.         l.addAll(db().getList(sql, FormaPgto.class));
  798.  
  799.         if (l.isEmpty()) {
  800.             System.err.println("FATURAMENTO: Nenhuma forma de pagamento configurada");
  801.             System.exit(1);
  802.         }
  803.         return l;
  804.     }
  805.  
  806.     /**
  807.      * Lista as assinaturas s serviços com o vencimento e forma de pagamento
  808.      * informados
  809.      *
  810.      * @param vencimentoId id do vencimento
  811.      * @param formaPgtoId id da forma de pagamento
  812.      * @return
  813.      * @throws Exception
  814.      */
  815.     private List<Assinatura> assinaturas(Integer vencimentoId, Integer formaPgtoId) throws Exception {
  816.         String sql = "SELECT null minutagens, null servicos, a.id, a.pacote_id pacoteId, a.cliente_id clienteId, a.validade, a.suspensao, a.diassuspenso, a.unidade_id unidadeId, a.ctrl_number ctrlNumber, t.separarduplicata "
  817.                 + "FROM bssgi.assinatura a INNER JOIN bssgi.cliente c ON (c.id = a.cliente_id) INNER JOIN bssgi.clientetipo t ON (t.id = c.clientetipo_id) WHERE a.cancelamento IS NULL AND a.vencimento_id = ? AND a.formapgto_id = ?";
  818.         List<Assinatura> l = db().getList(sql, Assinatura.class, vencimentoId, formaPgtoId);
  819.  
  820.         sql = "SELECT a.id, a.unidade_id unidadeId, a.servico_id servicoId, a.valor, a.desconto, a.descontolimite descontoLimite, s.codigo, s.nome, s.tipo FROM bssgi.assinaturaservico a "
  821.                 + "INNER JOIN bssgi.servico s ON (s.id = a.servico_id) WHERE a.assinatura_id = ?";
  822.         for (Assinatura a : l) {
  823.             a.setServicos(db().getList(sql, AssinaturaServico.class, a.getId()));
  824.         }
  825.         sql = "SELECT m.minutos, t.codigo, null grupo FROM bssgi.minutagem m "
  826.                 + "INNER JOIN ossgi.ligacaotipo t ON (t.id = m.ligacaotipo_id) WHERE m.pacote_id = ?";
  827.         for (Assinatura a : l) {
  828.             a.setMinutagens(db().getList(sql, Minutagem.class, a.getPacoteId()));
  829.         }
  830.         return l;
  831.     }
  832.  
  833.     /**
  834.      * Inicializa as informações de acesso à VSC
  835.      *
  836.      * @throws SQLServerException
  837.      * @throws Exception
  838.      */
  839.     private void setVSC() throws SQLServerException, Exception {
  840. //        try {
  841.             GenericRemote r = super.getRemote(GIModulo.GI_CORE, GenericRemote.class);
  842.             Config url = r.getConfig(Config.VSC_DB_URL);
  843.             Config port = r.getConfig(Config.VSC_DB_PORT);
  844.             Config user = r.getConfig(Config.VSC_DB_USER);
  845.             Config pass = r.getConfig(Config.VSC_DB_PASS);
  846.             Config base = r.getConfig(Config.VSC_DB_BASE);
  847.             Config driver = r.getConfig(Config.VSC_DB_DRIVER);
  848.             dbVSC = new NativeDB(url.getValor(), user.getValor(), pass.getValor(), base.getValor(), Integer.parseInt(port.getValor()), driver.getValor());
  849. //            dbVSC = new NativeDB(url.getValor(), user.getValor(), pass.getValor(), "VSCDBCDRs", Integer.parseInt(port.getValor()), driver.getValor());
  850. //        } catch (Exception ex) {
  851. //            System.err.println("Não foi possível conectar à VSC: " + ex);
  852. //        }
  853.     }
  854.  
  855.     /**
  856.      * Carrega as ligações a partir da storage procedure no período a ser
  857.      * faturado
  858.      *
  859.      * @param a Assinatura do cliente
  860.      * @param fat Faturamento corrente
  861.      * @return
  862.      * @throws Exception
  863.      */
  864.     private List<CallVSC> ligacoes(Assinatura a, gicron.bean.Faturamento fat) throws Exception {
  865.         if (dbVSC != null) {
  866. //            String key = UserInfo.getUserCode(a.getClienteId(), a.getId());
  867.             String from = (fat.getInicio().getYear() + 1900) + "-" + (fat.getInicio().getMonth() + 1) + "-" + fat.getInicio().getDate() + " 00:00:00";
  868.             String to = (fat.getFim().getYear() + 1900) + "-" + (fat.getFim().getMonth() + 1) + "-" + fat.getFim().getDate() + " 23:59:59";
  869.             List<CallVSC> l = dbVSC.getListProc(ConfigFile.get("sql.Calls.proc"), CallVSC.class, from, to, a.getCtrlNumber());
  870.             Collections.sort(l, CallVSC.COMPARATOR_MOMENTO); // Importante ordenar por tipo
  871.             Collections.sort(l, CallVSC.COMPARATOR_TIPO);
  872.             return l;
  873.         }
  874.         return null;
  875.     }
  876.  
  877. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement