Subversion Repositories bacoAlunos

Rev

Rev 1396 | Rev 1426 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package pt.estgp.estgweb.services.sigesimports;

import jomm.dao.impl.AbstractDao;
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.services.sigesimports.oracle.dao.DocenteDao;
import pt.estgp.estgweb.services.sigesimports.oracle.dao.connection.ConnectionManager;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.Disciplina;
import pt.estgp.estgweb.services.sigesimports.oracle.domain.Docente;
import pt.estgp.estgweb.utils.ConfigProperties;
import pt.estgp.estgweb.utils.Email;
import pt.utl.ist.berserk.logic.serviceManager.IService;

import java.sql.Connection;
import java.util.*;

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

public class ImportTeachersService 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(ImportTeachersService.class);

    private static final int MAX_COMMIT = 20;

    //int studentsMerged = 0;
    int teachersNew = 0;
    int teachersZeroUnits = 0;
    int unitsNotFound = 0;
    int unitsNotFoundCourseNotFound = 0;
    int unitsFoundForCourseNotFoundMult = 0;
    int unitsFoundForCourseNotFoundSingle = 0;
    int unitsDuplicated = 0;
    int unitsAddedToTeachers = 0;
    int unitsRemovedToTeachers = 0;
    int unitsLocalAddedNotRemoved = 0;
    int teachersFound = 0;
    int teachersChangeBI = 0;
    int unitsLocallyRemovedNotAdded = 0;
    int professoresDesaparecidosDoSigesNesteAno = 0;
    int cursosFicticios = 0;



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

        teachersNew = 0;
        teachersZeroUnits = 0;
        unitsNotFound = 0;
        unitsNotFoundCourseNotFound = 0;
        unitsFoundForCourseNotFoundMult = 0;
        unitsFoundForCourseNotFoundSingle = 0;
        unitsDuplicated = 0;
        unitsAddedToTeachers = 0;
        unitsRemovedToTeachers = 0;
        unitsLocalAddedNotRemoved = 0;
        teachersFound = 0;
        teachersChangeBI = 0;
        unitsLocallyRemovedNotAdded = 0;
        cursosFicticios = 0;

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

        DefaultLogMessages logMessages = new DefaultLogMessages();
        logMessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.INFO, "instituicao " + institutionCode));

        try
        {
            List<Integer> codigosDocentes = DocenteDao.getInstance().loadCodigosDocentes(institutionCode, year);

            /**
             * Este método vai procurar processores no BACO neste ano que não vieram do SIGES
             * Os professores que não vieram da extração do SIGES e terão de ser consistidos
             * pois as suas unidades ter desaparecido todas de uma vez e vão aqui ficar penduradas
             * Se foram adicionadas manualmente então nao serao removidas
             */

            removerUnidadesDosDesaparecidosDoSiges(year, institutionCode, codigosDocentes);

            1.5.0/docs/api/java/sql/Connection.html">Connection conn = ConnectionManager.openConnection();
            int i = 1;
            for (1.5.0/docs/api/java/lang/Integer.html">Integer c : codigosDocentes)
            {
                teachersFound++;
                if (i++ > MAX_COMMIT)
                {
                    i = 0;
                    setProgress((int) (((float)teachersFound)/((float)codigosDocentes.size())*100.0f));
                    conn.close();
                    commitPartially();
                    conn = ConnectionManager.openConnection();
                }
                logger.info("Starting import Funcionario: SIGES:" + c);

                Docente d = DocenteDao.getInstance().load(c, institutionCode, year,conn);

                /******Logging****/
                logger.info("Codigo Funcionario Importado: SIGES(" + d.getCodigoFuncionario().intValue() + ") email IPP SIGES: " + d.getEmail());
                serviceLogInfo("Codigo Funcionario Importado: SIGES(" + d.getCodigoFuncionario().intValue() + ") email IPP SIGES: " + d.getEmail());
                logger.info("SIGES IMPORTED INFO: " + docenteToString(d));
                serviceLogInfo("SIGES IMPORTED INFO: " + docenteToString(d));
                /******Logging****/

                Teacher t = DaoFactory.getTeacherDaoImpl().loadBySigesCode(d.getCodigoFuncionario().intValue());

                boolean newUser = false;
                if (t == null)
                {
                    /******Logging****/
                    msgS = "Teacher does not exist in baco, will create SIGES:" + d.getCodigoFuncionario().intValue();
                    logger.info(msgS);
                    serviceLogInfo(msgS);
                    /******Logging****/

                    t = DomainObjectFactory.createTeacherImpl();
                    DaoFactory.getTeacherDaoImpl().save(t);
                    newUser = true;
                    //teachersNew++;
                }
                else
                {
                    /******Logging****/
                    msgS = "Teacher EXIST in baco with SIGES: " + d.getCodigoFuncionario().intValue();
                    logger.info(msgS);
                    //serviceLogInfo(msgS);  //NOT NEED EXCESS OF INFORMATION
                    /******Logging****/
                }

                /******Logging****/
                msgS = "Will persist SIGES(" + d.getCodigoFuncionario().intValue() + ")  baco (username:" + t.getUsername() + ") baco name:" + t.getName();
                logger.info(msgS);
                serviceLogInfo(msgS);
                /******Logging****/

                try
                {
                    persist(d, t, newUser,year,logMessages,institutionCode);
                }
                catch (1.5.0/docs/api/java/lang/Exception.html">Exception e)
                {
                    logger.error(e, e);
                    throw e;
                }

                newUserSystemAdvise(t, newUser);
            }
            conn.close();

        }
        catch(StaleStateException e)
        {
            AbstractDao.getCurrentSession().getTransaction().rollback();
            AbstractDao.getCurrentSession().beginTransaction();
            /******Logging****/
            logger.error(e,e);
            serviceLogError("Rolling back will lost previous updates: " + e.toString(),e);
            sendNotificationAdmin("Erro de importacao de docentes",e.toString());
            /******Logging****/
        }
        catch(HibernateException e)
        {
            AbstractDao.getCurrentSession().getTransaction().rollback();
            AbstractDao.getCurrentSession().beginTransaction();
            /******Logging****/
            logger.error(e,e);
            serviceLogError("Rolling back will lost previous updates: " + e.toString(),e);
            sendNotificationAdmin("Erro de base de dados importacao de docentes, provavelmente chave errada, corrigir no MySql",e.toString());
            /******Logging****/
        }
        catch (1.5.0/docs/api/java/lang/Throwable.html">Throwable e)
        {
            /******Logging****/
            logMessages.addMessage(new DefaultLogMessage("import.error", e.toString(), "see log for details", LogMessageTypeEnum.ERROR));
            logger.error(e, e);
            /******Logging****/
            throw new ServiceException(e.toString(), e);
        }





        /******Logging****/
        serviceLogInfo("############################");
        serviceLogInfo("############################");
        serviceLogInfo("#Teachers found: " + teachersFound);
        serviceLogInfo("#Teachers New: " + teachersNew);
        serviceLogInfo("#Teachers Zero Units: " + teachersZeroUnits);
        serviceLogInfo("#Units not found: " + unitsNotFound);
        serviceLogInfo("#Units with NULL COURSE : " + unitsNotFoundCourseNotFound);
        serviceLogInfo("#Units added to one possible course because NULL COURSE : " + unitsFoundForCourseNotFoundSingle);
        serviceLogInfo("#Units added to multiple possible courses because NULL COURSE : " + unitsFoundForCourseNotFoundMult);
        serviceLogInfo("#Units duplicated : " + unitsDuplicated);
        serviceLogInfo("#Units removed to Teachers: " + unitsRemovedToTeachers);
        serviceLogInfo("#Units added to Teachers: " + unitsAddedToTeachers);
        serviceLogInfo("#Units not Removed because localy added: " + unitsLocalAddedNotRemoved);
        serviceLogInfo("#Units not Added because localy removed: " + unitsLocallyRemovedNotAdded);
        if(professoresDesaparecidosDoSigesNesteAno > 0)
        {
            serviceLogInfo("########!!!!!!!Professores que desapareceram do Siges neste ano e tinham cadeiras no BACO: " + professoresDesaparecidosDoSigesNesteAno);
        }
        else
        {
            serviceLogInfo("CHECK DESAPARECIDOS OK - Não existem professores desaparecidos");
        }
        if(cursosFicticios > 0)
        {
            serviceLogInfo("#######Cursos Ficticios Encontrados (SITUACAO NAO PREVISTA):" + cursosFicticios);
        }

        logger.info("############################");
        logger.info("############################");
        logger.info("#Teachers found: " + teachersFound);
        logger.info("#Teachers New: " + teachersNew);
        logger.info("#Teachers Zero Units: " + teachersZeroUnits);
        logger.info("#Units not found: " + unitsNotFound);
        logger.info("#Units with NULL COURSE : " + unitsNotFoundCourseNotFound);
        logger.info("#Units added to one possible course because NULL COURSE : " + unitsFoundForCourseNotFoundSingle);
        logger.info("#Units added to multiple possible courses because NULL COURSE : " + unitsFoundForCourseNotFoundMult);
        logger.info("#Units duplicated : " + unitsDuplicated);
        logger.info("#Units removed to Teachers: " + unitsRemovedToTeachers);
        logger.info("#Units added to Teachers: " + unitsAddedToTeachers);
        logger.info("#Units not Removed because localy added: " + unitsLocalAddedNotRemoved);
        logger.info("#Units not Added because localy removed: " + unitsLocallyRemovedNotAdded);
        if(professoresDesaparecidosDoSigesNesteAno > 0)
        {
            logger.info("########!!!!!!!Professores que desapareceram do Siges neste ano e tinham cadeiras no BACO: " + professoresDesaparecidosDoSigesNesteAno);
        }
        else
        {
            logger.info("CHECK DESAPARECIDOS OK - Não existem professores desaparecidos");
        }
        if(cursosFicticios > 0)
        {
            logger.info("#######Cursos Ficticios Encontrados (SITUACAO NAO PREVISTA):" + cursosFicticios);
        }

        if(teachersChangeBI>0)
        {
            serviceLogInfo("#>>>>>AVISO AVISO<<<<<<<<<: ");
            serviceLogInfo("#>>>>>AVISO AVISO<<<<<<<<<: ");
            serviceLogInfo("#>>>>>NUMEROS DE PROFESSORES MUDARAM DE BI<<<<<<<<<: CONSULTAR LOG");
            serviceLogInfo("#CODIGO SIGES COM BIs DIFERENTES:" + teachersChangeBI);

            logger.info("#>>>>>AVISO AVISO<<<<<<<<<: ");
            logger.info("#>>>>>AVISO AVISO<<<<<<<<<: ");
            logger.info("#>>>>>NUMEROS DE PROFESSORES MUDARAM DE BI<<<<<<<<<: CONSULTAR LOG");
            logger.info("#CODIGO SIGES COM BIs DIFERENTES:" + teachersChangeBI);
        }
        setProgress(100);

        logMessages.addMessage(new DefaultLogMessage("import.teachers.terminating", LogMessageTypeEnum.INFO));
        logger.info("terminating teacher import");
        serviceLogInfo("terminating teacher import");
        /******Logging****/
        return logMessages;
    }



    /**
     * Este métido vai consistir os alunos que não eram tratados porque não vinham do SIGES logo não constavam do
     * ciclo
     * @param year
     * @param institutionCode
     * @param codigos
     */

    private void  removerUnidadesDosDesaparecidosDoSiges(1.5.0/docs/api/java/lang/String.html">String year, int institutionCode, List<Integer> codigos) {
        1.5.0/docs/api/java/lang/String.html">String msgS;
        List<Integer> codesInBaco = DaoFactory.getTeacherDaoImpl().findAllSigesCodesYear(year,institutionCode);
        codesInBaco.removeAll(codigos);

        if(codesInBaco.size() > 0)
        {
            msgS = "Existem professores no BACO que não estao no SIGES no ano: " + year + " institution:" + institutionCode + " possiveis adicionados manualmente, confirmar";
            serviceLogWarn(msgS);
            logger.warn(msgS);
            msgS = "";
            for (1.5.0/docs/api/java/lang/Integer.html">Integer c : codesInBaco)
            {
                msgS+=c + ", ";
            }
            serviceLogWarn(msgS);
            logger.warn(msgS);
            for (1.5.0/docs/api/java/lang/Integer.html">Integer c : codesInBaco)
            {
                professoresDesaparecidosDoSigesNesteAno++;
                Teacher t = DaoFactory.getTeacherDaoImpl().loadBySigesCode(c);
                TeacherImpl teacherImpl = (TeacherImpl) DaoFactory.getTeacherDaoImpl().narrow(t);
                removerUnidadesQueDesapareceramNoSiges(year, teacherImpl, new HashSet<CourseUnit>(),institutionCode);
                //consistirTurmasAluno(studentImpl, year, new HashMap<CourseUnit, String>());
            }
        }
        else
        {
            msgS = "OK check - Não existem alunos desaparecidos no SIGES ano: " + year + " institution:" + institutionCode + " possiveis adicionados manualmente, confirmar";
            serviceLogInfo(msgS);
            logger.info(msgS);
        }
    }

    private void newUserSystemAdvise(Teacher t, boolean newUser) {
        if (newUser)
            CommonServicesManager.getInstance().adviseNew(t);
        else
        {
            1.5.0/docs/api/java/lang/String.html">String password = t.getPassword();
            t.setPassword(null);
            CommonServicesManager.getInstance().adviseUpdate(t);
            t.setPassword(password);
        }
    }


    /**
     * 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();
        }

    }

    /**
     * Implementação local do toString para a class Docente que foi gerada pelos web-services
     * @param d
     * @return
     */


    public 1.5.0/docs/api/java/lang/String.html">String docenteToString(Docente d)
    {
        return "Docente{" +
                "codigoFuncionario=" + d.getCodigoFuncionario() +
                ", nomeFuncionario='" + d.getNomeFuncionario() + '\'' +
                ", nomeFuncionarioInt='" + d.getNomeFuncionarioInt() + '\'' +
                ", nomeAcademico='" + d.getNomeAcademico() + '\'' +
                ", sexo='" + d.getSexo() + '\'' +
                ", dataNascimento=" + d.getData_nascimento() +
                ", morada='" + d.getMorada() + '\'' +
                ", codigoPostal=" + d.getCodigoPostal() +
                ", subCodigoPostal=" + d.getSubCodigoPostal() +
                ", email='" + d.getEmail() + '\'' +
                ", numeroBi='" + d.getNumeroBi() + '\'' +
                ", usernameNetpa='" + d.getUsernameNetpa() + '\'' +
                ", disciplinas=" + d.getDisciplinas() +
                '}';
    }

    private void cloneFields(Docente teacherSiges, Teacher teacher)
    {

        teacher.setName(teacherSiges.getNomeFuncionarioInt());
        teacher.setEmail(teacherSiges.getEmail());
        1.5.0/docs/api/java/lang/String.html">String msgS;

        if(teacherSiges.getEmail() != null && teacherSiges.getEmail().endsWith(Globals.EMAIL_LOCAL_SUFFIX))
        {
            int atIndex = teacherSiges.getEmail().indexOf("@");
            if (atIndex > 0)
            {
                teacher.setUsername(teacherSiges.getEmail().substring(0, atIndex));
                msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " foi-lhe atribuido o username d" + teacherSiges.getEmail().substring(0, atIndex);
                logger.info(msgS);
                serviceLogInfo(msgS);
            }
            else
            {
                msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " NAO lhe foi atribuido username o email não tem o caracter @";
                logger.info(msgS);
                serviceLogInfo(msgS);
            }
        }
        else
        {
            msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " nao tem email no SIGES foi-lhe atribuido o username d" + teacherSiges.getCodigoFuncionario().intValue();
            logger.info(msgS);
            serviceLogInfo(msgS);
            teacher.setUsername("d" + teacherSiges.getCodigoFuncionario().intValue());
        }
        teacher.setSigesCode(teacherSiges.getCodigoFuncionario().intValue());
        teacher.setAddress(teacherSiges.getMorada());
        teacher.setZip("" + teacherSiges.getCodigoPostal().intValue());
        teacher.setBi(teacherSiges.getNumeroBi());
        teacher.setEmployerName(teacherSiges.getNomeFuncionario());
        teacher.setAcademicName(teacherSiges.getNomeAcademico());
        teacher.setBirthDate(teacherSiges.getData_nascimento());
    }

    private static class TipologiaCourseUnitPair
    {
        CourseUnit cu;
        1.5.0/docs/api/java/lang/Integer.html">Integer cdTipologia;
        1.5.0/docs/api/java/lang/Integer.html">Integer cdFuncaoDocente;
    }
    /**
     * Nao esta testado
     * jm
     *
     * @param teacherSiges docente
     * @param teacher teacher
     * @throws Exception .
     */

    private void persist(Docente teacherSiges, Teacher teacher, boolean newUser, 1.5.0/docs/api/java/lang/String.html">String year,DefaultLogMessages logmessages,int institutionCode) throws 1.5.0/docs/api/java/lang/Exception.html">Exception
    {
        1.5.0/docs/api/java/lang/String.html">String msgS;
        try
        {
            updateTeacherFields(teacherSiges, teacher, newUser);
            //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 (teacherSiges.getDisciplinas() == null ||  teacherSiges.getDisciplinas().size() == 0)
            {
                /******Logging****/
                msgS = "ATENTION TEACHER WITH ZERO UNITS: codigoFuncionario " + teacherSiges.getCodigoFuncionario();
                logger.warn(msgS);
                serviceLogInfo(msgS);
                /******Logging****/

                TeacherImpl tImpl = (TeacherImpl) DaoFactory.getTeacherDaoImpl().narrow(teacher);
                removerUnidadesQueDesapareceramNoSiges(year, tImpl, new HashSet<CourseUnit>(),institutionCode);
            }
            else
            {
                //1 - PROCEDIMENTO CADEIRAS SAO CARREGADAS DO BACO DA LISTA QUE VEM DO SIGES -> units
                //2 - Sao retiradas da lista units as que o teacher tem mas que foram removidas localmente
                //3 - Sao adicionadas ao teacher as que o docente ainda nao tiver da lista units
                //4 - Remover da lista do teacher as unidades que não vêm do SIGES e que não foram adicionadas localmente

                //o mapa nao esta a ser usado neste momento mas fica porque podera vir a ser necessario
                //o docente e' colocado nas unidades todas e as turmas ficam nas tipologias tratadas na importacao de cursos
                Map<CourseUnit,String> map_CourseUnit_x_Turma = new HashMap<CourseUnit, String>();

                //PASSO 1
                Set<CourseUnit> unitsFromSigesPersistentInBaco = obterCadeirasBacoCorrespondentes(year,teacherSiges, teacher, logmessages,map_CourseUnit_x_Turma);
                //PASSO 2
                TeacherImpl tImpl = removerRemovidasLocalmente(teacher, unitsFromSigesPersistentInBaco);
                //PASSO 3
                adicionarCadeirasNovasAoDocente(tImpl, unitsFromSigesPersistentInBaco);
                //PASSO 4
                removerUnidadesQueDesapareceramNoSiges(year, tImpl, unitsFromSigesPersistentInBaco,institutionCode);

            }


        }
        catch (1.5.0/docs/api/java/lang/Exception.html">Exception e)
        {
            logger.error(e, e);
            List<String> emails = new ArrayList<String>();
            emails.add(ConfigProperties.getProperty("admin.email"));
            List<String> arguments = new ArrayList<String>();
            1.5.0/docs/api/java/lang/String.html">String cause = e.getCause() == null ? "" : e.getCause().toString();
            arguments.add((e.toString() + "\n" + cause).replace("\n","<br/>"));
            Email email = new Email("Erro de importacao de professores",emails,"baco@estgp.pt","messageToAdmin_pt.txt",arguments);
            new SendEmailService().sendEmail(email);
            throw e;
        }

    }

    private void removerUnidadesQueDesapareceramNoSiges(1.5.0/docs/api/java/lang/String.html">String year, Teacher teacher, Set<CourseUnit> units,int institutionCode)
    {
        //Remover unidades deste ano que nao vem do SIGES e que nao foram adicionadas localmente
        Iterator<CourseUnit> iterNowUnits = teacher.getTeachedUnits().iterator();
        TeacherImpl tImpl = (TeacherImpl) DaoFactory.getTeacherDaoImpl().narrow(teacher);
        while(iterNowUnits.hasNext())
        {
            CourseUnit cUNow = iterNowUnits.next();
            if(cUNow.getImportYear().equals(year) && cUNow.getInstitutionCode().equals(institutionCode+""))
            {
                //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.getId() == c.getId())
                    {
                        added = true;
                        break;
                    }
                }
                if(!added)
                {

                    if(!tImpl.isLocalUnit(cUNow))
                    {
                        /******Logging****/
                        1.5.0/docs/api/java/lang/String.html">String msg = "Removendo unidade: " + ((CourseUnitImpl)cUNow).getSigesUniqueIdentifiers() + " - do docente: " + teacher.getSigesCode() + " - Associacao desapareceu do SIGES";
                        serviceLogInfo(msg);
                        logger.info(msg);
                        unitsRemovedToTeachers++;
                        /******Logging****/

                        iterNowUnits.remove();
                    }
                    else
                    {
                        /******Logging****/
                        1.5.0/docs/api/java/lang/String.html">String msg = "NAO REMOVIDA - Unidade: " + ((CourseUnitImpl)cUNow).getSigesUniqueIdentifiers() + " - do docente: " + teacher.getSigesCode() + " - Associacao desapareceu do SIGES mas foi adicionada localmente";
                        serviceLogInfo(msg);
                        logger.info(msg);
                        unitsLocalAddedNotRemoved++;
                        /******Logging****/
                    }
                }
            }
        }
    }

    private void adicionarCadeirasNovasAoDocente(Teacher teacher, Set<CourseUnit> units) {
        //3 - da lista units sao adicionadas  ao teacher as que sobraram do passo 2 e o docente ainda nao tiver
        if (teacher.getTeachedUnits() != null)
        {
            for (CourseUnit c : units)
            {
                boolean isIn = false;
                for (CourseUnit tc : teacher.getTeachedUnits())
                {
                    if (tc.getId() == c.getId())
                    {
                        isIn = true;
                        break;
                    }
                }
                if (!isIn)
                {

                    /******Logging****/
                    1.5.0/docs/api/java/lang/String.html">String msg = "Adicionando unidade: " + ((CourseUnitImpl)c).getSigesUniqueIdentifiers() + " - ao teacher: " + teacher.getSigesCode() + " turma " + c.getCdTurma() + " - Associacao nova no SIGES";
                    serviceLogInfo(msg);
                    logger.info(msg);
                    unitsAddedToTeachers++;
                    /******Logging****/

                    teacher.getTeachedUnits().add(c);
                }
            }
        }
        else
            teacher.setTeachedUnits(units);
    }

    private TeacherImpl removerRemovidasLocalmente(Teacher teacher, Set<CourseUnit> units) {
        //2 - Sao retiradas da lista units as que o teacher tem mas que foram removidas localmente
        Iterator<CourseUnit> iter = units.iterator();
        TeacherImpl tImpl = (TeacherImpl) DaoFactory.getTeacherDaoImpl().narrow(teacher);
        while (iter.hasNext())
        {
            CourseUnit courseUnit = iter.next();
            //In case of a comming proxy
            if (tImpl.isLocalRemovedUnit(courseUnit))
            {
                /******Logging****/
                unitsLocallyRemovedNotAdded++;
                1.5.0/docs/api/java/lang/String.html">String msg = "Removendo unidade: " + ((CourseUnitImpl)courseUnit).getSigesUniqueIdentifiers() + " - do professor: " + tImpl.getSigesCode() + " - Associacao existe no SIGES mas foi removido LOCALMENTE";
                serviceLogInfo(msg);
                logger.info(msg);
                /******Logging****/

                iter.remove();
            }
        }
        return tImpl;
    }

    private Set<CourseUnit> obterCadeirasBacoCorrespondentes(1.5.0/docs/api/java/lang/String.html">String year, Docente teacherSiges, Teacher teacher, DefaultLogMessages logmessages,Map<CourseUnit,String> map_CourseUnit_x_Turma) {
        1.5.0/docs/api/java/lang/String.html">String msgS;
        Set<CourseUnit> units = new HashSet<CourseUnit>();

        for (Disciplina disciplina : teacherSiges.getDisciplinas())
        {
            List<CourseUnit> loadedunits = new ArrayList<CourseUnit>();
            if(disciplina.getCodigoCurso().intValue() < 0)
            {
                //O CODIGO DE CURSO VEM A NULL E E METIDO PELO DAO A -1
                //PORQUE OS ACADEMICOS NAO DEFINEM CURSO NA ASSOCIAÇÃO DO DOCENTE À TURMA NA TABELA T_DOC_TURMA
                //ISTO ACONTECE PORQUE A TURMA E MISTA E DE VARIOS CURSOS
                //NESTE CASO COLOCAMOS O DOCENTE NAS cadeiras dos cursos TODOS


                //todo futuro turmas separadas
                //neste caso das turmas separadas existe uma duvida:
                //Vir < 0 no codigo de curso significa que alunos de varios cursos podem estar nesta unidade
                //isso significa que nao temos cursos --> nao saber se é separated turmas
                //se nao sabemos se é separated turmas nunca podemos saber como ir buscar as unidades ao BACO
                // neste caso vamos busca-las sem a turma a descriminar e atribuimos todas ao docente.
                //a hipotese no futuro é, para todas as cadaeiras que forem devolvidas
                //corremos uma a uma e verificamos o seu curso, se for separated turmas e a turma for igual
                //a da disciplina adicionamos, se não for seprated turmas adicionamos sempre


                List<CourseUnit> courseUnits = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUniqueAllCourses("" + disciplina.getCodigo(), "" + disciplina.getCdDuracao(), "" + disciplina.getCdLectivo());
                if(courseUnits!=null)
                {
                    loadedunits = courseUnits;
                }

                /*******Logging************************/
                if(loadedunits.size() > 0)
                {
                    msgS = "Unit No Course -> course = " + disciplina.getCodigoCurso().intValue() + " semestre:" + disciplina.getCdDuracao() + " codigo:" + disciplina.getCodigo() + " year:" + disciplina.getCdLectivo()
                            + " will load of all possible courses:{ ";
                    for(CourseUnit cc : courseUnits)
                    {
                        msgS+= cc.getCourseCode() + ",";
                    }
                    msgS+=" } all added to teacher: " + teacher.getSigesCode();
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                    if(loadedunits.size() > 1)
                        unitsFoundForCourseNotFoundMult++;
                    else
                        unitsFoundForCourseNotFoundSingle++;
                    logger.warn(msgS);
                    serviceLogWarn(msgS);
                }
                /******Logging****/
            }
            else{

                boolean cursoFicticio = ImportStudentsService.isCursoFicticio(disciplina.getCodigoCurso());
                if(cursoFicticio)
                {
                    msgS = "WARNING WARNING #### Docente com curso ficticio, nao esperamos aqui cursos ficticios: " + disciplina.getCodigoCurso();
                    serviceLogWarn(msgS);
                    logger.warn(msgS);
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                    cursosFicticios++;
                    continue;
                }

                //Nao vamos usar este pormenor aqui. Caregamos todas e pronto. Os docentes ficam associados às duas unidades das duas turmas
                //mesmo no caso das turmas separadas. As tipologias tratam das associações às turmas para que não haja questionarios a mais
                //na criacao de questionarios é natural que falhe alguma coisa por haver aqui unidades a mais
                //por isso devera ser ai feita a verificacao destes casos
                boolean separateTurmas = ImportCourseService.loadCourseYearTurmasPolicy(disciplina.getCodigoCurso(), year, logmessages, this);
                /*
                este procedimento requer que a turma venha do siges, neste momento nao vem
                if(separateTurmas)
                    loadedunits = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUniqueWithTurma("" + disciplina.getCodigo(), "" + disciplina.getCodigoCurso(), "" + disciplina.getCdDuracao(), "" + disciplina.getCdLectivo(),disciplina.getCdTurma());
                else
                    loadedunits = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUnique("" + disciplina.getCodigo(), "" + disciplina.getCodigoCurso(), "" + disciplina.getCdDuracao(), "" + disciplina.getCdLectivo());
                */

                loadedunits = DaoFactory.getCourseUnitDaoImpl().loadBySigesCodeUnique("" + disciplina.getCodigo(), "" + disciplina.getCodigoCurso(), "" + disciplina.getCdDuracao(), "" + disciplina.getCdLectivo());
                /*******Logging************************/
                if(loadedunits.size() > 1 && !separateTurmas)
                {
                    unitsDuplicated++;
                    msgS = "WARNING WARNING #### UnitsDuplicated: ";
                    serviceLogWarn(msgS);
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                    msgS = "WARNING WARNING ####String sigesCode, String courseCode, String semestre, String year = " + disciplina.getCodigo() + ", " + disciplina.getCodigoCurso() + ","+ disciplina.getCdDuracao() + "," +  disciplina.getCdLectivo();
                    serviceLogWarn(msgS);
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                    msgS = "WARNING WARNING ####returning first one, this could be a case of units spared because of TURMAS split used in 201516: ";
                    serviceLogWarn(msgS);
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                }
                if(loadedunits.size() > 1 && separateTurmas)
                {
                    Map<String,String> turmas = new HashMap<String, String>();

                    for(CourseUnit c :loadedunits)
                    {
                        turmas.put(c.getCdTurma(),c.getCdTurma());
                    }
                    if(turmas.size() < loadedunits.size())
                    {
                        unitsDuplicated++;
                        msgS = "WARNING WARNING #### O Curso é de turmas separadas mas o docente tem unidades repetidas com a mesma turma: ";
                        serviceLogWarn(msgS);
                        logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                        logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                        msgS = "WARNING WARNING ####String sigesCode, String courseCode, String semestre, String year = " + disciplina.getCodigo() + ", " + disciplina.getCodigoCurso() + ","+ disciplina.getCdDuracao() + "," +  disciplina.getCdLectivo();
                        serviceLogWarn(msgS);
                    }
                    turmas.clear();
                }
                /*******Logging************************/
            }


            if (loadedunits.size() == 0)
            {
                /*******Logging************************/
                msgS = "Unit not found: semestre:" + disciplina.getCdDuracao() + " codigo:" + disciplina.getCodigo() + " course:" + disciplina.getCodigoCurso() + " year:" + disciplina.getCdLectivo();
                unitsNotFound++;
                if(disciplina.getCodigoCurso()==null || disciplina.getCodigoCurso().intValue() < 0)
                {
                    unitsNotFoundCourseNotFound++;
                    msgS += "... unit with No Course Found in SIGES";
                    logmessages.addMessage(new DefaultLogMessage("import.teachers", LogMessageTypeEnum.WARNING,msgS ));
                }
                else
                {
                    msgS += "... probably unit with zero students not imported in CoursesImport";
                }
                logger.warn(msgS);
                serviceLogWarn(msgS);
                /*******Logging************************/
            }
            else
            {
                for(CourseUnit found: loadedunits)
                {
                    map_CourseUnit_x_Turma.put(found,disciplina.getCdTurma());
                }
                units.addAll(loadedunits);
            }
        }
        return units;
    }

    private void updateTeacherFields(Docente teacherSiges, Teacher teacher, boolean newUser) {
        1.5.0/docs/api/java/lang/String.html">String msgS;
        if(newUser)
        {
            cloneFields(teacherSiges, teacher);

            /*******Logging************************/
            teachersNew++;
            serviceLogInfo("NOVO PROFESSOR ENCONTRADO: siges:" + teacherSiges.getCodigoFuncionario() + " bi:" + teacher.getBi() + " nome:" + teacher.getName());
            /*******Logging************************/
        }

        //CASO EM QUE O DOCENTE NO SIGES FOI ATRIBUIDO A OUTRO ESTUDANTE PARA PREENCHER BURACO NA NUMERACAO
        else if(teacherSiges.getNumeroBi() == null || teacher.getBi() == null || ! teacherSiges.getNumeroBi().equals(teacher.getBi()))
        {

            teachersChangeBI++;

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

            /*******Logging************************/
            builder.append("ATENCAO NUMERO DE PROFESSOR " + teacherSiges.getCodigoFuncionario() + " MUDOU DE DONO Confirme dados\n");
            builder.append("ALTERANDO DADOS DO PROFESSOR " + teacherSiges.getCodigoFuncionario() + "\n");
            builder.append("-------ANTES: " + "\n");
            builder.append("-------BI: " + teacher.getBi() + "\n");
            builder.append("-------Nome: " + teacher.getName() + "\n");
            builder.append("-------Username: " + teacher.getUserNameNetpa() + "\n");
            builder.append("-------Address: " + teacher.getAddress() + "\n");
            builder.append("-------Zip: " + teacher.getZip() + "\n");
            builder.append("-------Email: " + teacher.getEmail() + "\n");
            builder.append("-------Phone: " + teacher.getPhonenumber() + "\n");
            /*******Logging************************/


            cloneFields(teacherSiges, teacher);

            //teacher.setAutoBlockMode(false);
            //teacher.setManualBlock(true);

            /*******Logging************************/
            builder.append("DEPOIS: " + "\n");
            builder.append("BI: " + teacher.getBi() + "\n");
            builder.append("Nome: " + teacher.getName() + "\n");
            builder.append("Username: " + teacher.getUserNameNetpa() + "\n");
            builder.append("Address: " + teacher.getAddress() + "\n");
            builder.append("Zip: " + teacher.getZip() + "\n");
            builder.append("Email: " + teacher.getEmail() + "\n");
            builder.append("Phone: " + teacher.getPhonenumber() + "\n");
            serviceLogWarn(builder.toString());
            sendNotificationAdmin("CODIGO SIGES PROFESSOR " + teacherSiges.getCodigoFuncionario() + " MUDOU DE DONO - NAO FOI BLOQUEADO OS DADOS FORAM REPOSTOS ",builder.toString());
            /*******Logging************************/

        }
        else
        {
            //novo para termos sempre o email externo
            if(teacher.getOutEmail() == null ||teacher.getOutEmail().indexOf("@") < 0)
                teacher.setOutEmail(teacherSiges.getEmail());
            //VAMOS APENAS ADICIONAR CAMPOS QUE AINDA NAO EXISTAM IGUAL AO CLONE MAS NAO MECHE
            if(teacher.getName() == null || teacher.getName().length() == 0)
                teacher.setName(teacherSiges.getNomeFuncionarioInt());
            //Email instituicao
            //if(teacher.getEmail() == null || teacher.getEmail().indexOf("@") < 0)
            //    teacher.setEmail(teacherSiges.getEmail());

            1.5.0/docs/api/java/lang/String.html">String suffixReaded = null;
            List<String> sufixes = ConfigProperties.getListValues("email.local.suffix.");
            for(1.5.0/docs/api/java/lang/String.html">String suffix: sufixes)
            {
                if(teacherSiges.getEmail()!=null && teacherSiges.getEmail().endsWith("@"+suffix))
                {
                    suffixReaded = suffix;
                    break;
                }
            }

            if (teacherSiges.getEmail() != null && (teacher.getUsername() == null || teacher.getUsername().trim().length() == 0)
                    && suffixReaded != null)
            {
                int atIndex = teacherSiges.getEmail().indexOf("@");
                if (atIndex > 0)
                {
                    teacher.setUsername(teacherSiges.getEmail().substring(0, atIndex));
                    /*******Logging************************/
                    msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " foi-lhe atribuido o username d" + teacherSiges.getEmail().substring(0, atIndex);
                    logger.info(msgS);
                    serviceLogInfo(msgS);
                    /*******Logging************************/
                }
                else
                {
                    /*******Logging************************/
                    msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " NAO lhe foi atribuido username o email não tem o caracter @";
                    logger.info(msgS);
                    serviceLogInfo(msgS);
                    /*******Logging************************/
                }
            }
            else if(teacher.getUsername() == null || teacher.getUsername().trim().length() == 0)
            {
                /*******Logging************************/
                msgS = "Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " nao tem email no SIGES foi-lhe atribuido o username d" + teacherSiges.getCodigoFuncionario().intValue();
                logger.info(msgS);
                serviceLogInfo(msgS);
                /*******Logging************************/

                teacher.setUsername("d" + teacherSiges.getCodigoFuncionario().intValue());
            }
            else
            {
                //ALL OK
                //username não foi alterado
                //msgS="Teacher SIGES:" + teacherSiges.getCodigoFuncionario().intValue() + " nao lhe foi alterado o username " + teacher.getUsername();
                //logger.info(msgS);
                //serviceLogInfo(msgS);
            }
            teacher.setSigesCode(teacherSiges.getCodigoFuncionario().intValue());
            if(teacher.getAddress() == null || teacher.getAddress().length() == 0)
                teacher.setAddress(teacherSiges.getMorada());
            if(teacher.getZip() == null || teacher.getZip().length() == 0)
                teacher.setZip("" + teacherSiges.getCodigoPostal().intValue());
            if(teacher.getBi() == null || teacher.getBi().length() == 0)
                teacher.setBi(teacherSiges.getNumeroBi());
            teacher.setEmployerName(teacherSiges.getNomeFuncionario());
            teacher.setAcademicName(teacherSiges.getNomeAcademico());
            if(teacher.getBirthDate() == null || teacher.getBirthDate().getTime() == 0)
                teacher.setBirthDate(teacherSiges.getData_nascimento());
        }
    }

    @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();
        1.5.0/docs/api/java/lang/String.html">String institutionCode = getParametersMap().get(JOB_institution_KEY).getObject();
        return run(importYear,1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(institutionCode));
    }

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


    /**
     * 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();
        if(args != null && args.length > 0)
            year = args[0];
        1.5.0/docs/api/java/lang/String.html">String institutionCode = "1";
        if(args != null && args.length > 1)
            institutionCode = args[1];
        AbstractDao.getCurrentSession().beginTransaction();
        new ImportTeachersService().run(year,1.5.0/docs/api/java/lang/Integer.html">Integer.parseInt(institutionCode));
        AbstractDao.getCurrentSession().getTransaction().commit();
    }


}