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