Subversion Repositories bacoAlunos

Rev

Rev 1051 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.services.sigesimports;

import jomm.dao.impl.AbstractDao;
import jomm.utils.StringsUtils;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.StaleStateException;
import pt.estgp.estgweb.Globals;
import pt.estgp.estgweb.domain.*;
import pt.estgp.estgweb.domain.dao.DaoFactory;
import pt.estgp.estgweb.services.common.CommonServicesManager;
import pt.estgp.estgweb.services.email.SendEmailService;
import pt.estgp.estgweb.services.expceptions.ServiceException;
import pt.estgp.estgweb.services.jobs.ServiceJob;
import pt.estgp.estgweb.services.logresults.ILogMessages;
import pt.estgp.estgweb.services.logresults.LogMessageTypeEnum;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessage;
import pt.estgp.estgweb.services.logresults.impl.DefaultLogMessages;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.utils.Email;
import pt.ipportalegre.siges.web.services.*;
import pt.utl.ist.berserk.logic.serviceManager.IService;

import javax.xml.namespace.QName;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;


/**
 * @author Jorge Machado
 * @date 11/May/2008
 * @time 12:51:32
 * @see pt.estgp.estgweb
 */

public class ImportStudentsService extends ServiceJob implements IService
{

    private static final 1.5.0/docs/api/java/util/logging/Logger.html">Logger logger = 1.5.0/docs/api/java/util/logging/Logger.html">Logger.getLogger(ImportStudentsService.class);
    private static final int MAX_COMMIT = 100;

    int studentsMerged = 0;
    int studentsNew = 0;
    int studentsZeroUnits = 0;
    int unitsNotFound = 0;
    int unitsRemovedToStudents = 0;
    int unitsLocalAddedNotRemoved = 0;
    int unitsLocallyRemovedNotAdded = 0;
    int alunosFound = 0;
    int studentsChangeBI = 0;
    int unitsAddedToStudents = 0;

    public ILogMessages run(1.5.0/docs/api/java/lang/String.html">String year) throws ServiceException
    {

        studentsMerged = 0;
        studentsNew = 0;
        studentsZeroUnits = 0;
        unitsNotFound = 0;
        unitsRemovedToStudents = 0;
        unitsLocalAddedNotRemoved = 0;
        unitsLocallyRemovedNotAdded = 0;
        alunosFound = 0;
        studentsChangeBI = 0;
        unitsAddedToStudents = 0;

        1.5.0/docs/api/java/lang/String.html">String activeImportYear = DaoFactory.getConfigurationDaoImpl().getInterfaceImportYear();

        1.5.0/docs/api/java/lang/String.html">String msgS = "STARTING STUDENTS IMPORT SERVICE FOR YEAR: " + year;
        serviceLogInfo(msgS);
        logger.info(msgS);

        DefaultLogMessages logMessages = new DefaultLogMessages();
        logMessages.addMessage(new DefaultLogMessage("import.students", LogMessageTypeEnum.INFO, "instituicao " + DaoFactory.getConfigurationDaoImpl().getSigesInstitutionCode()));

        try
        {
            SiGesWEB service;
            1.5.0/docs/api/java/lang/String.html">String WSDL = DaoFactory.getConfigurationDaoImpl().getSigesWebServicesWsdl();
            try
            {
                serviceLogInfo("STARTING WEB SERVICE AT " + WSDL);
                service = new SiGesWEB(new 1.5.0/docs/api/java/net/URL.html">URL(WSDL), new 1.5.0/docs/api/javax/xml/namespace/QName.html">QName(Globals.SIGES_WEBSERVICE_TARGET_NAMESPACE, "SiGesWEB"));
            }
            catch (1.5.0/docs/api/java/net/MalformedURLException.html">MalformedURLException e)
            {
                logger.fatal(e, e);
                logMessages.addMessage(new DefaultLogMessage("import.error",e.toString(),"erro na configuracao do WEB Service", LogMessageTypeEnum.INFO));
                serviceLogFatal(logMessages.getLastMessage(), e);
                return logMessages;
            }

            ArrayOfDecimal codigosAlunos = service.getSiGesWEBSoap().getCodigosAlunosInscritosDaInstituicao(new 1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal(DaoFactory.getConfigurationDaoImpl().getSigesInstitutionCode()), year);
            List<BigDecimal> codigos = codigosAlunos.getDecimal();
            int i = 1;

            for (1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal c : codigos)
            {
                alunosFound++;
                if (i++ > MAX_COMMIT)
                {
                    i = 0;
                    setProgress((int) (((float)alunosFound)/((float)codigos.size())*100.0f));
                    AbstractDao.getCurrentSession().getTransaction().commit();
                    AbstractDao.getCurrentSession().beginTransaction();
                }

                Aluno alunoSiges = service.getSiGesWEBSoap().getAlunoInscrito(c, new 1.5.0/docs/api/java/math/BigDecimal.html">BigDecimal(DaoFactory.getConfigurationDaoImpl().getSigesInstitutionCode()), year);
                User u = DaoFactory.getUserDaoImpl().loadByUsernameOrSigesCode(alunoSiges.getCodigo().intValue());
                Student s = null;  
                boolean newUser = false;
                if(u != null && !(u instanceof Student))
                {
                    msgS = "Student " + u.getUsername() + " already exist in system but is not a Student is a standard USER, will merge both users";
                    studentsMerged++;
                    serviceLogWarn(msgS);
                    logger.warn(msgS);
//                    Set<Record> records = u.getCreatorRecords();
                    DaoFactory.getUserDaoImpl().delete(u);
                    msgS = "Student " + u.getUsername() + "1";
                    logger.warn(msgS);
                    serviceLogWarn(msgS);
                    i = 0;

                    AbstractDao.getCurrentSession().getTransaction().commit();
                    AbstractDao.getCurrentSession().beginTransaction();

                    msgS = "Student " + u.getUsername() + "2";
                    logger.warn(msgS);
                    serviceLogWarn(msgS);
                    s = DomainObjectFactory.createStudentImpl();
                    DaoFactory.getStudentDaoImpl().save(s);
//                    for(Record r:records)
//                    {
//                        r.setOwner(null);
//                        DaoFactory.getRecordDaoImpl().reattach(r);
//                        r.setOwner(s);
//                    }
                    newUser = true;
                }
                else if(u != null)
                {
                    s = DaoFactory.getStudentDaoImpl().load(u.getId());
                }

                if (s == null)
                {
                    s = DomainObjectFactory.createStudentImpl();
                    DaoFactory.getStudentDaoImpl().save(s);
                    newUser = true;
                }
                persist(alunoSiges, s, newUser,year,activeImportYear);
                //Advising CommonsServicesManager before change password

                if (newUser)
                    CommonServicesManager.getInstance().adviseNew(s);

                else
                {
                    1.5.0/docs/api/java/lang/String.html">String password = s.getPassword();
                    s.setPassword(null);
                    CommonServicesManager.getInstance().adviseUpdate(s);
                    s.setPassword(password);
                }
            }
            logMessages.addMessage(new DefaultLogMessage("import.students.terminating", LogMessageTypeEnum.INFO));
            logger.info("terminating student import");
            serviceLogInfo("terminating student import");
        }
        catch(StaleStateException e)
        {
            AbstractDao.getCurrentSession().getTransaction().rollback();
            AbstractDao.getCurrentSession().beginTransaction();
            logger.error(e,e);
            serviceLogError("Rolling back will lost previous updates: " + e.toString(),e);
            sendNotificationAdmin("Erro de importacao de alunos",e.toString());
        }
        catch(HibernateException e)
        {
            AbstractDao.getCurrentSession().getTransaction().rollback();
            AbstractDao.getCurrentSession().beginTransaction();
            logger.error(e,e);
            serviceLogError("Rolling back will lost previous updates: " + e.toString(),e);
            sendNotificationAdmin("Erro de base de dados importacao de alunos, provavelmente chave errada, corrigir no MySql",e.toString());
        }
        catch(1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
        {
            logger.error(e,e);
            logMessages.addMessage(new DefaultLogMessage("import.error",e.toString(), "see log for details", LogMessageTypeEnum.ERROR));
            serviceLogError(e.toString(),e);
            1.5.0/docs/api/java/lang/String.html">String cause = e.getCause() == null ? "" : e.getCause().toString();
            sendNotificationAdmin("Erro de importacao de alunos",cause);
        }


        serviceLogInfo("############################");
        serviceLogInfo("############################");
        serviceLogInfo("#Students found: " + alunosFound);
        serviceLogInfo("#Students New: " + studentsNew);
        serviceLogInfo("#Students Merged: " + studentsMerged);
        serviceLogInfo("#Students Zero Units: " + studentsZeroUnits);
        serviceLogInfo("#Units not found: " + unitsNotFound);
        serviceLogInfo("#Units added to Students: " + unitsAddedToStudents);
        serviceLogInfo("#Units removed to Students: " + unitsRemovedToStudents);
        serviceLogInfo("#Units not Removed because localy added: " + unitsLocalAddedNotRemoved);
        serviceLogInfo("#Units not Added because localy removed: " + unitsLocallyRemovedNotAdded);

        logger.info("############################");
        logger.info("############################");
        logger.info("#Students found: " + alunosFound);
        logger.info("#Students New: " + studentsNew);
        logger.info("#Students Merged: " + studentsMerged);
        logger.info("#Students Zero Units: " + studentsZeroUnits);
        logger.info("#Units not found: " + unitsNotFound);
        logger.info("#Units added to Students: " + unitsAddedToStudents);
        logger.info("#Units removed to Students: " + unitsRemovedToStudents);
        logger.info("#Units not Removed because localy added: " + unitsLocalAddedNotRemoved);
        logger.info("#Units not Added because localy removed: " + unitsLocallyRemovedNotAdded);
        if(studentsChangeBI>0)
        {
            serviceLogInfo("#>>>>>AVISO AVISO<<<<<<<<<: ");
            serviceLogInfo("#>>>>>AVISO AVISO<<<<<<<<<: ");
            serviceLogInfo("#>>>>>NUMEROS DE ALUNOS MUDARAM DE BI<<<<<<<<<: CONSULTAR LOG");
            serviceLogInfo("#CODIGO SIGES COM BIs DIFERENTES:" + studentsChangeBI);
            logger.info("#>>>>>AVISO AVISO<<<<<<<<<: ");
            logger.info("#>>>>>AVISO AVISO<<<<<<<<<: ");
            logger.info("#>>>>>NUMEROS DE ALUNOS MUDARAM DE BI<<<<<<<<<: CONSULTAR LOG");
            logger.info("#CODIGO SIGES COM BIs DIFERENTES:" + studentsChangeBI);
        }

        setProgress(100);
        return logMessages;
    }

    /**
     * Envio de Notificação aos operadores do CI
     * @param subject
     * @param cause
     */

    private void sendNotificationAdmin(1.5.0/docs/api/java/lang/String.html">String subject, 1.5.0/docs/api/java/lang/String.html">String cause)
    {
        List<String> emails = ConfigProperties.getListValues("admin.email");
        for(1.5.0/docs/api/java/lang/String.html">String email:emails)
        {
            serviceLogWarn(">>>>>>>>ENVIANDO NOTIFICACAO A ADMINISTRACAO: " + email);
            logger.warn(">>>>>>>>ENVIANDO NOTIFICACAO A ADMINISTRACAO: " + email);
        }
        List<String> arguments = new ArrayList<String>();
        arguments.add(cause.replace("\n","<br/>"));
        Email email = new Email(subject,emails,Globals.SYSTEM_EMAIL_BOX,"messageToAdmin_pt.txt",arguments);
        email.setHtml(true);
        try {
            new SendEmailService().sendEmail(email);
        } catch (ServiceException e) {
            e.printStackTrace();
        }
    }



    /**
     * Nao esta testado
     * jm
     *
     * @param alunoSiges       Aluno
     * @param student Student
     */

    private void persist(Aluno alunoSiges, Student student, boolean newUser, 1.5.0/docs/api/java/lang/String.html">String year, 1.5.0/docs/api/java/lang/String.html">String activeImportYear)
    {
        if(newUser)
        {
            studentsNew++;
            cloneFields(alunoSiges, student);
            serviceLogInfo("NOVO ALUNO ENCONTRADO: siges:" + student.getSigesCode() + " bi:" + student.getBi() + " nome:" + student.getName());
        }
        //CASO EM QUE O ALUNO NO SIGES FOI ATRIBUIDO A OUTRO ESTUDANTE PARA PREENCHER BURACO NA NUMERACAO
        else if(alunoSiges.getNumeroBi() == null || student.getBi() == null || ! alunoSiges.getNumeroBi().equals(student.getBi()))
        {
            studentsChangeBI++;

            1.5.0/docs/api/java/lang/StringBuilder.html">StringBuilder builder = new 1.5.0/docs/api/java/lang/StringBuilder.html">StringBuilder();

            builder.append("ATENCAO NUMERO DE ALUNO " + alunoSiges.getCodigo() + " MUDOU DE DONO VAI SER BLOQUEADO IMEDIATAMENTE\n");
            builder.append("ALTERANDO DADOS DO ALUNO " + alunoSiges.getCodigo() + "\n");
            builder.append("-----ANTES: " + "\n");
            builder.append("-----BI: " + student.getBi() + "\n");
            builder.append("-----Nome: " + student.getName() + "\n");
            builder.append("-----Username: " + student.getUserNameNetpa() + "\n");
            builder.append("-----Address: " + student.getAddress() + "\n");
            builder.append("-----Zip: " + student.getZip() + "\n");
            builder.append("-----Email: " + student.getEmail() + "\n");
            builder.append("-----Phone: " + student.getPhonenumber() + "\n");

            cloneFields(alunoSiges, student);

            //todo verificar isto
            //student.setAutoBlockMode(false);
            //student.setManualBlock(true);

            builder.append("DEPOIS: " + "\n");
            builder.append("BI: " + student.getBi() + "\n");
            builder.append("Nome: " + student.getName() + "\n");
            builder.append("Username: " + student.getUserNameNetpa() + "\n");
            builder.append("Address: " + student.getAddress() + "\n");
            builder.append("Zip: " + student.getZip() + "\n");
            builder.append("Email: " + student.getEmail() + "\n");
            builder.append("Phone: " + student.getPhonenumber() + "\n");

            serviceLogWarn(builder.toString());

            sendNotificationAdmin("CODIGO SIGES " + alunoSiges.getCodigo() + " MUDOU DE DONO - FOI BLOQUEADO ",builder.toString());


        }

        if(alunoSiges.getHistoricos() == null || alunoSiges.getHistoricos().getAlunoHistorico() == null || alunoSiges.getHistoricos().getAlunoHistorico().size() == 0)
        {
            student.setPropinasEmDia(false);
            serviceLogWarn("ATENTION Estudante sem historico de Matriculas para aferir propinas: codigo " + alunoSiges.getCodigo());
            logger.warn("ATENTION Estudante sem historico de Matriculas para aferir propinas: codigo " + alunoSiges.getCodigo());
        }
        else
        {
            student.setPropinasEmDia(false);
            student.setPropinasEmDiaYear(activeImportYear);

            for(AlunoHistorico hist: alunoSiges.getHistoricos().getAlunoHistorico())
            {
                if(hist.getCodigoLectivo()!=null && hist.getCodigoLectivo().equals(activeImportYear))
                {
                    if(hist.getPropinaEmDia().equalsIgnoreCase("s"))
                    {
                        student.setPropinasEmDia(true);
                        student.setPropinasEmDiaYear(activeImportYear);
                    }
                    break;
                }
            }
            if(!student.isPropinasEmDia())
            {
                serviceLogWarn("ATENTION Estudante sem propina em dia: codigo " + alunoSiges.getCodigo());
                logger.warn("ATENTION Estudante sem propina em dia: codigo " + alunoSiges.getCodigo());
            }
        }
        /*Desta forma as relacoes antigas sao ignoradas cria-se uma lista nova e atribui-se ao Teacher, o Hibernate faz resto e apaga as chaves estrangeiras antigas */
        if (alunoSiges.getDisciplinasInscrito() == null || alunoSiges.getDisciplinasInscrito().getDisciplina() == null || alunoSiges.getDisciplinasInscrito().getDisciplina().size() == 0)
        {
            studentsZeroUnits++;
            serviceLogWarn("ATENTION STUDENT WITH ZERO UNITS: codigo " + alunoSiges.getCodigo());
            logger.warn("ATENTION STUDENT WITH ZERO UNITS: codigo " + alunoSiges.getCodigo());
        }
        else
        {
            //1 - PROCEDIMENTO CADEIRAS SAO CARREGADAS DO BACO DA LISTA QUE VEM DO SIGES -> units
            //2 - Sao retiradas da lista units as que o aluno tem mas que foram removidas localmente
            //3 - Sao adicionadas ao aluno as que o aluno ainda nao tiver da lista units
            //4 - Remover da lista do aluno as unidades que não vêm do SIGES e que não foram adicionadas localmente


            //PASSO 1
            Set<CourseUnit> units = new HashSet<CourseUnit>();
            ArrayOfDisciplina disciplinas = alunoSiges.getDisciplinasInscrito();
            for (Disciplina disciplina : disciplinas.getDisciplina())
            {
                CourseUnit courseUnit = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUnique("" + disciplina.getCodigo(),"" + disciplina.getCodigoCurso(),disciplina.getCdDuracao(),disciplina.getCdLectivo());
                if(courseUnit == null)
                {
                    unitsNotFound++;
                    1.5.0/docs/api/java/lang/String.html">String msg = "Unit not found: semestre:" + disciplina.getCdDuracao() + " codigo:" + disciplina.getCodigo() + " course:" + disciplina.getCodigoCurso() + " year:" + disciplina.getCdLectivo();
                    serviceLogWarn(msg);
                    logger.warn(msg);
                }
                else
                    units.add(courseUnit);
            }

            //PASSO 2
            Iterator<CourseUnit> iter = units.iterator();
            StudentImpl sImpl = (StudentImpl) DaoFactory.getStudentDaoImpl().narrow(student);
            while (iter.hasNext())
            {
                CourseUnit courseUnit = iter.next();
                //In case of a comming proxy

                if(sImpl.isLocalRemovedUnit(courseUnit))
                {
                    unitsLocallyRemovedNotAdded++;
                    1.5.0/docs/api/java/lang/String.html">String msg = "Removendo unidade: " + ((CourseUnitImpl)courseUnit).getSigesUniqueIdentifiers() + " - do aluno: " + student.getSigesCode() + " - Associacao existe no SIGES mas foi removido LOCALMENTE";
                    serviceLogInfo(msg);
                    logger.info(msg);
                    iter.remove();
                }
            }

            //PASSO 3
            if(student.getSubscribedUnits() != null)
            {
                for(CourseUnit c: units)
                {
                    boolean isIn = false;
                    for(CourseUnit tc : student.getSubscribedUnits())
                    {
                        if(tc.equals(c))
                        {
                            isIn = true;
                            break;
                        }
                    }
                    if(!isIn)
                    {
                        1.5.0/docs/api/java/lang/String.html">String msg = "Adicionando unidade: " + ((CourseUnitImpl)c).getSigesUniqueIdentifiers() + " - ao aluno: " + student.getSigesCode() + " - Associacao nova no SIGES";
                        serviceLogInfo(msg);
                        logger.info(msg);
                        unitsAddedToStudents++;
                        student.getSubscribedUnits().add(c);
                    }
                }
            }
            else
                student.setSubscribedUnits(units);

            //PASSO 4
            //Remover unidades deste ano que nao vem do SIGES e que nao foram adicionadas localmente
            Iterator<CourseUnit> iterNowUnits = student.getSubscribedUnits().iterator();
            while(iterNowUnits.hasNext())
            {
                CourseUnit cUNow = iterNowUnits.next();
                if(cUNow.getImportYear().equals(year))
                //Apenas tentamos apagar as unidades do ano corrente.
                //Este servico trabalha com unidades importadas do ano que e passado como argumento
                //Se importamos unidades desse ano, as dos outros anos nao vem na lista, logo
                //iriamos constatar que nenhuma estava no SIGES o que nao e verdade.
                //Assim so apagamos unidades do ano que estamos a importar e que nao venham
                //na importacao desse ano
                {

                    boolean added = false;
                    for(CourseUnit c: units)
                    {
                        if(cUNow.equals(c))
                        {
                            added = true;
                            break;
                        }
                    }
                    if(!added)
                    {

                        if(!sImpl.isLocalUnit(cUNow))
                        {
                            1.5.0/docs/api/java/lang/String.html">String msg = "Removendo unidade: " + ((CourseUnitImpl)cUNow).getSigesUniqueIdentifiers() + " - do aluno: " + student.getSigesCode() + " - Associacao desapareceu do SIGES";
                            serviceLogInfo(msg);
                            logger.info(msg);
                            iterNowUnits.remove();
                            unitsRemovedToStudents++;
                        }
                        else
                        {
                            1.5.0/docs/api/java/lang/String.html">String msg = "NAO REMOVIDA - Unidade: " + ((CourseUnitImpl)cUNow).getSigesUniqueIdentifiers() + " - do aluno: " + student.getSigesCode() + " - Associacao desapareceu do SIGES mas foi adicionada localmente";
                            serviceLogInfo(msg);
                            logger.info(msg);
                            unitsLocalAddedNotRemoved++;
                        }
                    }
                }
            }
        }
    }

    private void cloneFields(Aluno alunoSiges, Student student) {
        student.setName(alunoSiges.getNome());
        student.setEmail(alunoSiges.getEmail());
        student.setSigesCode(alunoSiges.getCodigo().intValue());
        student.setAddress(alunoSiges.getMorada());
        student.setPhonenumber(StringsUtils.cleanKeepNumbers(alunoSiges.getTelemovel()));
        student.setZip("" + alunoSiges.getCodigoPostal().intValue());
        student.setBi(alunoSiges.getNumeroBi());
        student.setSex(alunoSiges.getSexo());
        student.setUserNameNetpa(alunoSiges.getUsernameNetpa());
        student.setBirthDate(alunoSiges.getDataNascimento().toGregorianCalendar().getTime());
        student.setUsername("a" + alunoSiges.getCodigo().intValue());
    }

    public static final 1.5.0/docs/api/java/lang/String.html">String JOB_importYear_KEY = "JOB_importYear_KEY";

    @1.5.0/docs/api/java/lang/Override.html">Override
    protected ILogMessages runJobServiceTask() throws 1.5.0/docs/api/java/lang/Throwable.html">Throwable {

        1.5.0/docs/api/java/lang/String.html">String importYear = getParametersMap().get(JOB_importYear_KEY).getObject();
        ILogMessages messages = run(importYear);
        return messages;

    }

    /**
     * Testar por aqui poi requer Super Role e assim e' autmatico
     *
     * @param args of main
     * @throws ServiceException on error
     */


    public static void main(1.5.0/docs/api/java/lang/String.html">String[] args) throws ServiceException
    {
        1.5.0/docs/api/java/lang/String.html">String year = DaoFactory.getConfigurationDaoImpl().getImportsDefaultImportYearCreateTransaction();
            1.5.0/docs/api/java/lang/System.html">System.out.println("YEAR:" + year);
        if(args != null && args.length > 0)
            year = args[0];
        AbstractDao.getCurrentSession().beginTransaction();
        new ImportStudentsService().run(year);
        AbstractDao.getCurrentSession().getTransaction().commit();
    }
}