/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.shedule.reception;
import framework.beans.SecuredBean;
import framework.beans.security.BeanRights;
import beans.service.ServiceRender;
import beans.user.client.entity.Client;
import beans.user.collaborator.entities.Collaborator;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import java.util.ArrayList;
import java.util.Date;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.Query;
import beans.UserRightsSet; import framework.security.RightChecker;
/**
* Бин контролирует запись пациентов на прием
* @author axe
* @security OK
*/
@Stateful(mappedName="clips-beans/SheduleReceptionBean")
public class SheduleReceptionBean extends SecuredBean
implements SheduleReceptionBeanRemote {
public static int COMMAND_CREATE = 0;
public static int COMMAND_CREATE_OWN = 1;
public static int COMMAND_MODIFY = 2;
public static int COMMAND_MODIFY_OWN = 3;
@Override
protected void initBeanRights() {
int[] r = new int[4];
r[COMMAND_CREATE] = RightPresence(UserRightsSet.CREATE_RECEPTION.id);
r[COMMAND_CREATE_OWN] = RightPresence(UserRightsSet.CREATE_OWN_RECEPTION.id);
r[COMMAND_MODIFY] = RightPresence(UserRightsSet.CREATE_RECEPTION.id);
r[COMMAND_MODIFY_OWN] = RightPresence(UserRightsSet.CREATE_OWN_RECEPTION.id);
rights = new BeanRights(r);
}
/**
* Возвращает список запланированных приемов за указанный период
* @param collaboratorID сотрудник
* @param begin дата начала периода
* @param end дата конца периода
* @return список приемов
* @throws generic.ClipsServerException
* @security без ограничений
*/
@Override
public List<SheduleReceptionDetails> getReceptionList(int collaboratorID, Date begin, Date end)
throws ClipsServerException {
Field f[] = {
new Field("begin", begin, Field.OPERATOR_EQUAL_OR_MORE) ,
new Field("begin", end, Field.OPERATOR_LESS),
new Field("collaborator", findEntity(Collaborator.class, collaboratorID))
};
Collection<SheduleReception> list = findEntityList(SheduleReception.class, f);
List<SheduleReceptionDetails> res = new ArrayList<SheduleReceptionDetails>();
Iterator<SheduleReception> i = list.iterator();
while(i.hasNext()) {
SheduleReception j = (SheduleReception) i.next();
res.add(j.getDetails((RightChecker) this));
}
//load reception services
for(int j=0; j<res.size(); j++) {
SheduleReceptionDetails d = res.get(j);
Iterator<ServiceRender> ser = findEntityList(ServiceRender.class, "reception.id", d.id).iterator();
while(ser.hasNext()) {
ServiceRender sr = (ServiceRender) ser.next();
d.serviceRenders.add(sr.getId());
}
}
return res;
}
/**
* Добавляет или обновляет прием. Если details.id = 0 сущность создается,
* иначе обновляется существующая с заданным идентификатором.
* @param details данные
* @return идентификатор сущности
* @throws ClipsServerException
* @security если создается запись в своем расписании нужно право CREATE_OWN_RECEPTION,
* если в чужом расписании - CREATE_RECEPTION, при модицикации записи нужны соответсвенно
* права MODIFY_OWN_RECEPTION и MODIFY_RECEPTION
* Нельзя модифицировать и создавать приемы за прошлые дни
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public int setReception(SheduleReceptionDetails details) throws ClipsServerException {
//бин д/б аутентифицирован
checkAuthentic();
//ОДЗ
if(details.duration <= 0) {
throw new ClipsServerException("Нельзя записать на прием с нулевой длительностью");
}
checkIsNotInThePast(details.begin);
//check service renders
List<ServiceRender> ls = new ArrayList<ServiceRender>();
for(int i=0; i<details.serviceRenders.size(); i++) {
Integer sid = details.serviceRenders.get(i);
ServiceRender ser = findEntity(ServiceRender.class, sid);
if(ser.isRendered()) {
throwNeedAdminSecurityException("Одна из услуг уже оказана");
}
if(ser.getCancelled()) {
throwNeedAdminSecurityException("Одна из услуг уже отменена");
}
if(ser.getPolis().getClient().getId() != details.clientID) {
throw new EDataIntegrity("Попытка записать услугу пациента в прием другого");
}
ls.add(ser);
}
Collaborator collab = findEntity(Collaborator.class, details.collaboratorID);
if(collab.isTrash()) {
throw new ClipsServerException("Нельзя записать на прием к уволенному сотруднику");
}
SheduleReception sr = null;
if(details.id != 0) {
sr = findEntity(SheduleReception.class, details.id);
//check rights
if(!isCommandAccessible(COMMAND_MODIFY)) {
if(sr.getAuthor().getId() == getCollaboratorId()) {
checkCommandAccessibility(COMMAND_MODIFY_OWN);
} else {
checkCommandAccessibility(COMMAND_MODIFY);
}
}
// check existent entity not in the past
checkIsNotInThePast(sr.getBegin());
if(sr.getClient().getId() != details.clientID) {
throwNeedAdminSecurityException("Попытка подмены пациента");
}
if(sr.getCollaborator().getId() != details.collaboratorID) {
throwNeedAdminSecurityException("Попытка подмены сотрудника");
}
updateOrphanServices(ls, details.id);
} else {
//check rights
if(!isCommandAccessible(COMMAND_CREATE)) {
if(details.collaboratorID == getCollaboratorId()) {
checkCommandAccessibility(COMMAND_CREATE_OWN);
} else {
checkCommandAccessibility(COMMAND_CREATE);
}
}
sr = new SheduleReception();
sr.setClient(findEntity(Client.class, details.clientID));
sr.setCollaborator(collab);
sr.setAuthor(findEntity(Collaborator.class, getCollaboratorId()));
}
sr.setBegin(details.begin);
sr.setDuration(details.duration);
sr.setDescription(details.description);
sr.setConfirmed(true);
sr.setRegister(new Date());
int id = saveEntity(sr);
if(ls.size() > 0) {
updateLinkedServices(ls, sr);
}
return id;
}
/**
* обновляет все оказываемые услуги, привязанные к данному приему, которые
* эту привязку потеряли
* @param ls список привязанных услуг, может быть null или пустым
* @param receptionId идентифкатор приема
*/
private void updateOrphanServices(List<ServiceRender> ls, int receptionId) {
String sql = "UPDATE ServiceRender sr SET sr.reception=null WHERE sr.reception.id=:rec";
if(ls != null && ls.size() > 0) {
sql += " AND sr.id NOT IN (";
for(int i=0; i<ls.size(); i++) {
if(i>0) {
sql += ",";
}
sql += ":ser" + i;
}
sql += ")";
}
Query query = manager.createQuery(sql);
query.setParameter("rec", receptionId);
if(ls != null) {
for(int i=0; i<ls.size(); i++) {
query.setParameter("ser" + i, ls.get(i).getId());
}
}
query.executeUpdate();
}
/**
* Привязывает услуги к приему
* @param ls список идентифкаторов услуг, не должен быть пустым
* @param receptionId
*/
private void updateLinkedServices(List<ServiceRender> ls, SheduleReception rec) {
String sql = "UPDATE ServiceRender sr SET sr.reception=:rec"
+ " WHERE sr.id IN (";
for(int i=0; i<ls.size(); i++) {
if(i>0) {
sql += ",";
}
sql += ":ser" + i;
}
sql += ")";
Query query = manager.createQuery(sql);
query.setParameter("rec", rec);
for(int i=0; i<ls.size(); i++) {
query.setParameter("ser" + i, ls.get(i).getId());
}
query.executeUpdate();
}
/**
* Удаляет запись на прием
* @param id идентификатор приема
* @throws ClipsServerException
* @security если удаляется запись в своем расписании нужно право MODIFY_OWN_RECEPTION,
* если в чужом расписании - MODIFY_RECEPTION
* Нельзя удалять приемы за прошлые дни
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public void removeReception(int id) throws ClipsServerException {
SheduleReception sr = findEntity(SheduleReception.class, id);
checkIsNotInThePast(sr.getBegin());
//check rights
if(!isCommandAccessible(COMMAND_MODIFY)) {
if(sr.getAuthor().getId() == getCollaboratorId()) {
checkCommandAccessibility(COMMAND_MODIFY_OWN);
} else {
checkCommandAccessibility(COMMAND_MODIFY);
}
}
updateOrphanServices(null, id);
manager.remove(sr);
}
/**
* Возвращает список приемов в указанном диапазоне дат для данного клиента
* @param clientID клиент
* @param begin навала диапазона
* @param end конец диапазона
* @return список приемов
* @throws ClipsServerException
* @security нет ограничений
*/
@Override
public List<SheduleReceptionDetails> getClientReceptionList(int clientID, Date begin, Date end)
throws ClipsServerException {
Field f[] = {
new Field("begin", begin, Field.OPERATOR_EQUAL_OR_MORE) ,
new Field("begin", end, Field.OPERATOR_LESS),
new Field("client", findEntity(Client.class, clientID))
};
Collection<SheduleReception> list = findEntityList(SheduleReception.class, f, " ORDER BY a.begin DESC");
List<SheduleReceptionDetails> res = new ArrayList<SheduleReceptionDetails>();
Iterator<SheduleReception> i = list.iterator();
while(i.hasNext()) {
SheduleReception j = i.next();
res.add(j.getDetails((RightChecker) this));
}
return res;
}
}