Java tutorial
/*** Copyright (c) 2012 - 2020 Hrcules S. S. Jos Este arquivo parte do programa Oramento Domstico. Oramento Domstico um software livre; voc pode redistribui-lo e/ou modific-lo dentro dos termos da Licena Pblica Geral Menor GNU como publicada pela Fundao do Software Livre (FSF); na verso 2.1 da Licena. Este programa distribudo na esperana que possa ser til, mas SEM NENHUMA GARANTIA; sem uma garantia implcita de ADEQUAO a qualquer MERCADO ou APLICAO EM PARTICULAR. Veja a Licena Pblica Geral Menor GNU em portugus para maiores detalhes. Voc deve ter recebido uma cpia da Licena Pblica Geral Menor GNU sob o nome de "LICENSE.TXT" junto com este programa, se no, acesse o site do projeto no endereco https://github.com/herculeshssj/orcamento ou escreva para a Fundao do Software Livre(FSF) Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. Para mais informaes sobre o programa Oramento Domstico e seu autor entre em contato pelo e-mail herculeshssj@outlook.com, ou ainda escreva para Hrcules S. S. Jos, Av. Ministro Lafaeyte de Andrade, 1683 - Bl. 3 Apt 404, Marco II - Nova Iguau, RJ, Brasil. ***/ package br.com.hslife.orcamento.service; import java.util.Calendar; import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import br.com.hslife.orcamento.entity.CartaoCredito; import br.com.hslife.orcamento.entity.Conta; import br.com.hslife.orcamento.entity.ConversaoMoeda; import br.com.hslife.orcamento.entity.FaturaCartao; import br.com.hslife.orcamento.entity.LancamentoConta; import br.com.hslife.orcamento.entity.LancamentoPeriodico; import br.com.hslife.orcamento.entity.Moeda; import br.com.hslife.orcamento.entity.Usuario; import br.com.hslife.orcamento.enumeration.PeriodoLancamento; import br.com.hslife.orcamento.enumeration.StatusFaturaCartao; import br.com.hslife.orcamento.enumeration.StatusLancamento; import br.com.hslife.orcamento.enumeration.StatusLancamentoConta; import br.com.hslife.orcamento.enumeration.TipoLancamento; import br.com.hslife.orcamento.enumeration.TipoLancamentoPeriodico; import br.com.hslife.orcamento.exception.BusinessException; import br.com.hslife.orcamento.facade.IFaturaCartao; import br.com.hslife.orcamento.facade.ILancamentoPeriodico; import br.com.hslife.orcamento.repository.FaturaCartaoRepository; import br.com.hslife.orcamento.repository.LancamentoContaRepository; import br.com.hslife.orcamento.util.Util; @Service("faturaCartaoService") public class FaturaCartaoService extends AbstractCRUDService<FaturaCartao> implements IFaturaCartao { @Autowired private FaturaCartaoRepository repository; @Autowired private LancamentoContaRepository lancamentoContaRepository; @Autowired private FechamentoPeriodoService fechamentoPeriodoService; @Autowired private ILancamentoPeriodico lancamentoPeriodicoService; public FaturaCartaoRepository getRepository() { this.repository.setSessionFactory(this.sessionFactory); return repository; } public ILancamentoPeriodico getLancamentoPeriodicoService() { return lancamentoPeriodicoService; } public FechamentoPeriodoService getFechamentoPeriodoService() { return fechamentoPeriodoService; } public LancamentoContaRepository getLancamentoContaRepository() { this.lancamentoContaRepository.setSessionFactory(this.sessionFactory); return lancamentoContaRepository; } @Override public void validar(FaturaCartao entity) { // Impede que haja mais de uma fatura com a mesma data de vencimento para o carto selecionado List<FaturaCartao> faturas = getRepository().findByContaAndDataVencimento(entity.getConta(), entity.getDataVencimento()); if (faturas != null && !faturas.isEmpty()) { faturas.remove(entity); if (faturas.size() != 0) throw new BusinessException("Data de vencimento j informada para uma fatura cadastrada!"); } } public double saldoDevedorUltimaFatura(CartaoCredito cartao) { FaturaCartao fatura = getRepository().lastFaturaCartaoFechada(cartao.getConta()); if (fatura != null && !fatura.getStatusFaturaCartao().equals(StatusFaturaCartao.QUITADA)) { return fatura.getValorFatura() + fatura.getSaldoDevedor(); } else { return 0.0; } } @SuppressWarnings("deprecation") @Override public void fecharFatura(FaturaCartao entity, List<Moeda> conversoes) { // Busca a fatura que ser fechada FaturaCartao faturaCartao = this.buscarPorID(entity.getId()); // Obtm o saldo devedor da fatura atualmente fechada if (this.saldoDevedorUltimaFatura(entity.getConta().getCartaoCredito()) == 0.0) faturaCartao.setSaldoDevedor(faturaCartao.getSaldoDevedor() + this.saldoDevedorUltimaFatura(entity.getConta().getCartaoCredito())); else faturaCartao.setSaldoDevedor(this.saldoDevedorUltimaFatura(entity.getConta().getCartaoCredito())); // Atribuies dos valores faturaCartao.setDataVencimento(entity.getDataVencimento()); faturaCartao.setDataFechamento(entity.getDataFechamento()); faturaCartao.setStatusFaturaCartao(StatusFaturaCartao.FECHADA); // Calcula o valor total da fatura double totalFatura = 0.0; for (Moeda moeda : conversoes) { if (moeda.isPadrao()) { moeda.setTotalConvertido(Util.arredondar(moeda.getTotal())); } else { moeda.setTotalConvertido(Util.arredondar(moeda.getTotal() * moeda.getTaxaConversao())); } totalFatura += moeda.getTotalConvertido(); } // Adiciona ao total da fatura o valor da fatura vencida faturaCartao.setValorFatura(totalFatura); faturaCartao.setValorMinimo( Util.arredondar((Math.abs(totalFatura + faturaCartao.getSaldoDevedor()) * 15) / 100)); // 15% do valor da fatura // Popula a lista de converses de moeda for (Moeda moeda : conversoes) { ConversaoMoeda conversao = new ConversaoMoeda(); conversao.setFaturaCartao(faturaCartao); conversao.setMoeda(moeda); conversao.setTaxaConversao(moeda.getTaxaConversao()); conversao.setValor(moeda.getTotalConvertido()); faturaCartao.getConversoesMoeda().add(conversao); } // Altera o status da fatura atualmente fechada para VENCIDA FaturaCartao faturaVencida = getRepository().lastFaturaCartaoFechada(entity.getConta()); if (faturaVencida != null && !faturaVencida.getId().equals(faturaCartao.getId()) && faturaVencida.getStatusFaturaCartao().equals(StatusFaturaCartao.FECHADA)) { faturaVencida.setStatusFaturaCartao(StatusFaturaCartao.VENCIDA); // Seta as informaes de pagamento da fatura faturaVencida.setDataPagamento(entity.getDataFechamento()); faturaVencida.setValorPago(Math.abs(faturaVencida.getValorFatura())); faturaVencida.setValorMinimo(Util.arredondar((Math.abs(faturaVencida.getValorFatura()) * 15) / 100)); // Salva a fatura getRepository().update(faturaVencida); } // Verifica se a fatura possui saldo total e saldo devedor zerado // Caso tenha, a fatura automaticamento quitada if (faturaCartao.getSaldoDevedor() == 0 && faturaCartao.getValorFatura() == 0) { faturaCartao.setStatusFaturaCartao(StatusFaturaCartao.QUITADA); } // Salva a fatura do carto getRepository().update(faturaCartao); // Quita todos os lanamentos vinculados fatura for (LancamentoConta lancamento : faturaCartao.getDetalheFatura()) { LancamentoConta l = getLancamentoContaRepository().findById(lancamento.getId()); // Procura a taxa de converso para a moeda do lanamento double taxaConversao = 1.0000; for (ConversaoMoeda conversao : faturaCartao.getConversoesMoeda()) { if (conversao.getMoeda().equals(l.getMoeda())) { taxaConversao = conversao.getTaxaConversao(); break; } } // Atualiza a taxa de converso para registrar corretamente os valores l.getTaxaConversao().atualizaTaxaConversao(l.getValorPago(), taxaConversao); if (l.getLancamentoPeriodico() != null) { // Delega a quitao do lanamento para a rotina de registro de pagamento de lanamentos peridicos getFechamentoPeriodoService().registrarPagamento(l); } else { l.setStatusLancamentoConta(StatusLancamentoConta.QUITADO); getLancamentoContaRepository().update(l); } } // Verifica se existe fatura futura para alterar o status if (getRepository().findNextFaturaCartaoFutura(entity.getConta()) == null) { // Cria a prxima fatura ABERTA FaturaCartao novaFatura = new FaturaCartao(); novaFatura.setConta(entity.getConta()); novaFatura.setStatusFaturaCartao(StatusFaturaCartao.ABERTA); // Data de vencimento da prxima fatura Calendar vencimento = Calendar.getInstance(); vencimento.setTime(entity.getDataVencimento()); vencimento.add(Calendar.MONTH, 1); novaFatura.setDataVencimento(vencimento.getTime()); // Seta o ms e ano da fatura novaFatura.setMes(novaFatura.getDataVencimento().getMonth() + 1); novaFatura.setAno(novaFatura.getDataVencimento().getYear() + 1900); // Salva a nova fatura getRepository().save(novaFatura); } else { FaturaCartao novaFatura = getRepository().findNextFaturaCartaoFutura(entity.getConta()); novaFatura.setStatusFaturaCartao(StatusFaturaCartao.ABERTA); getRepository().update(novaFatura); } } @Override public void reabrirFatura(FaturaCartao entity) { // Busca a fatura atualmente aberta e muda seu status para FUTURA FaturaCartao faturaAtual = getRepository().findFaturaCartaoAberta(entity.getConta()); if (faturaAtual != null) { faturaAtual.setStatusFaturaCartao(StatusFaturaCartao.FUTURA); getRepository().update(faturaAtual); } // Busca a fatura que ser reaberta FaturaCartao fatura = getRepository().findById(entity.getId()); // Atribuies dos valores //fatura.setDataFechamento(null); fatura.setStatusFaturaCartao(StatusFaturaCartao.ABERTA); // Salva a fatura do carto getRepository().update(fatura); // Reabre todos os lanamentos vinculados fatura for (LancamentoConta lancamento : fatura.getDetalheFatura()) { LancamentoConta l = getLancamentoContaRepository().findById(lancamento.getId()); l.setStatusLancamentoConta(StatusLancamentoConta.REGISTRADO); getLancamentoContaRepository().update(l); } } @Override public void quitarFaturaDebitoConta(FaturaCartao faturaCartao, Conta contaCorrente, double valorAQuitar, Date dataPagamento) { if (Math.abs(Util.arredondar(valorAQuitar)) < Math.abs(Util.arredondar(faturaCartao.getValorMinimo()))) { throw new BusinessException("Valor de pagamento no pode ser menor que o valor mnimo da fatura!"); } if (Math.abs(Util.arredondar(valorAQuitar)) > Math .abs(Util.arredondar(faturaCartao.getValorFatura() + faturaCartao.getSaldoDevedor()))) { throw new BusinessException("No possvel quitar um valor maior que o valor total da fatura!"); } if (dataPagamento.before(contaCorrente.getDataAbertura())) { throw new BusinessException( "Data de pagamento deve ser posterior a data de abertura da conta selecionada!"); } // Traz a fatura e seta seus atributos FaturaCartao fatura = getRepository().findById(faturaCartao.getId()); fatura.setStatusFaturaCartao(StatusFaturaCartao.QUITADA); fatura.setDataPagamento(dataPagamento); fatura.setValorPago(valorAQuitar); fatura.setValorMinimo(faturaCartao.getValorMinimo()); // Cria o lanamento que ir quitar a fatura LancamentoConta lancamentoPagamento = new LancamentoConta(); lancamentoPagamento.setConta(contaCorrente); lancamentoPagamento.setMoeda(contaCorrente.getMoeda()); lancamentoPagamento.setDataPagamento(dataPagamento); lancamentoPagamento.setDescricao("Pagamento Fatura " + fatura.getLabel() + ", " + faturaCartao.getConta().getCartaoCredito().getDescricao()); lancamentoPagamento.setStatusLancamentoConta(StatusLancamentoConta.QUITADO); lancamentoPagamento.setValorPago(valorAQuitar); lancamentoPagamento.setTipoLancamento(TipoLancamento.DESPESA); lancamentoPagamento.setCategoria(faturaCartao.getCategoriaSelecionada()); lancamentoPagamento.setFavorecido(faturaCartao.getFavorecidoSelecionado()); lancamentoPagamento.setMeioPagamento(faturaCartao.getMeioPagamentoSelecionado()); // Determina o valor do saldo devedor double saldoDevedor = (faturaCartao.getValorFatura() + faturaCartao.getSaldoDevedor()) - valorAQuitar; // Salva o lanamento getLancamentoContaRepository().save(lancamentoPagamento); // Atribui o lanamento fatura fatura.setLancamentoPagamento(lancamentoPagamento); // Salva a fatura paga getRepository().update(fatura); // Busca a fatura aberta e atribui o saldo devedor a ela. Depois salva FaturaCartao faturaAtual = getRepository().findFaturaCartaoAberta(faturaCartao.getConta()); faturaAtual.setSaldoDevedor(saldoDevedor); getRepository().update(faturaAtual); } @Override public void quitarFaturaParcelamento(FaturaCartao faturaCartao, int quantParcelas, Date dataParcelamento) { /* Efetua a quitao da fatura */ FaturaCartao fatura = getRepository().findById(faturaCartao.getId()); fatura.setStatusFaturaCartao(StatusFaturaCartao.QUITADA); fatura.setDataPagamento(dataParcelamento); fatura.setValorPago(faturaCartao.getValorFatura() + faturaCartao.getSaldoDevedor()); fatura.setValorMinimo(faturaCartao.getValorMinimo()); // Salva a fatura paga getRepository().update(fatura); /* Efetua o parcelamento da fatura */ // Traz as informaes da fatura atualmente aberta FaturaCartao faturaAberta = getRepository().findFaturaCartaoAberta(faturaCartao.getConta()); // Determina a data de fechamento da fatura atual Calendar temp = Calendar.getInstance(); temp.setTime(faturaAberta.getDataVencimento()); if (faturaAberta.getConta().getCartaoCredito().getDiaFechamentoFatura() < faturaAberta.getConta() .getCartaoCredito().getDiaVencimentoFatura()) { temp.set(Calendar.DAY_OF_MONTH, faturaAberta.getConta().getCartaoCredito().getDiaFechamentoFatura()); } else { temp.add(Calendar.MONTH, 1); temp.set(Calendar.DAY_OF_MONTH, faturaAberta.getConta().getCartaoCredito().getDiaFechamentoFatura()); } LancamentoPeriodico parcelamentoFatura = new LancamentoPeriodico(); parcelamentoFatura.setConta(faturaCartao.getConta()); parcelamentoFatura.setDataAquisicao(dataParcelamento); parcelamentoFatura.setDataPrimeiraParcela(temp.getTime()); parcelamentoFatura .setDescricao("Parcelamento Fatura " + faturaCartao.getMes() + "/" + faturaCartao.getAno()); parcelamentoFatura.setDiaVencimento(faturaCartao.getConta().getCartaoCredito().getDiaFechamentoFatura()); parcelamentoFatura.setMoeda(faturaCartao.getConta().getMoeda()); parcelamentoFatura.setPeriodoLancamento(PeriodoLancamento.MENSAL); parcelamentoFatura.setStatusLancamento(StatusLancamento.ATIVO); parcelamentoFatura.setTipoLancamento(TipoLancamento.DESPESA); parcelamentoFatura.setTipoLancamentoPeriodico(TipoLancamentoPeriodico.PARCELADO); parcelamentoFatura.setTotalParcela(quantParcelas); parcelamentoFatura.setUsuario(faturaCartao.getConta().getUsuario()); parcelamentoFatura.setValorCompra(fatura.getValorPago()); parcelamentoFatura.setValorParcela(Util.arredondar(fatura.getValorPago() / quantParcelas)); parcelamentoFatura.setCategoria(faturaCartao.getCategoriaSelecionada()); parcelamentoFatura.setFavorecido(faturaCartao.getFavorecidoSelecionado()); parcelamentoFatura.setMeioPagamento(faturaCartao.getMeioPagamentoSelecionado()); getLancamentoPeriodicoService().cadastrar(parcelamentoFatura); } @Override public void quitarFaturaLancamentoSelecionado(FaturaCartao faturaCartao, LancamentoConta lancamentoConta) { // Verifica se o lanamento selecionado j foi vinculado com outra fatura if (getLancamentoContaRepository().existsLinkagePagamentoFaturaCartao(lancamentoConta)) { throw new BusinessException("Lanamento selecionado j foi usado para quitar outra fatura!"); } // Verifica se o valor do lanamento selecionado menor que o valor mnimo da fatura if (Math.abs(Util.arredondar(lancamentoConta.getValorPago())) < Math .abs(Util.arredondar(faturaCartao.getValorMinimo()))) { throw new BusinessException("Valor de pagamento no pode ser menor que o valor mnimo da fatura!"); } // Verifica se o valor do lanamento selecionado maior que o valor total da fatura if (Math.abs(Util.arredondar(lancamentoConta.getValorPago())) > Math .abs(Util.arredondar(faturaCartao.getValorFatura() + faturaCartao.getSaldoDevedor()))) { throw new BusinessException("No possvel quitar um valor maior que o valor total da fatura!"); } FaturaCartao fatura = getRepository().findById(faturaCartao.getId()); fatura.setStatusFaturaCartao(StatusFaturaCartao.QUITADA); fatura.setDataPagamento(lancamentoConta.getDataPagamento()); fatura.setValorPago(lancamentoConta.getValorPago()); fatura.setValorMinimo(faturaCartao.getValorMinimo()); double saldoDevedor = (faturaCartao.getValorFatura() + faturaCartao.getSaldoDevedor()) - lancamentoConta.getValorPago(); // Atribui o lanamento fatura fatura.setLancamentoPagamento(lancamentoConta); // Salva a fatura paga getRepository().update(fatura); // Busca a fatura aberta e atribui o saldo devedor a ela. Depois salva FaturaCartao faturaAtual = getRepository().findFaturaCartaoAberta(faturaCartao.getConta()); faturaAtual.setSaldoDevedor(saldoDevedor); getRepository().update(faturaAtual); } @Override public List<FaturaCartao> buscarTodosPorCartaoCredito(Conta conta) { return getRepository().findAllByCartaoCredito(conta); } @Override public List<FaturaCartao> buscarTodos() { return getRepository().findAll(); } @Override public List<FaturaCartao> buscarTodosPorUsuario(Usuario usuario) { return getRepository().findAllByUsuario(usuario); } @Override public List<FaturaCartao> buscarPorCartaoCreditoEStatusFatura(CartaoCredito cartao, StatusFaturaCartao statusFatura) { return getRepository().findByContaAndStatusFatura(cartao.getConta(), statusFatura); } @Override public List<FaturaCartao> buscarTodosPorContaOrdenadoPorMesEAno(Conta conta) { return getRepository().findAllByContaOrderedByMesAndAno(conta); } @Override public List<FaturaCartao> buscarTodosPorContaEAnoOrdenadosPorMesAno(Conta conta, int ano) { return getRepository().findAllByContaAndAnoOrderedByMesAndAno(conta, ano); } }