/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.doctor.disease;
import framework.beans.EntityDetails;
import framework.beans.FacadeBean;
import framework.beans.security.BeanRights;
import beans.doctor.diagnosis.Diagnosis;
import beans.doctor.diagnosis.DiagnosisDetails;
import beans.profcheckup.entity.ProfcheckupItem;
import beans.directory.simple.entities.DiagnosisType;
import beans.doctor.emc.Emc;
import beans.service.ServiceRender;
import beans.service.ServiceRenderDetails;
import beans.user.collaborator.entities.Collaborator;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import javax.ejb.EJBException;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import beans.UserRightsSet;
import beans.followup.entity.Followup;
import beans.followup.entity.FollowupEvent;
import beans.profcheckup.ProfcheckupItemBeanRemote;
import beans.profcheckup.entity.Profcheckup;
import beans.directory.simple.entities.DiseaseResult;
import beans.directory.simple.entities.VisitingPurpose;
import beans.service.medexam.Medexam;
import beans.service.medexam.MedexamDetails;
import beans.doctor.sicklist.entity.SickLong;
import beans.doctor.sicklist.entity.Sicklist;
import beans.doctor.sicklist.entity.SicklistDetails;
import beans.profcheckup.ProfcheckupItemBean;
import framework.audit.AuditDoc;
import framework.generic.ESecurity;
import framework.security.RightChecker;
import framework.security.SecurityChecker;
import framework.utils.DateTimeUtils;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Set;
/**
* @security - Ok.
* @author axe
*/
@Stateful(mappedName="clips-beans/DiseaseBean")
public class DiseaseBean extends FacadeBean<Disease>
implements DiseaseBeanRemote, DiseaseBeanLocal {
public static int COMMAND_CLOSE = 4;
public DiseaseBean() {
super(Disease.class);
}
@Override
protected void initBeanRights() {
int[] r = new int[5];
r[COMMAND_READ] = RightPresence(UserRightsSet.READ_MEDICAL_DATA.id);
int cmr = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
r[COMMAND_CREATE] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
r[COMMAND_MODIFY] = 0;
r[COMMAND_REMOVE] = cmr;
r[COMMAND_CLOSE] = RightPresence(UserRightsSet.WRITE_DISEASE_CLOSE.id);
rights = new BeanRights(r);
}
/**
* Обновляет данные сущности.
* @param details новые детали сущности
* @throws EJBException в случае если обновление отвергнуто системой
* безопастности либо произошла ошибка
* @return идентификатор сущности
*/
@Override
protected void onUpdate(Disease entity, EntityDetails details,
AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException {
DiseaseDetails d = (DiseaseDetails) details;
if (entity.getId() == 0) {
//Создание нового заболевания
if (d.closed != null || d.closerID != 0) {
throw new EDataIntegrity("Нельзя создавать сразу закрытые заболевания");
}
//d.created может быть нуллом
if (!DateTimeUtils.belongsToCurrentDay(d.created) || d.collaboratorID != getCollaboratorId()) {
if (!hasRight(UserRightsSet.WRITE_STATISTIC_MEDICAL_DATA) && !isSuperUser()) {
throw new ESecurity(SecurityChecker.getClientHasNoRightMsg(UserRightsSet.WRITE_STATISTIC_MEDICAL_DATA.id));
}
}
entity.setCreated(d.created);
entity.setDateReg(d.dateReg);
entity.setExtKey(d.extKey == 0 ? null : d.extKey);
} else {
if (entity.getEmc().getId() != d.emcID) {
throw new EDataIntegrity("Cмена ЭМК недопустима");
}
if (entity.getCollaborator().getId() != d.collaboratorID) {
throwNeedAdminSecurityException("Cмена сотрудника недопустима");
}
if (d.closed == null && d.closerID != 0) {
throw new EDataIntegrity("В заболевании если не указана дата закрытия нельзя указывать сотрудника, закрывшего заболевание");
}
if (d.closed != null && d.closerID == 0) {
throw new EDataIntegrity("В заболевании при указании даты закрытия необходимо указывать сотрудника");
}
if (entity.getClosed() == null) {
//был открыт
if (!isSuperUser()) {
if (d.closed != null) {
if (getSpecificDiagnosis() == null) {
throw new EDataIntegrity("Нельзя закрывать заболевание без заключительного диагноза");
}
if (d.visitingPurposeID == 0) {
throw new EDataIntegrity("Нельзя закрывать заболевание без указания цели посещения");
}
if (d.diseaseResultID == 0) {
throw new EDataIntegrity("Нельзя закрывать заболевание без указания результата обращения");
}
checkCommandAccessibility(COMMAND_CLOSE);
checkCurrentCollaborator(d.closerID);
Field f[] = {
new Field("disease", entity),
new Field("renderedDate", "", Field.OPERATOR_IS_NULL)
};
if (getEntityCount(ServiceRender.class, f) > 0) {
throw new EDataIntegrity("Нельзя закрывать заболевание связанное с неоказанными услугам");
}
}
}
} else {
//был закрыт
if (!isSuperUser()) {
if (d.closed == null) {
throw new EDataIntegrity("Нельзя открывать уже закрытые заболевания");
} else {
if (!d.closed.equals(entity.getClosed())) {
throw new EDataIntegrity("Нельзя изменять дату закрытия заболевания");
}
if (d.closerID != entity.getCloser().getId()) {
throw new EDataIntegrity("Нельзя изменять сотрудника, закрывшего заболевание");
}
}
}
}
}
entity.setEmc(findEntity(Emc.class, d.emcID));
entity.setCollaborator(findEntity(Collaborator.class, d.collaboratorID));
entity.setClosed(d.closed);
entity.setCloser(d.closerID == 0 ? null : findEntity(Collaborator.class, d.closerID));
entity.setVisitingPurpose(d.visitingPurposeID == 0 ? null : findEntity(VisitingPurpose.class, d.visitingPurposeID));
entity.setDiseaseResult(d.diseaseResultID == 0 ? null : findEntity(DiseaseResult.class, d.diseaseResultID));
}
/**
*
* @throws generic.ClipsServerException
*/
@Override
protected void onRemove(Disease entity, List<AuditDoc> audit) throws ClipsServerException {
if (entity.getClosed() != null) {
throwNeedAdminSecurityException("Невозможно удалить закрытое заболевание");
}
Field f[] = {new Field("disease", entity)};
//Ибо удаляя профосмотр никто не хочет чистить всё ручками
List<ProfcheckupItem> items = findEntityList(ProfcheckupItem.class, f);
if (items.size() > 0) {
for (ProfcheckupItem profcheckupItem : items) {
ProfcheckupItemBeanRemote bean = getBean(ProfcheckupItemBean.class);
bean.initByID(profcheckupItem.getId(), getSessionId());
bean.remove();
}
}
if (getEntityCount(ServiceRender.class, f) > 0) {
throw new EDataIntegrity("Заболевание содержит услуги, удаление невозможно");
}
if (getEntityCount(FollowupEvent.class, f) > 0) {
throwNeedAdminSecurityException("Данное заболевание связано с диспансерным учётом, удаление невозможно");
deleteEntityList2(FollowupEvent.class, f, audit);
}
if (getEntityCount(Medexam.class, f) > 0) {
throw new EDataIntegrity("Данное заболевание связано с медосмотром, удаление невозможно");
}
}
/**
* Возвращает список оказанных и оказываемых услуг для данного заболевания
* и не отмененные
* @return список услуг
*/
@Override
public List<ServiceRenderDetails> getServiceRenders() throws ClipsServerException {
Disease entity = getExistentEntity();
Field fields[] = {
new Field("disease", entity),
new Field("cancelled", false)
};
List list = findEntityList(ServiceRender.class, fields);
Collections.sort(list, new Comparator<ServiceRender>() {
@Override
public int compare(ServiceRender o1, ServiceRender o2) {
return o1.getDate().compareTo(o2.getDate());
}
});
List<ServiceRenderDetails> res = new ArrayList<ServiceRenderDetails>();
Iterator i = list.iterator();
while (i.hasNext()) {
ServiceRender j = (ServiceRender) i.next();
res.add((ServiceRenderDetails) j.getDetails((RightChecker) this));
}
return res;
}
/**
* Является ли заболевание профосмотром
* @return
* @throws generic.ClipsServerException
*/
@Override
public Date getProfcheckupDate() throws ClipsServerException {
Disease entity = getExistentEntity();
String sql = "SELECT DISTINCT pch FROM Profcheckup pch, ProfcheckupItem pi " +
" WHERE pi.disease =:st AND pi.profcheckup = pch";
Query q = manager.createQuery(sql);
q.setParameter("st", entity);
int count = q.getResultList().size();
if (count > 1) {
throw new ClipsServerException("Более одного профосмотра (" + count + ") ссылаются на одно заболевание");
}
if (count < 1){
return null;
}
return ((Profcheckup)q.getResultList().get(0)).getDatefrom();
}
@Override
public DiseaseFolluwupPrintInfo getFollowupPrintInfo() throws ClipsServerException {
Disease currentDisease = getExistentEntity();
DiseaseFolluwupPrintInfo info = new DiseaseFolluwupPrintInfo();
String sql = "SELECT d FROM Diagnosis d WHERE d.serviceRender.disease=:st " +
"AND d.type.id=:diagfinal " +
"AND d.referenced IS NULL";
Query q = manager.createQuery(sql);
q.setParameter("st", currentDisease);
q.setParameter("diagfinal", +DiagnosisType.DIAGNOSIS_TYPE_FINAL);
List list = q.getResultList();
if (!list.isEmpty()){
Diagnosis finalDiag = (Diagnosis) list.get(0);
info.mainFollowStage = getFollowupStage(finalDiag);
if (info.mainFollowStage == Followup.FOLLOWUP_GET_OUT){
info.mainFollowDownReason = getDownReasonExtKey(finalDiag);
}
List<Diagnosis> diagnosises = findEntityList(Diagnosis.class, "referenced", finalDiag);
if (diagnosises.size() > 0){
Diagnosis d = diagnosises.get(0);
info.attendant0DiagnosisMkbID = d.getMkb10().getId();
info.attendant0FollowStage = getFollowupStage(d);
if (d.getEncounter() == null) {
info.attendant0DiagnosisEncounter = 1;
} else {
info.attendant0DiagnosisEncounter = d.getEncounter().isPlus() ? 1 : 2;
}
if (info.attendant0FollowStage != 0){
if (info.attendant0FollowStage == Followup.FOLLOWUP_GET_OUT){
info.attendant0FollowDownReason = getDownReasonExtKey(d);
}
}
}
if (diagnosises.size() > 1){
Diagnosis d = diagnosises.get(1);
info.attendant1DiagnosisMkbID = d.getMkb10().getId();
info.attendant1FollowStage = getFollowupStage(d);
if (d.getEncounter() == null) {
info.attendant1DiagnosisEncounter = 1;
} else {
info.attendant1DiagnosisEncounter = d.getEncounter().isPlus() ? 1 : 2;
}
if (info.attendant1FollowStage == 0){
if (info.attendant1FollowStage == Followup.FOLLOWUP_GET_OUT){
info.attendant1FollowDownReason = getDownReasonExtKey(d);
}
}
}
}
return info;
}
private int getDownReasonExtKey(Diagnosis diagnosis){
Field[] fields = new Field[]{
new Field("serrenDown", "", Field.OPERATOR_NOT_NULL),
new Field("diagnosisUp", diagnosis),};
List<Followup> list = findEntityList(Followup.class, fields);
if (list.size() > 0){
return Integer.parseInt(list.get(0).getDownReason().getExtKey());
}
return 0;
}
private int getFollowupStage(Diagnosis diagnosis) throws ClipsServerException{
Date created = DateTimeUtils.getDateOnly(getExistentEntity().getCreated());
Field[] fieldsIs0 = new Field[]{
new Field("dateup", created, Field.OPERATOR_EQUAL_OR_LESS),
new Field("datedown", created, Field.OPERATOR_EQUAL_OR_MORE),
new Field("diagnosisUp.mkb10", diagnosis.getMkb10()),};
Field[] fieldsIs1 = new Field[]{
new Field("dateup", created, Field.OPERATOR_EQUAL_OR_LESS),
new Field("datedown", "", Field.OPERATOR_IS_NULL),
new Field("diagnosisUp.mkb10", diagnosis.getMkb10()),};
Field[] fieldsGetIn = new Field[]{
new Field("diagnosisUp", diagnosis),};
Field[] fieldsGetOut = new Field[]{
new Field("serrenDown.disease", getExistentEntity()),
new Field("diagnosisUp.mkb10", diagnosis.getMkb10()),};
int followupIs = getEntityCount(Followup.class, fieldsIs0);
followupIs += getEntityCount(Followup.class, fieldsIs1);
int followupGetIn = getEntityCount(Followup.class, fieldsGetIn);
int followupGetOut = getEntityCount(Followup.class, fieldsGetOut);
if (followupGetIn > 0){
return Followup.FOLLOWUP_GET_IN;
}
if (followupGetOut > 0){
return Followup.FOLLOWUP_GET_OUT;
}
if (followupIs > 0) {
return Followup.FOLLOWUP_IS;
}
return 0;
}
@Override
public SicklistDetails getSickListData(Set<Integer> serIDs) {
Field field[] = {new Field("serren.id", serIDs, Field.OPERATOR_IN)};
List<SickLong> sicklongList = findEntityList(SickLong.class, field);
Collections.sort(sicklongList, new Comparator<SickLong>() {
@Override
public int compare(SickLong o1, SickLong o2) {
return framework.utils.Comparator.compareDates(o1.getDate(), o2.getDate());
}
});
Field field1[] = {new Field("serrenClosed.id", serIDs, Field.OPERATOR_IN)};
List<Sicklist> sickLists = findEntityList(Sicklist.class, field1);
Collections.sort(sickLists, new Comparator<Sicklist>() {
@Override
public int compare(Sicklist o1, Sicklist o2) {
return framework.utils.Comparator.compareDates(o1.getDateToWork(), o2.getDateToWork());
}
});
SickLong sickLong = null;
if (!sicklongList.isEmpty()) {
sickLong = sicklongList.get(sicklongList.size() - 1);
}
Sicklist sicklist = null;
if (!sickLists.isEmpty()) {
sicklist = sickLists.get(sickLists.size() - 1);
}
if (sickLong == null && sicklist == null) {
return null;
} else if (sickLong == null) {
return sicklist.getDetails(this);
} else if (sicklist == null) {
return sickLong.getSicklist().getDetails(this);
} else if (sickLong.getDate().after(sicklist.getDateToWork())) {
return sickLong.getSicklist().getDetails(this);
} else {
return sicklist.getDetails(this);
}
}
@Override
public boolean isFollowupEvent() throws ClipsServerException {
Field f[] = {new Field("disease", getExistentEntity())};
return getEntityCount(FollowupEvent.class, f) > 0;
}
@Override
public MedexamDetails getMedexam() throws ClipsServerException {
List<Medexam> findEntityList = findEntityList(Medexam.class, "disease", getExistentEntity());
if (findEntityList.size() == 0) {
return null;
} else {
return findEntityList.get(0).getDetails(this);
}
}
@Override
public DiagnosisDetails getSpecificDiagnosis() throws ClipsServerException {
return getSpecificDiagnosis(getExistentEntity(), manager);
}
/**
* Возвращает первый попавшийся заключительный, диагноз (mkb10ID)
* предполагается что в заболевании может существовать только один заключительный диагноз
* @param disease
* @param manager
* @return may be null if diagnosis not found
* @throws ClipsServerException
*/
public static DiagnosisDetails getSpecificDiagnosis(Disease disease, EntityManager manager) throws ClipsServerException {
String sql = "SELECT d FROM Diagnosis d WHERE d.serviceRender.disease.id=:st AND d.type.id=:diagfinal AND d.referenced IS NULL";
Query q = manager.createQuery(sql);
q.setParameter("st", disease.getId());
q.setParameter("diagfinal", +DiagnosisType.DIAGNOSIS_TYPE_FINAL);
List<Diagnosis> resultList = q.getResultList();
if (resultList.size() == 0) {
return null;
} else {
return resultList.get(0).getDetails(null);
}
}
public static HashMap<Disease, DiagnosisDetails> getSpecificDiagnosis(Emc emc, EntityManager manager) {
String sql = "SELECT d FROM Diagnosis d WHERE d.serviceRender.disease.emc.id=:emcID AND d.type.id=:diagfinal AND d.referenced IS NULL";
Query q = manager.createQuery(sql);
q.setParameter("emcID", emc.getId());
q.setParameter("diagfinal", +DiagnosisType.DIAGNOSIS_TYPE_FINAL);
List<Diagnosis> resultList = q.getResultList();
HashMap<Disease, DiagnosisDetails> res = new HashMap<Disease, DiagnosisDetails>();
for (Diagnosis diagnosis : resultList) {
Disease disease = diagnosis.getServiceRender().getDisease();
if (!res.containsKey(disease)) {
res.put(disease, diagnosis.getDetails(null));
}
}
return res;
}
}