/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.doctor.sicklist;
import framework.beans.EntityDetails;
import framework.beans.FacadeBean;
import beans.directory.simple.entities.DisabilityType;
import framework.beans.security.BeanRights;
import beans.doctor.sicklist.entity.SickLong;
import beans.doctor.sicklist.entity.SickLongDetails;
import beans.doctor.sicklist.entity.Sicklist;
import beans.doctor.sicklist.entity.SicklistDetails;
import beans.user.collaborator.entities.Collaborator;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.Stateful;
import beans.UserRightsSet;
import beans.directory.enterprise.Enterprise;
import beans.directory.lpu.entity.Lpu;
import beans.doctor.diagnosis.Diagnosis;
import beans.service.ServiceRender;
import framework.audit.AuditDoc;
import framework.generic.ESecurity;
import framework.utils.FormatChecker;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
/**
* @security ok
* @author axe
*/
@Stateful(mappedName="clips-beans/SicklistBean")
public class SicklistBean extends FacadeBean<Sicklist> implements SicklistBeanRemote {
public static int COMMAND_WRITE_SERIAL = 4;
public static int COMMAND_WRITE_CLOSE = 5;
public static int COMMAND_WRITE_LONG = 6;
public SicklistBean() {
super(Sicklist.class);
}
/* создание - открытие
* модификация
* - запись серийника
* - продление
* - закрытие
* удаление
*/
// внимание возможна проблеме если бин не будет Stateful
@Override
protected void initBeanRights() throws ClipsServerException {
Sicklist entity = (getId() == 0) ? null : getExistentEntity();
int[] r = new int[7];
r[COMMAND_CREATE] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
r[COMMAND_READ] = RightPresence(UserRightsSet.READ_MEDICAL_DATA.id);
if (entity != null) {
Collaborator opener = entity.getOpener();
Lpu lpu = findEntity(Collaborator.class, getCollaboratorId()).getLpu();
//выставление команд на модификацию
/*Запись серийника
* возможна при наличии соответствующего права
* только сотрудником из той же поликлиники, где был открыт больничный
*/
if (RightPresence(UserRightsSet.WRITE_SICKLIST_SERIAL.id) > 0) {
if (opener.getLpu().getId() == lpu.getId()) {
r[COMMAND_WRITE_SERIAL] = UserRightsSet.WRITE_SICKLIST_SERIAL.id;
} else {
r[COMMAND_WRITE_SERIAL] = -UserRightsSet.WRITE_SICKLIST_SERIAL.id;
}
} else {
r[COMMAND_WRITE_SERIAL] = -UserRightsSet.WRITE_SICKLIST_SERIAL.id;
}
/*Продление
* возможно при наличии права записывать мед данные, в любой поликлинике
*/
r[COMMAND_WRITE_LONG] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
/*Закрытие
* возможно при наличии права записывать мед данные, в любой поликлинике
* либо при наличии команды записи серийника (для закрытия в кабинете
* регистрации БЛ в случае неявки пациента)
*/
r[COMMAND_WRITE_LONG] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
if (r[COMMAND_WRITE_LONG] < 0 && r[COMMAND_WRITE_SERIAL] > 0) {
r[COMMAND_WRITE_LONG] = r[COMMAND_WRITE_SERIAL];
}
/* модификация возможна при любом из 3 случаев
*/
if (r[COMMAND_WRITE_CLOSE] > 0) {
r[COMMAND_MODIFY] = r[COMMAND_WRITE_CLOSE];
} else if (r[COMMAND_WRITE_LONG] > 0) {
r[COMMAND_MODIFY] = r[COMMAND_WRITE_LONG];
} else if (r[COMMAND_WRITE_SERIAL] > 0) {
r[COMMAND_MODIFY] = r[COMMAND_WRITE_SERIAL];
} else {
r[COMMAND_MODIFY] = -UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id;
}
/* Удаление возможно при таких же проверках как и для других
* медицинских данных (см. MedicalDataBean)
*/
int removeRight = 0;
if (RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id) > 0){
//Начинаем проверять со слабого права
removeRight = entity.getDiagOpen().getServiceRender().canWriteDuringDay(
isSuperUser(),
UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY,
getCollaboratorId());
}
if (RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME.id) > 0){
//Если есть более сильное право, то команда перезаписывается им
removeRight = entity.getDiagOpen().getServiceRender().canWriteAnyTime(
isSuperUser(),
UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME,
findEntity(Collaborator.class, getCollaboratorId()));
}
if (isSuperUser() && removeRight <= 0) {
//Если суперюзер, и прав нету или запрет то всеравно разрешаем по самому сильному праву
removeRight = UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME.id;
}
if (removeRight == 0) {
removeRight = -UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id;
}
r[COMMAND_REMOVE] = removeRight;
}
rights = new BeanRights(r);
}
@Override
protected void onRemove(Sicklist entity, List<AuditDoc> audit) throws ClipsServerException {
super.onRemove(entity, audit);
if (entity.getRegistrator() != null &&
(entity.getRegistrator().getId() != getCollaboratorId() || entity.getOpener().getId() != getCollaboratorId())) {
if (RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id) < 0) {
throw new ESecurity("Не возможно удалить выданный на руки больничный лист, нужно как минимум право \"" + UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME.getDescription() + "\"");
}
}
}
@SuppressWarnings("unchecked")
private void checkValidSicklistDiagnosis(Sicklist entity, Diagnosis diag) throws ClipsServerException{
if (diag.getReferenced() != null){
throw new EDataIntegrity("Диагноз больничного листа не может быть сопутствующим");
}
if (diag.getServiceRender().getDisease() == null){
throw new EDataIntegrity("Дигноз больничного должен быть добавлен в стат-талон");
}
boolean isHasCurSicklists = false;
@SuppressWarnings("unchecked")
ArrayList<Sicklist> list =
new ArrayList<Sicklist>(findEntityList(Sicklist.class, "diagOpen.id", diag.getId()));
list.addAll(findEntityList(Sicklist.class, "diagClose.id", diag.getId()));
topfor: for (Sicklist found : list) {
Sicklist cur = entity;
while (cur != null){
if (found.getId() == cur.getId()){
isHasCurSicklists = true;
}
cur = cur.getReferenced();
}
}
if (list.size() > 0 && !isHasCurSicklists){
throw new EDataIntegrity("По данному диагнозу уже выдан другой больничный лист");
}
}
private boolean onOpen(Sicklist entity, SicklistDetails d) throws ClipsServerException {
boolean actionPreformed = false;
if (getId() == 0) {
checkCommandAccessibility(COMMAND_CREATE);
actionPreformed = true;
//System.out.println("Открытие больничного");
if (d.entID != 0 && d.otherDirection != null) {
throw new EDataIntegrity("Запрещено указывать две организации, куда выдан больничный");
}
entity.setEnterprise(d.entID == 0 ? null: findEntity(Enterprise.class, d.entID));
entity.setOtherDirection(d.otherDirection);
Diagnosis diagnosis = findEntity(Diagnosis.class, d.diagOpenID);
Sicklist referenced = d.refID == 0? null: findEntity(Sicklist.class, d.refID);
entity.setReferenced(referenced);
//обновляем head
if(referenced != null) {
Sicklist head = referenced.getHead();
if(head == null) {
head = referenced;
}
entity.setHead(head);
}
entity.setComment(d.comment);
entity.setDisabilityType(findEntity(DisabilityType.class, d.disabID));
// доделал код виталия, сотрудника создавшего больничный, можно установить по первому sickLong
// (мое имхо отчеты будет выбирать страшний геморой)
if (d.openerID != 0){
if (d.altOpener != null){
throw new EDataIntegrity("Указано одновременно два сотрудника, открывших больничный лист");
}
if (d.altLpu != null){
throw new EDataIntegrity("Сотрудниник этой поликлиники выдал больнчный альтернативной. Внутренняя ошибка.");
}
entity.setOpener(findEntity(Collaborator.class, d.openerID));
entity.setAltlpu(null);
entity.setAltopener(null);
}else{
if (d.altLpu == null){
throw new EDataIntegrity("Не указанна организация выдавшая больничный");
}
if (d.altOpener == null || d.altOpener.trim().length() < 3){
throw new EDataIntegrity("Не указан сотрудник, открывший больничный лист");
}
entity.setOpener(null);
entity.setAltlpu(d.altLpu);
entity.setAltopener(d.altOpener);
}
entity.setDateOpen(d.dateOpen);
// после того как был установлен Referenced
checkValidSicklistDiagnosis(entity, diagnosis);
if (referenced != null){
if (referenced.getDiagClose() == null){
throw new EDataIntegrity("Попытка продления незакрытого больничного листа, сперва закройте больничный лист");
}
if (referenced.getDiagOpen().getServiceRender().getDisease().getEmc().getId()
!= diagnosis.getServiceRender().getDisease().getEmc().getId()){
throw new EDataIntegrity("Продляемый больничный находится в другой медицинской карте");
}
}
entity.setDiagOpen(diagnosis);
if (d.sickLongList == null || d.sickLongList.size() == 0){
throw new EDataIntegrity("Не установлена дата окончания действия больничного");
}
}else{
if (false
|| !isEntityEqualID(entity.getEnterprise(), d.entID)
|| !nullEqual(entity.getOtherDirection(), d.otherDirection)
|| !isEntityEqualID(entity.getReferenced(), d.refID)
|| !isEntityEqualID(entity.getDisabilityType(), d.disabID)
|| !isEntityEqualID(entity.getOpener(), d.openerID)
|| !nullEqual(entity.getAltlpu(), d.altLpu)
|| !nullEqual(entity.getAltopener(), d.altOpener)
|| !entity.getDateOpen().equals(d.dateOpen)
|| !nullEqual(entity.getOtherDirection(), d.otherDirection)
|| !isEntityEqualID(entity.getDiagOpen(), d.diagOpenID)
){
throw new EDataIntegrity("Запрещено свободное редактирование больничного листа");
}
}
return actionPreformed;
}
private boolean onSetSerial(Sicklist entity, SicklistDetails d) throws ClipsServerException {
boolean actionPreformed = false;
if (entity.getSerial() == null && d.serial != null){
//System.out.println("Внесение серийного номера в больничный");
// больничный создан с серийным номером
if (entity.getId() != 0) {
checkCommandAccessibility(COMMAND_WRITE_SERIAL);
}
actionPreformed = true;
String msg = FormatChecker.check(FormatChecker.SICK_LIST_SERIAL, d.serial);
if(msg != null) {
throw new EDataIntegrity(msg);
}
entity.setSerial(d.serial);
entity.setComment(d.comment);
entity.setRegistrator(findEntity(Collaborator.class, getCollaboratorId()));
}else{
if (false
|| !nullEqual(entity.getSerial(), d.serial)
|| !isEntityEqualID(entity.getRegistrator(), d.registratorID)
){
throw new EDataIntegrity("Запрещено свободное редактирование больничного листа");
}
}
return actionPreformed;
}
private boolean onClose(Sicklist entity, SicklistDetails d) throws ClipsServerException {
boolean actionPreformed = false;
if (entity.getDateToWork() == null && d.dateToWork != null) {
checkCommandAccessibility(COMMAND_WRITE_CLOSE);
actionPreformed = true;
//System.out.println("Закрытие больничного");
if (entity.getSerial() == null || entity.getSerial().trim().isEmpty()) {
throw new EDataIntegrity("Запрещено закрывать больничный без серийного номера");
}
entity.setDateToWork(d.dateToWork);
if (d.closerID != getCollaboratorId() && !isSuperUser()){
throw new ESecurity("Запрещено указывать другого пользователя при продлении");
}
entity.setCloser(findEntity(Collaborator.class, d.closerID));
entity.setComment(d.comment);
entity.setSerrenClosed(d.serrenCloseID == 0 ? null : findEntity(ServiceRender.class, d.serrenCloseID));
if (d.diagCloseID == 0){
throw new EDataIntegrity("не установлен диагноз закрытия.");
}
Diagnosis diagnosis = findEntity(Diagnosis.class, d.diagCloseID);
checkValidSicklistDiagnosis(entity, diagnosis);
if (entity.getDiagOpen().getServiceRender().getDisease().getEmc().getId() != diagnosis.getServiceRender().getDisease().getEmc().getId()){
throw new EDataIntegrity("Диагнозы открытия и закрытия находятся в разных медицинских картах");
}
entity.setDiagClose(diagnosis);
if (d.serrenCloseID == 0) {
throw new EDataIntegrity("Не установлен талон или услуга закрытия.");
}
ServiceRender serrenClose = findEntity(ServiceRender.class, d.serrenCloseID);
entity.setSerrenClosed(serrenClose);
}else{
if (false
|| !nullEqual(entity.getDateToWork(), d.dateToWork)
|| !isEntityEqualID(entity.getCloser(), d.closerID)
|| !isEntityEqualID(entity.getSerrenClosed(), d.serrenCloseID)
|| !isEntityEqualID(entity.getDiagClose(), d.diagCloseID)
){
throw new EDataIntegrity("Запрещено свободное редактирование больничного листа");
}
}
return actionPreformed;
}
/**
* Обновляет данные сущности.
* @param entity
* @param details новые детали сущности
* @throws ClipsServerException
*/
@Override
protected void onUpdate(Sicklist entity, EntityDetails details,
AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException{
SicklistDetails d = (SicklistDetails) details;
boolean actionPreformed = false;
//Разграничение по действиям
//открытие больничного
if (onOpen(entity, d)){
actionPreformed = true;
}
// Внесение серийного номера в больничный
if (onSetSerial(entity, d)){
actionPreformed = true;
}
// закрытие больничного
if (onClose(entity, d)){
actionPreformed = true;
}
if (!nullEqual(entity.getComment(), d.comment)){
throw new EDataIntegrity("Запрещено свободное редактирование больничного листа");
}
//Проверка может продление
ArrayList<SickLongDetails> newList = d.sickLongList;
ArrayList<SickLongDetails> oldList = entity.getSickLongList(this);
if (newList.containsAll(oldList) && newList.size() > oldList.size()) {
checkCommandAccessibility(COMMAND_WRITE_LONG);
actionPreformed = true;
//System.out.println("Продление больничного");
setSickLongList(entity, d.sickLongList, auditDocList);
}
}
@Override
protected void afterUpdate(Sicklist entity, boolean isNewEntity, EntityDetails details, List<AuditDoc> audit) throws ClipsServerException {
super.afterUpdate(entity, isNewEntity, details, audit);
initBeanRights();
}
/**
* Возможно только добавление, иначе эксепшен
* @param newList
* @throws generic.ClipsServerException
*/
private void setSickLongList(Sicklist entity, ArrayList<SickLongDetails> newList,
List<AuditDoc> auditDocList) throws ClipsServerException {
if (newList.size() > Sicklist.SICKLIST_PROLONGATION_LIMIT) {
throw new EDataIntegrity("Нельзя делать записи об освобождении от работы более "
+ Sicklist.SICKLIST_PROLONGATION_LIMIT + " раз");
}
Collection<SickLongDetails> oldList = entity.getSickLongList(this);
//Проверка - все ли старые записи находятся в новых
if (!newList.containsAll(oldList)) {
throw new EDataIntegrity("Запрещено изменять существующие продления больничного");
}
for (int i = 0; i < newList.size(); i++) {
SickLongDetails sickLongDetails = newList.get(i);
if (!oldList.contains(sickLongDetails)) {
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(sickLongDetails.date);
calendar.add(GregorianCalendar.DAY_OF_MONTH, -1);
Date compareDate = calendar.getTime();
for (SickLongDetails oldDetail : oldList) {
if (oldDetail.date.compareTo(compareDate) > 0){
throw new EDataIntegrity("Больничный должен быть продлен как минимум на один день");
}
}
//Сохранение новой сущности продления
SickLong sickLong = new SickLong();
AuditDoc<SickLong> auditDoc = new AuditDoc<SickLong>(sickLong, getCollaborator());
sickLong.setSicklist(entity);
if (sickLongDetails.collID != getCollaboratorId() && !isSuperUser()){
throw new ESecurity("Запрещено указывать другого пользователя при продлении");
}
sickLong.setCollaborator(findEntity(Collaborator.class, sickLongDetails.collID));
sickLong.setDate(sickLongDetails.date);
sickLong.setSerren(findEntity(ServiceRender.class, sickLongDetails.serrenID));
entity.addSickLong(sickLong);
//saveEntity(sickLong);
checkAudit(auditDocList, auditDoc, sickLong);
}
}
}
}