AdmMono/src/com/rjconsultores/ventaboletos/service/impl/CalculoComissaoServiceImpl....

533 lines
20 KiB
Java
Raw Blame History

package com.rjconsultores.ventaboletos.service.impl;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rjconsultores.ventaboletos.constantes.Constantes;
import com.rjconsultores.ventaboletos.dao.ComissaoDAO;
import com.rjconsultores.ventaboletos.entidad.Comissao;
import com.rjconsultores.ventaboletos.entidad.DescontoComissao;
import com.rjconsultores.ventaboletos.entidad.PtovtaComissao;
import com.rjconsultores.ventaboletos.entidad.PtovtaComissao.Receita;
import com.rjconsultores.ventaboletos.enums.IndStatusBoleto;
import com.rjconsultores.ventaboletos.exception.ComissaoException;
import com.rjconsultores.ventaboletos.service.CalculoComissaoService;
import com.rjconsultores.ventaboletos.service.ComissaoService;
import com.rjconsultores.ventaboletos.service.DescontoComissaoService;
import com.rjconsultores.ventaboletos.service.PtovtaComissaoService;
import com.rjconsultores.ventaboletos.utilerias.DateUtil;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.comissao.BoletoComissao;
import com.rjconsultores.ventaboletos.vo.comissao.ComissaoDesconto;
import com.rjconsultores.ventaboletos.vo.comissao.ComissaoDesconto.TipoDesconto;
import com.rjconsultores.ventaboletos.vo.comissao.ComissaoReceita;
import com.rjconsultores.ventaboletos.vo.comissao.RegistroCalculo;
@Service("calculoComissaoService")
public class CalculoComissaoServiceImpl implements CalculoComissaoService {
private static final Logger log = LoggerFactory.getLogger(CalculoComissaoServiceImpl.class);
private static final BigDecimal CEM = BigDecimal.TEN.multiply(BigDecimal.TEN);
@Autowired
private PtovtaComissaoService ptovtaComissaoService;
@Autowired
private ComissaoService comissaoService;
@Autowired
private ComissaoDAO comissaoDAO;
@Autowired
private DescontoComissaoService descontoComissaoService;
public boolean validaCompetencia(Date periodo) {
Calendar calendario = Calendar.getInstance();
calendario.setTime(periodo);
int mes = calendario.get(Calendar.MONTH) + 1;
int ano = calendario.get(Calendar.YEAR);
Calendar now = Calendar.getInstance();
int mesNow = now.get(Calendar.MONTH) + 1;
int anoNow = now.get(Calendar.YEAR);
if (anoNow == ano) {
if (mesNow > mes) {
return true;
}
} else if (anoNow > ano) {
return true;
}
return false;
}
@Override
public void registrarCalculoComissao(Integer puntoVentaId, Integer empresaId, Date periodo) throws ComissaoException {
if (validaCompetencia(periodo)) {
String competencia = DateUtil.getStringDate(periodo, "MM/yyyy");
List<Comissao> comissoes = comissaoDAO.buscaComissaoVigencia(puntoVentaId, empresaId, competencia);
if (comissoes.isEmpty()) {
RegistroCalculo rc = realizarCalculoComissao(puntoVentaId, empresaId, periodo);
Comissao comissao = new Comissao();
comissao.setCompetencia(competencia);
comissao.setDataPagamento(Calendar.getInstance().getTime());
comissao.setEmpresaId(empresaId);
comissao.setPuntoVentaId(puntoVentaId);
comissao.setBonificacaoMetas(rc.getComissaoBonificaoMetas());
comissao.setComissaoBpr(rc.getComissaoBPR());
comissao.setEntregasPassagem(rc.getComissaoEntregaPassagem());
comissao.setReceitaExcessobagagem(rc.getComissaoExcessoBagagem());
comissao.setReceitaSeguroopcional(rc.getComissaoSegOpcional());
comissao.setReceitaOutros(rc.getComissaoOutros());
comissao.setRoyaties(rc.getRoyaties());
comissao.setIssRetido(rc.getRetidoISS());
comissao.setBonificacaoMetas(rc.getComissaoBonificaoMetas());
comissao.setDescontosEventuais(rc.getDescontos());
comissao.setIndPago(true);
comissao.setUsuarioPagamentoId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
comissao = comissaoService.suscribir(comissao);
} else {
throw new ComissaoException("busquedaCalculoComissaoController.registro.exception");
}
} else {
throw new ComissaoException("busquedaCalculoComissaoController.competencia.exception");
}
}
@Override
public RegistroCalculo relatorioCalculoComissao(Integer puntoVentaId, Integer empresaId, Date periodo) {
return realizarCalculoComissao(puntoVentaId, empresaId, periodo);
}
private BigDecimal calculoComisssaoBPR(boolean isAltaTemporada, PtovtaComissao ptovtaComissao, ComissaoReceita cr) {
// Comiss<73>o BPR = Receita Comiss<73>o * (% Com BPR)
BigDecimal bpr = BigDecimal.ZERO;
BigDecimal receitaBPR = cr.getReceitaBPR().add(cr.getReceitaGAP());
if (isAltaTemporada) {
bpr = receitaBPR.multiply(ptovtaComissao.getPassagemAlta().divide(CEM));
} else {
bpr = receitaBPR.multiply(ptovtaComissao.getPassagemBaixa().divide(CEM));
}
return bpr;
}
private BigDecimal calculoEntregaPassagem(boolean isAltaTemporada, PtovtaComissao ptovtaComissao, ComissaoReceita cr) {
// EntregaPassagem (Internet/Venda Impress<73>o Posterior/Outros)
BigDecimal entregaPassagem = BigDecimal.ZERO;
BigDecimal receitaEntrega = cr.getGapImpressa().add(cr.getInternet());
if (ptovtaComissao.getIndimpressaogapporc()) {
entregaPassagem = receitaEntrega.multiply(ptovtaComissao.getValorImpressaoGap().divide(CEM));
} else {
entregaPassagem = ptovtaComissao.getValorImpressaoGap().multiply(new BigDecimal(cr.getContImpressa()));
}
return entregaPassagem;
}
private BigDecimal calculoExcessoBagagem(boolean isAltaTemporada, PtovtaComissao ptovtaComissao, ComissaoReceita cr) {
// Comiss<73>o Excesso = Receita Excesso Bagagem * (% Com. Exc. Bag)
BigDecimal excessoBagagem = BigDecimal.ZERO;
if (isAltaTemporada) {
excessoBagagem = cr.getReceitaExcessoBagagem().multiply(ptovtaComissao.getExcessoAlta().divide(CEM));
} else {
excessoBagagem = cr.getReceitaExcessoBagagem().multiply(ptovtaComissao.getExcessoBaixa().divide(CEM));
}
return excessoBagagem;
}
private BigDecimal calculoSeguroOpcional(boolean isAltaTemporada, PtovtaComissao ptovtaComissao, ComissaoReceita cr) {
// Comiss<73>o Seg. Opcional = Receita Seguro Opcional * (% Com. Seg. Pol)
BigDecimal segOpcional = BigDecimal.ZERO;
if (isAltaTemporada) {
segOpcional = cr.getReceitaSeguroOpcional().multiply(ptovtaComissao.getSeguroAlta().divide(CEM));
} else {
segOpcional = cr.getReceitaSeguroOpcional().multiply(ptovtaComissao.getSeguroBaixa().divide(CEM));
}
return segOpcional;
}
private BigDecimal calculoOutros(boolean isAltaTemporada, PtovtaComissao ptovtaComissao, ComissaoReceita cr) {
// Comiss<73>o Seg. Opcional = Receita Seguro Opcional * (% Com. Seg. Pol)
BigDecimal outros = BigDecimal.ZERO;
if (isAltaTemporada) {
outros = cr.getReceitaSeguroOutros().multiply(ptovtaComissao.getOutrosAlta().divide(CEM));
} else {
outros = cr.getReceitaSeguroOutros().multiply(ptovtaComissao.getOutrosBaixa().divide(CEM));
}
return outros;
}
private Map<String, Object> calculoDescontos(Integer puntoVentaId, Integer empresaId, Date periodo, PtovtaComissao ptovtaComissao) {
List<ComissaoDesconto> lsDescontos = new ArrayList<ComissaoDesconto>();
BigDecimal valorDescontoTotal = BigDecimal.ZERO;
Date inicioPeriodo = DateUtil.inicioFechaPeriodoMeses(periodo);
Date fimPeriodo = DateUtil.fimFechaPeriodoMeses(periodo);
List<DescontoComissao> itensDescontos = descontoComissaoService.buscaDescontoComissaoPeriodo(puntoVentaId, empresaId, inicioPeriodo, fimPeriodo);
for (DescontoComissao dc : itensDescontos) {
BigDecimal valorDesconto = dc.getPreco();
valorDescontoTotal = valorDescontoTotal.add(valorDesconto);
ComissaoDesconto desconto = new ComissaoDesconto();
if (dc.getDatafinal() == null) {
desconto.setTipo(TipoDesconto.FIXO);
} else {
desconto.setTipo(TipoDesconto.EVENTUAL);
}
desconto.setNomeDesconto(dc.getItemDesconto().getNomitemdesconto());
desconto.setValorDesconto(valorDesconto);
lsDescontos.add(desconto);
}
Map<String, Object> respDescontos = new HashMap<String, Object>();
respDescontos.put("LISTA_DESCONTOS", lsDescontos);
respDescontos.put("VALOR_DESCONTOS", valorDescontoTotal);
return respDescontos;
}
@SuppressWarnings("unchecked")
public RegistroCalculo realizarCalculoComissao(Integer puntoVentaId, Integer empresaId, Date periodo) {
PtovtaComissao ptovtaComissao = ptovtaComissaoService.buscarPuntaVentaEmpresa(puntoVentaId, empresaId);
List<BoletoComissao> receitasBoleto = comissaoDAO.buscarReceitasComissoes(puntoVentaId, empresaId, periodo);
Calendar calendario = Calendar.getInstance();
calendario.setTime(periodo);
int ultimodia = calendario.getActualMaximum(Calendar.DAY_OF_MONTH);
int mes = calendario.get(Calendar.MONTH) + 1;
int ano = calendario.get(Calendar.YEAR);
List<ComissaoReceita> receitas = calculaReceitaComissao(ptovtaComissao, receitasBoleto, ultimodia, mes, ano);
RegistroCalculo rc = new RegistroCalculo();
BigDecimal comissaoBPR = BigDecimal.ZERO;
BigDecimal comissaoExcessoBagagem = BigDecimal.ZERO;
BigDecimal comissaoSegOpcional = BigDecimal.ZERO;
BigDecimal comissaoEntregaPassagem = BigDecimal.ZERO;
BigDecimal comissaoOutros = BigDecimal.ZERO;
BigDecimal receitaTotal = BigDecimal.ZERO;
for (ComissaoReceita cr : receitas) {
// Est<73> parte esta encapsulada, posteriormente ser<65> implementada a valida<64><61>o de alta e baixa temporada
// Inicialmente s<> ser<65> validado os calculos de comiss<73>o em baixa temporada
boolean isAltaTemporada = false;
receitaTotal = receitaTotal.add(cr.getReceitaComissao());
BigDecimal bpr = calculoComisssaoBPR(isAltaTemporada, ptovtaComissao, cr);
cr.setComissaoBPRDiaria(bpr);
comissaoBPR = comissaoBPR.add(bpr);
BigDecimal entregaPassagem = calculoEntregaPassagem(isAltaTemporada, ptovtaComissao, cr);
cr.setComissaoEntregaPassagemDiaria(entregaPassagem);
comissaoEntregaPassagem = comissaoEntregaPassagem.add(entregaPassagem);
BigDecimal excessoBagagem = calculoExcessoBagagem(isAltaTemporada, ptovtaComissao, cr);
cr.setComissaoExcessoBagagemDiaria(excessoBagagem);
comissaoExcessoBagagem = comissaoExcessoBagagem.add(excessoBagagem);
BigDecimal segOpcional = calculoSeguroOpcional(isAltaTemporada, ptovtaComissao, cr);
cr.setComissaoSegOpcionalDiaria(segOpcional);
comissaoSegOpcional = comissaoSegOpcional.add(segOpcional);
BigDecimal outros = calculoOutros(isAltaTemporada, ptovtaComissao, cr);
cr.setComissaoOutrosDiaria(outros);
comissaoOutros = comissaoOutros.add(outros);
}
rc.setLsReceitas(receitas);
rc.setComissaoBPR(comissaoBPR);
rc.setComissaoExcessoBagagem(comissaoExcessoBagagem);
rc.setComissaoSegOpcional(comissaoSegOpcional);
rc.setComissaoEntregaPassagem(comissaoEntregaPassagem);
rc.setComissaoOutros(comissaoOutros);
// Descontos (Fixos e Eventuais)
Map<String, Object> respDescontos = calculoDescontos(puntoVentaId, empresaId, periodo, ptovtaComissao);
rc.setDescontos((BigDecimal) respDescontos.get("VALOR_DESCONTOS"));
rc.setLsDescontos((List<ComissaoDesconto>) respDescontos.get("LISTA_DESCONTOS"));
// Bonifica<63><61>o Metas
BigDecimal comissaoBonificaoMetas = BigDecimal.ZERO;
rc.setComissaoBonificaoMetas(comissaoBonificaoMetas);
// Royaties
BigDecimal royaties = BigDecimal.ZERO;
royaties = receitaTotal.multiply(ptovtaComissao.getRoyalties().divide(CEM));
rc.setRoyaties(royaties);
// ISS retido
BigDecimal issRetido = BigDecimal.ZERO;
issRetido = receitaTotal.multiply(ptovtaComissao.getIssretido().divide(CEM));
rc.setRetidoISS(issRetido);
// Comiss<73>o <20> pagar = Comiss<73>o BPR + Comiss<73>o Excesso Bagagem + Comiss<73>o Seg. Opcional + Bonifica<63><61>o Metas + Internet(EntregaPassagem)
BigDecimal comissaoPagar = BigDecimal.ZERO;
comissaoPagar = comissaoPagar.add(comissaoBPR).add(comissaoExcessoBagagem).add(comissaoSegOpcional);
comissaoPagar = comissaoPagar.add(comissaoEntregaPassagem).add(comissaoOutros);
comissaoPagar = comissaoPagar.add(comissaoBonificaoMetas);
// - Descontos (Fixos e Eventuais) - Royaties - ISS retido
comissaoPagar = comissaoPagar.add(rc.getDescontos().negate()).add(royaties.negate()).add(issRetido.negate());
rc.setComissaoPagar(comissaoPagar);
return rc;
}
private List<ComissaoReceita> calculaReceitaComissao(PtovtaComissao ptovtaComissao, List<BoletoComissao> receitasBoleto, Integer ultimodia, Integer mes, Integer ano) {
List<ComissaoReceita> receitas = new ArrayList<ComissaoReceita>();
for (int dia = 1; dia <= ultimodia; dia++) {
List<BoletoComissao> list = verificaCalculoComissaoProDia(receitasBoleto, dia, mes);
Calendar dataRegistro = Calendar.getInstance();
dataRegistro.set(Calendar.DAY_OF_MONTH, dia);
dataRegistro.set(Calendar.MONTH, mes - 1);
dataRegistro.set(Calendar.YEAR, ano);
ComissaoReceita cr = new ComissaoReceita();
cr.setData(dataRegistro.getTime());
BigDecimal receitaComissao = BigDecimal.ZERO;
BigDecimal receitaBPR = BigDecimal.ZERO;
BigDecimal receitaGAP = BigDecimal.ZERO;
BigDecimal internet = BigDecimal.ZERO;
BigDecimal receitaExcessoBagagem = BigDecimal.ZERO;
BigDecimal receitaSeguroOpcional = BigDecimal.ZERO;
BigDecimal receitaSeguroOutros = BigDecimal.ZERO;
BigDecimal cancelados = BigDecimal.ZERO;
BigDecimal devolvidos = BigDecimal.ZERO;
BigDecimal devolvidosOrigem = BigDecimal.ZERO;
BigDecimal canceladosGAP = BigDecimal.ZERO;
BigDecimal devolvidosGAP = BigDecimal.ZERO;
BigDecimal devolvidosGAPOrigem = BigDecimal.ZERO;
BigDecimal gapImpressa = BigDecimal.ZERO;
int contImpressa = 0;
// Receita Total -- bruta/liquida - abatimento do valor do icms
boolean isReceitaLiquida = false;
Receita receita = Receita.getByValor(ptovtaComissao.getReceita());
if (receita.equals(Receita.RECEITALIQUIDA)) {
isReceitaLiquida = true;
}
for (BoletoComissao rcc : list) {
IndStatusBoleto statusBoleto = IndStatusBoleto.valueOf(rcc.getIndstatusboleto());
BigDecimal receitaItem = BigDecimal.ZERO;
BigDecimal receitaDevItem = BigDecimal.ZERO;
// Totais
if (ptovtaComissao.getTarifaReceita()) {
receitaItem = receitaItem.add(rcc.getValorpagado());
}
if (ptovtaComissao.getTaxaReceita()) {
receitaItem = receitaItem.add(rcc.getEmbarque());
}
if (ptovtaComissao.getSeguroReceita()) {
receitaItem = receitaItem.add(rcc.getSeguro());
}
if (ptovtaComissao.getPedagioReceita()) {
receitaItem = receitaItem.add(rcc.getPedagio());
}
// Totais de Devolu<6C><75>o / Cancelamento
if (ptovtaComissao.getTarifaDev()) {
receitaDevItem = receitaDevItem.add(rcc.getValorpagado());
}
if (ptovtaComissao.getTaxaDev()) {
receitaDevItem = receitaDevItem.add(rcc.getEmbarque());
}
if (ptovtaComissao.getSeguroDev()) {
receitaDevItem = receitaDevItem.add(rcc.getSeguro());
}
if (ptovtaComissao.getPedagioDev()) {
receitaDevItem = receitaDevItem.add(rcc.getPedagio());
}
// Calculo de ICMS sobre o valor do bilhete
if (isReceitaLiquida) {
BigDecimal icsm = BigDecimal.ZERO;
icsm = receitaItem.multiply(rcc.getIcmsBase().divide(CEM));
receitaItem = receitaItem.add(icsm.negate());
BigDecimal icsmDev = BigDecimal.ZERO;
icsmDev = receitaDevItem.multiply(rcc.getIcmsBase().divide(CEM));
receitaDevItem = receitaDevItem.add(icsmDev.negate());
}
// Boletos impressos no punto venta
if (statusBoleto.equals(IndStatusBoleto.E)) {
contImpressa++;
gapImpressa = gapImpressa.add(receitaItem);
} else {
// Receitas calculadas sempre
receitaExcessoBagagem = receitaExcessoBagagem.add(rcc.getExcessoBagagem());
receitaSeguroOpcional = receitaSeguroOpcional.add(rcc.getSeguroOpcional());
receitaSeguroOutros = receitaSeguroOutros.add(rcc.getSeguroOutros());
// Receita GAP
if (rcc.getTipoVenta().equals(Constantes.TPV_BOLETO_REMOTO.intValue())) {
receitaGAP = receitaGAP.add(receitaItem);
}
// Internet
else if (rcc.getTipoVenta().equals(Constantes.TPV_POR_INTERNET.intValue())) {
internet = internet.add(receitaItem);
}
// Receita BPR
else {
receitaBPR = receitaBPR.add(receitaItem);
}
}
if (statusBoleto.equals(IndStatusBoleto.C)) {
// Devolu<6C><75>o Receita
if (rcc.getMotivoCancelacionId().equals(Constantes.MVO_CANCEL_DEVOLUCAO)) {
// Devolu<6C><75>o Receita GAP
if (rcc.getTipoVenta().equals(Constantes.TPV_BOLETO_REMOTO.intValue())) {
// Impresso Venta de otro punto venta
if (rcc.isPtoVtaOrigem()) {
devolvidosGAPOrigem = devolvidosGAPOrigem.add(receitaDevItem);
}
devolvidosGAP = devolvidosGAP.add(receitaDevItem);
} else {
// Impresso Venta de otro punto venta
if (rcc.isPtoVtaOrigem()) {
devolvidosOrigem = devolvidosOrigem.add(receitaDevItem);
}
devolvidos = devolvidos.add(receitaDevItem);
}
}
// Cancelamento Receita
else {
// Cancelamento Receita GAP
if (rcc.getTipoVenta().equals(Constantes.TPV_BOLETO_REMOTO.intValue())) {
canceladosGAP = canceladosGAP.add(receitaDevItem);
} else {
cancelados = cancelados.add(receitaDevItem);
}
}
}
}
cr.setCancelados(cancelados);
cr.setCanceladosGAP(canceladosGAP);
cr.setDevolvidos(devolvidos);
cr.setDevolvidosGAP(devolvidosGAP);
cr.setDevolucoesOrigem(devolvidosOrigem);
cr.setDevolucoesOrigemGAP(devolvidosGAPOrigem);
cr.setReceitaBPR(receitaBPR);
cr.setReceitaExcessoBagagem(receitaExcessoBagagem);
cr.setReceitaGAP(receitaGAP);
cr.setReceitaSeguroOpcional(receitaSeguroOpcional);
cr.setReceitaSeguroOutros(receitaSeguroOutros);
cr.setInternet(internet);
cr.setGapImpressa(gapImpressa);
cr.setContImpressa(contImpressa);
// Receita Comiss<73>o = Receita BPR + Receita GAP - GapImpressa - Internet
// - Cancelados - Devolu<6C><75>es Origem - Cancelados GAP - Devolu<6C><75>es GAP Origem - Devolu<6C><75>es - Devolu<6C><75>es GAP
receitaComissao = receitaComissao.add(receitaBPR).add(receitaGAP);
receitaComissao = receitaComissao.add(gapImpressa.negate()).add(internet.negate()).add(cancelados.negate());
receitaComissao = receitaComissao.add(devolvidosOrigem.negate()).add(devolvidos.negate()).add(canceladosGAP.negate());
receitaComissao = receitaComissao.add(devolvidosGAPOrigem.negate()).add(devolvidosGAP.negate());
cr.setReceitaComissao(receitaComissao);
receitas.add(cr);
}
return receitas;
}
private List<BoletoComissao> verificaCalculoComissaoProDia(List<BoletoComissao> list, Integer dia, Integer mes) {
List<BoletoComissao> aux = new ArrayList<BoletoComissao>();
for (BoletoComissao rcc : list) {
try {
Calendar calendario = Calendar.getInstance();
calendario.setTime(DateUtil.getDateFromString(rcc.getDatavenda(), "dd-MM-yyyy"));
int diaItem = calendario.get(Calendar.DAY_OF_MONTH);
int mesItem = calendario.get(Calendar.MONTH) + 1;
if (dia.equals(diaItem) && mes.equals(mesItem)) {
aux.add(rcc);
}
} catch (ParseException e) {
log.error("ERRO - ao converter data", e);
}
}
return aux;
}
}