/* * * Copyright (c) 2013 - 2014 INT - National Institute of Technology & COPPE - Alberto Luiz Coimbra Institute - Graduate School and Research in Engineering. * See the file license.txt for copyright permission. * */ package service; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import comparator.PlPerModComparatorPorPerioPM; import service.anotacao.Transacional; import service.controleTransacao.FabricaDeAppService; import service.exception.AplicacaoException; import DAO.Impl.HPDAOImpl; import DAO.Impl.PerioPMVigDAOImpl; import DAO.Impl.PMPDAOImpl; import DAO.Impl.ModeloDAOImpl; import DAO.controle.FabricaDeDao; import DAO.exception.ObjetoNaoEncontradoException; import DAO.HPDAO; import DAO.PerioPMVigDAO; import DAO.PMPDAO; import DAO.ModeloDAO; import modelo.CadPlan; import modelo.HP; import modelo.HPVig; import modelo.PerioPM; import modelo.PerioPMVig; import modelo.PMP; import modelo.Modelo; import modelo.PlPerMod; import modelo.PlanoModelo; /** * * As classes de servi�o � que possuem as regras de neg�cio. Fazem as cr�ticas * quando necess�rio e chamam as classes DAO para pegar as informa��es do BD. * * S�o essas classes AppService que fazem o controle de transa�ao, ou seja quem * abre a transa�ao, "quem commita" atrav�s do interceptador de appservice. Aqui * defino se o metodo � transacional ou n�o e em fun�ao desta informa�ao o * interceptador vai usar ou nao transacao. * * * * * @author felipe/daysemou * */ public class PMPAppService { // DAOs private static PMPDAO pmpDAO; private static HPDAO hpDAO; private static PerioPMVigDAO perioPMVigDAO; private static ModeloDAO modeloDAO; // Services private static PerioPMVigAppService perioPMVigService; private static ModeloAppService modeloService; private static PlanoModeloAppService planoModeloService; private static PlPerModAppService plPerModService; private static PerioPAPVigAppService perioPAPVigService; private static HPVigAppService hpVigService; @SuppressWarnings("unchecked") public PMPAppService() { try { // DAOs pmpDAO = FabricaDeDao.getDao(PMPDAOImpl.class); hpDAO = FabricaDeDao.getDao(HPDAOImpl.class); perioPMVigDAO = FabricaDeDao.getDao(PerioPMVigDAOImpl.class); modeloDAO = FabricaDeDao.getDao(ModeloDAOImpl.class); // Services modeloService = FabricaDeAppService.getAppService(ModeloAppService.class); plPerModService = FabricaDeAppService.getAppService(PlPerModAppService.class); planoModeloService = FabricaDeAppService.getAppService(PlanoModeloAppService.class); perioPMVigService = FabricaDeAppService.getAppService(PerioPMVigAppService.class); perioPAPVigService = FabricaDeAppService.getAppService(PerioPAPVigAppService.class); hpVigService = FabricaDeAppService.getAppService(HPVigAppService.class); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * A inclus�o do PMP vigente � feita a partir da op��o implementaPlanoMestre no cadastro de Planos * * * * @param pmp * @return * @throws AplicacaoException */ @Transacional public long inclui(PMP pmp) throws AplicacaoException { long retorno = -1; PMP pmpBD = null; // verifica se existe o modelo a que se refere o registro PMP try { modeloDAO.getPorIdComLock(pmp.getModelo().getId()); } catch(ObjetoNaoEncontradoException e) { throw new AplicacaoException("modelo.NAO_ENCONTRADO"); } // verifica se existe o perioPMVig a que se refere o registro PMP try { perioPMVigDAO.getPorIdComLock(pmp.getPerioPMVig().getId()); } catch(ObjetoNaoEncontradoException e) { throw new AplicacaoException("perioPMVig.NAO_ENCONTRADO"); } // verifica se o modelo j� esta relacionado com este perioPMVig try { pmpBD = pmpDAO.recuperaPMPPorModeloEPerioPMVig(pmp.getModelo(), pmp.getPerioPMVig()); throw new AplicacaoException("capacRec.ENCONTRADO_PERIOPM"); } catch (ObjetoNaoEncontradoException ob) { //o modelo e o perioPMVig serao setados no implementa plano do plpermod, que � o responsavel pela inclusao retorno = pmpDAO.inclui(pmp).getId(); } return retorno; } @Transacional public void implementaPlanoMestre(CadPlan cadPlan) throws AplicacaoException { //===Verifica se todos os modelos desse plano foram planejados SortedSet<PlanoModelo> setDePlanoModelos = new TreeSet<PlanoModelo>(cadPlan.getPlanosModelo()); for(PlanoModelo planoModelo : setDePlanoModelos){ if(!planoModelo.isModeloPlanejado()){ throw new AplicacaoException("PMP.MODELO_NAO_PLANEJADO"); } } //===Apaga todos os registros de plano mestre vigente atual //===Apaga plano mestre vigente atual List<PMP> listaDePMPs = pmpDAO.recuperaListaDePMPs(); for(PMP pmp : listaDePMPs){ this.exclui(pmp); } //===Apaga todos os registros de PerioPMVig, PerioPAPVig, HPVig hpVigService.apagaTodos(); perioPMVigService.apagaTodos(); perioPAPVigService.apagaTodos(); //===Inclui copiando todos os PerioPMVig, PerioPAPVig, HPVig perioPAPVigService.incluiCopiandoTodosPerioPAPs(); perioPMVigService.incluiCopiandoTodosPerioPMs(); hpVigService.incluiCopiandoTodosHPs(); HP hp = hpDAO.recuperaListaDeHP().get(0); for(PlanoModelo planoModelo : setDePlanoModelos){ // System.out.println("plano modelo: "+planoModelo.getCadPlan()); try { planoModelo = planoModeloService.recuperarPlPerModsPorPlanoModelo(planoModelo); SortedSet<PlPerMod> setDePlPerMods = new TreeSet<PlPerMod>(new PlPerModComparatorPorPerioPM()); setDePlPerMods.addAll(planoModelo.getPlPerMods()); // ArrayList<Double> dispEntregas = plPerModService.calculaDisponibilidadeDeEntregaDiscreta(planoModelo,hp); for(PlPerMod plPerMod : setDePlPerMods){ // System.out.println("plpermod: "+plPerMod.getPerioPM()); this.incluiCopiandoPlPerMod(plPerMod); } //depois de copiar os plpermods, altera o modelo referente a esse plano modelo para que os valores //dos campos relativos a pmp sejam atualizados modeloService.atualizaCamposPMP(planoModelo.getModelo()); this.calculaDisponibilidadeDeEntregaDiscreta(planoModelo.getModelo()); } catch (ObjetoNaoEncontradoException e) { e.printStackTrace(); } } //Apaga o planoAgregadoVigente e copia o plano selecionado para o Plano Agregado Vigente, //ou seja copia o conteudo do arquivo plperfam referente a este cadPlan para o arquivo PAP. //calcaula e grava o parametro disponibilidade de entrega para o plano mestre vigente //(Ver procedure CalculaDisponibilidadeDeEntrega) return; } @Transacional public void incluiCopiandoPlPerMod(PlPerMod plPerMod) throws AplicacaoException { PMP pmp = new PMP(); pmp.setCoberturaModel(plPerMod.getCoberturaModel()); // pmp.setDisponibEntrega(dispEntrega); pmp.setDispProjModel(plPerMod.getDispProjModel()); pmp.setEscorePlanPerMod(plPerMod.getEscorePlanPerMod()); pmp.setModelo(plPerMod.getPlanoModelo().getModelo()); pmp.setPedidosModel(plPerMod.getPedidosModel()); pmp.setPeriodoPMInicioPMP(plPerMod.getPeriodoPMInicioPMP()); PerioPMVig perioPMVig = new PerioPMVig(); try { perioPMVig = perioPMVigDAO.recuperaPerioPMVigPorPeriodoPM(plPerMod.getPerioPM().getPeriodoPM()); } catch (ObjetoNaoEncontradoException e) { } pmp.setPerioPMVig(perioPMVig); pmp.setProdDiariaLoteModel(plPerMod.getProdDiariaLoteModel()); pmp.setProdLoteModel(plPerMod.getProdLoteModel()); pmp.setProducaoModel(plPerMod.getProducaoModel()); pmp.setVarEstqPerc(plPerMod.getVarEstqPerc()); pmp.setVarProdDiaPerc(plPerMod.getVarProdDiaPerc()); pmp.setVendasModel(plPerMod.getVendasModel()); this.inclui(pmp); return; } /** * Retorna o pmp que contem o proximo recebimento, dado: * o periodo em que deve comecar a procurar; * a lista de PMPs que deve percorrer; * o vetor de recebimentos que foram verificados; * * @param periodo * @param plPerModList * @param vetorRecebimentoVerificados * @return */ @Transacional public PMP localizaProximoRecebimentoSimples(int periodo, List<PMP> pmpList){ for(int i=periodo-1;i < pmpList.size(); i++){ PMP pmpCorrente = pmpList.get(i); //se tiver recebimento nesse periodo entao marca esse periodo como verificado e retorna o mesmo plpermod. if(pmpCorrente.getProducaoModel()!= 0){ return pmpCorrente; } } //se chegar nesse ponto quer dizer que nao encontrou nenhum recebimento e retorna null return null; } /** * Retorna o sum dos pedidos acumulados num intervalo de periodo para um dado modelo. * quando o periodo final for menor que o periodo inicial, considera que est� querendo analizar apenas o periodo * inicial em particular. * * @param modelo * @param periodoPMInicial * @param periodoPMFinal * @return */ @Transacional public double calculaPedidosAcumuladosNoIntervaloParaModelo(Modelo modelo, int periodoPMInicial, int periodoPMFinal){ double pedidosAcumulados = 0.0; //entra nesse caso quando temos algo do tipo: //periodo inicial = 2 //periodo final = 1 //causado pelo fato de que o priprio periodo 2 teve o recebimento, e o algoritimo tenta fazer //para n -1 //mas nesse caso deve considerar apenas o priprio periodo 2. if(periodoPMFinal < periodoPMInicial){ return pedidosAcumulados; } List<PMP> intervaloPMPs = pmpDAO.recuperaIntervaloDePMPPorModeloEIntervaloDePerioPMVig (modelo, periodoPMInicial, periodoPMFinal); for(PMP pmp: intervaloPMPs){ pedidosAcumulados += pmp.getPedidosModel(); } return pedidosAcumulados; } /** * Implementando algoritmo para o calculo discreto da Disponibilidade de Entrega * * @param modelo */ @Transacional public void calculaDisponibilidadeDeEntregaDiscreta(Modelo modelo){ //calcula o estoque total desse modelo: double estqInicCalculado = modelo.getEstqInicModelPMP() + modelo.getRecebimentoPendentePMP() - modelo.getEstqEmFaltaPMP(); List<PMP> listaDePMPDoModelo = pmpDAO.recuperaListaDePMPsPorModeloComPerioPMVigs(modelo); //Para cada periodo de 1 at� o final do hp vigente for(PMP pmpCorrente : listaDePMPDoModelo){ double dispEntrega= 0.0; //Recupera um pmp correspondente a cada periodo para esse modelo //calcula a dispEntrega para ele. System.out.println("localizando para:"+pmpCorrente.getPerioPMVig()); //localiza o proximo recebimento, considerando que deve comecar a procurar desconsiderando o proprio periodo //que esta sendo calculado no momento. PMP pmpProxRecebimento = this.localizaProximoRecebimentoSimples(pmpCorrente.getPerioPMVig().getPeriodoPM()+1, listaDePMPDoModelo); //j� considera o pedido do proprio periodo, logo em seguida � somado o pedido dos proximos periodos, //at� o pedido do periodo n-1 double pedidosAcumulados = pmpCorrente.getPedidosModel(); Integer numPeriodoProxRecebimento; //se for null quer dizer que n�o existe recebimento nos periodos seguintes a esse. //logo deve considerar que vai acumular os pedidos desde o periodo corrente at� o ultimo //periodo do hp. if(pmpProxRecebimento!= null){ numPeriodoProxRecebimento = pmpProxRecebimento.getPerioPMVig().getPeriodoPM(); } else{ PMP ultimoPMP = listaDePMPDoModelo.get(listaDePMPDoModelo.size()-1); numPeriodoProxRecebimento = ultimoPMP.getPerioPMVig().getPeriodoPM()+1; } //calcula os pedidos acumulados para o intervalo do periodo seguinte ao que est� sendo analisado at� o //periodo do proximo recebimento -1 //soma esses valores acumulados de pedidos ao valor que j� havia antes(isso �, o do proprio periodo) pedidosAcumulados += this.calculaPedidosAcumuladosNoIntervaloParaModelo (modelo,pmpCorrente.getPerioPMVig().getPeriodoPM()+1, numPeriodoProxRecebimento-1); //se for o primeiro periodo faz um calculo diferente if(pmpCorrente.getPerioPMVig().getPeriodoPM()==1){ //calcula a disponibilidade de entrega para o primeiro periodo dispEntrega = estqInicCalculado + pmpCorrente.getProducaoModel() - pedidosAcumulados; } else{ //se recebimento de producao for igual a 0 a DispEntrega � zero if(pmpCorrente.getProducaoModel() == 0){ dispEntrega= 0.0; } else{ dispEntrega = pmpCorrente.getProducaoModel() - pedidosAcumulados; } } if(dispEntrega<0){ dispEntrega=0.0; } //altera o valor da disponibilidade de entrega do plPermod corrente para a calculada pmpCorrente.setDisponibEntrega(dispEntrega); this.altera(pmpCorrente); } return; } /** A principio nao tera alteracao de um pmp */ @Transacional public void altera(PMP pmp) { pmpDAO.altera(pmp); } @Transacional public void exclui(PMP umPMP) throws AplicacaoException { PMP pmp = null; try { pmp = pmpDAO.getPorIdComLock((umPMP.getId())); } catch (ObjetoNaoEncontradoException e) { throw new AplicacaoException("PMP.NAO_ENCONTRADO"); } pmpDAO.exclui(pmp); } /** * Usa um m�todo do DAO para recuperar um PMP juntamente com o seu perioPMVig * * @author dayse.arruda * @throws AplicacaoException */ public PMP recuperaPMPComPerioPMVig(PMP pmp) throws AplicacaoException { try { return pmpDAO.recuperaPMPComPerioPMVig(pmp); } catch (ObjetoNaoEncontradoException e) { throw new AplicacaoException("PMP.NAO_ENCONTRADO"); } } public PMP recuperaPMPPorModeloEPerioPMVig(Modelo modelo, PerioPMVig perioPMVig) throws AplicacaoException { try { return pmpDAO.recuperaPMPPorModeloEPerioPMVig(modelo, perioPMVig); } catch (ObjetoNaoEncontradoException e) { throw new AplicacaoException("PMP.NAO_ENCONTRADO"); } } /** * * Usa PMPDAO para recuperar lista de todos os PMPs. Retorna um List * de PMPs * * @author felipe.arruda * @throws AplicacaoException */ public List<PMP> recuperaListaDePMPs() throws AplicacaoException { List<PMP> pmps = pmpDAO.recuperaListaDePMPs(); if (pmps.size() == 0) { throw new AplicacaoException("PMP.NAO_ENCONTRADO"); } else { return pmps; } } public List<PMP> recuperaListaDePMPsComPerioPMVigs () { return pmpDAO.recuperaListaDePMPsComPerioPMVigs(); } }