/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.shedule.individual;
import beans.directory.cabinet.entity.Cabinet;
import beans.directory.worktypes.entities.WorkType;
import framework.beans.SecuredBean;
import framework.beans.security.BeanRights;
import beans.user.collaborator.entities.Collaborator;
import framework.generic.ClipsServerException;
import framework.generic.ESecurity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import javax.ejb.EJBException;
import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import framework.security.RightChecker;
import beans.UserRightsSet;
import framework.generic.EDataIntegrity;
/**
* Бин для управления расписанием работ сотрудников
* @security OK
* @author axe
*/
@Stateful(mappedName="clips-beans/SheduleIndividualBean")
public class SheduleIndividualBean extends SecuredBean
implements SheduleIndividualBeanRemote {
public static int COMMAND_MODIFY_PLAN = 0;
public static int COMMAND_MODIFY_REAL = 1;
@Override
protected void initBeanRights() {
int[] r = new int[2];
r[COMMAND_MODIFY_PLAN] = RightPresence(UserRightsSet.MODIFY_SHEDULE_INDIVIDUAL.id);
r[COMMAND_MODIFY_REAL] = RightPresence(UserRightsSet.MODIFY_SHEDULE_INDIVIDUAL_REAL.id);
rights = new BeanRights(r);
}
private void checkRights(Date date) throws ESecurity {
if(isPlanned(date)) {
checkCommandAccessibility(COMMAND_MODIFY_PLAN);
} else {
checkCommandAccessibility(COMMAND_MODIFY_REAL);
}
}
private boolean isPlanned(Date date) {
return date.before(new Date(2008, 0, 1));
}
/**
* Выдает список работ для указанного сотрудника в диапазоне дат
* Выдаются только работы которые НАЧИНАЮТСЯ в этом диапазоне
* @param collaboratorID идентификатор сотрудника
* @param begin начало диапазона дат
* @param end конец диапазона дат
* @return список деталей работ сотрудника
* @security Нет ограничений
*/
@Override
public List<SheduleIndividualWorkDetails> getWorkList(int collaboratorID, Date begin, Date end) throws ClipsServerException {
Field f[] = {
new Field("collaborator", findEntity(Collaborator.class, collaboratorID)),
new Field("timeBegin", begin, Field.OPERATOR_MORE),
new Field("timeBegin", end, Field.OPERATOR_LESS)
};
Collection<SheduleIndividualWork> list = findEntityList(SheduleIndividualWork.class, f);
List<SheduleIndividualWorkDetails> res = new ArrayList<SheduleIndividualWorkDetails>();
Iterator<SheduleIndividualWork> i = list.iterator();
while(i.hasNext()) {
SheduleIndividualWork j = i.next();
res.add(j.getDetails((RightChecker) this));
}
return res;
}
/**
* Добавляет или обновляет работу. Если details.id = 0 сущность создается,
* иначе обновляется существующая с заданным идентификатором. Все работы
* относятся либо к запланированным, либо к исключительным. Работа считается
* запланированной, если начинается до января 2008 года
* @param details данные
* @return идентификатор сущности
* @throws ClipsServerException
* @security Если обновляются плановые работы,
* у вызывающего должно быть право MODIFY_SHEDULE_INDIVIDUAL, иначе требуется
* право MODIFY_SHEDULE_INDIVIDUAL_REAL. Обновляться могут все поля,
* кроме поля сотрудника. Нельзхя переносить между плановыми и внеплановыми записями.
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public int setWork(SheduleIndividualWorkDetails details) throws ClipsServerException {
checkRights(details.begin);
//создание или обновление
if(details.id != 0) {
SheduleIndividualWork entity = findEntity(SheduleIndividualWork.class, details.id);
if(entity.getCollaborator().getId() != details.collID) {
throw new ClipsServerException("Нельзя изменять сотрудника");
}
int one = isPlanned(details.begin) ? 1:0;
int two = isPlanned(entity.getTimeBegin()) ? 1:0;
if(one + two == 1) {
throw new ClipsServerException("Перенос через дату 01.01.2008 запрещен");
}
//если исключительная работа, запретить изменение прошедших работ
if(one == 0) {
checkIsNotInThePast(details.begin);
}
if(two == 0) {
checkIsNotInThePast(entity.getTimeBegin());
}
entity.setTimeBegin(details.begin);
entity.setDuration(details.workDuration);
entity.setServiceDuration(details.defaultServiceDuration);
entity.setWorkType(details.typeID == 0 ? null : findEntity(WorkType.class, details.typeID));
entity.setCabinet(details.cabinetID == 0 ? null : findEntity(Cabinet.class, details.cabinetID));
if (entity.getCabinet() != null && entity.getCabinet().getLpu().getId() != entity.getCollaborator().getLpu().getId()){
throw new EDataIntegrity("Сотрудник и кабинет находятся в разных клиниках");
}
entity.setDescription(details.description);
manager.merge(entity);
return details.id;
} else {
if(!isPlanned(details.begin)) {
checkIsNotInThePast(details.begin);
}
SheduleIndividualWork entity = new SheduleIndividualWork();
entity.setTimeBegin(details.begin);
entity.setDuration(details.workDuration);
entity.setServiceDuration(details.defaultServiceDuration);
entity.setWorkType(details.typeID == 0 ? null : findEntity(WorkType.class, details.typeID));
entity.setCabinet(details.cabinetID == 0 ? null : findEntity(Cabinet.class, details.cabinetID));
entity.setCollaborator(findEntity(Collaborator.class, details.collID));
if (entity.getCabinet() != null && entity.getCabinet().getLpu().getId() != entity.getCollaborator().getLpu().getId()){
throw new EDataIntegrity("Сотрудник и кабинет находятся в разных клиниках");
}
entity.setDescription(details.description);
manager.persist(entity);
manager.flush();
manager.refresh(entity);
return entity.getId();
}
}
/**
* Удаляет работу.
* @param id идентификатор работы
* @throws ClipsServerException
* @security Если обновляются плановые работы, у вызывающего должно быть
* право MODIFY_SHEDULE_INDIVIDUAL, иначе требуется право MODIFY_SHEDULE_INDIVIDUAL_REAL.
* Нельзя удалять исключительные работы за прошедшие дни.
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public void removeWork(int id) throws ClipsServerException {
SheduleIndividualWork entity = findEntity(SheduleIndividualWork.class, id);
//безопастность
checkRights(entity.getTimeBegin());
if(!isPlanned(entity.getTimeBegin())) {
checkIsNotInThePast(entity.getTimeBegin());
}
manager.remove(entity);
}
/**
* Возвращает количество недель в периоде работ сотрдуника
* @param collaborator сотрудник
* @return количество недель 0-3
* @throws generic.ClipsServerException
* @security нет ограничений
*/
@Override
public int getCollaboratorWeekPeriod(int collaborator) throws ClipsServerException {
return findEntity(Collaborator.class, collaborator).getWeekPeriod();
}
/**
* Назначает количество недель в периоде работ сотрдуника
* @param collaborator сотрудник
* @param count количество недель (0-3)
* @throws generic.ClipsServerException
* @security у вызывающего должно быть право MODIFY_SHEDULE_INDIVIDUAL
*/
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Override
public void setCollaboratorWeekPeriod(int collaborator, int count) throws ClipsServerException {
//права
checkCommandAccessibility(COMMAND_MODIFY_PLAN);
//ОДЗ
if(count <0 || count>=4) {
throw new EJBException("Неверное значение периода недели: " + count);
}
//сделаем ченить полезное
Collaborator coll = findEntity(Collaborator.class, collaborator);
coll.setWeekPeriod(count);
manager.merge(coll);
//очистим все работы до конца 2007 года
Calendar cal = GregorianCalendar.getInstance();
cal.set(2007,0, 1, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.DAY_OF_MONTH, (count+1)*7);
Date from = cal.getTime();
cal.set(2008,0, 1, 0, 0, 0);
Date till = cal.getTime();
Field d[] = {
new Field("collaborator", coll),
new Field("timeBegin", from, Field.OPERATOR_EQUAL_OR_MORE),
new Field("timeBegin", till, Field.OPERATOR_LESS)
};
deleteEntityList(SheduleIndividualWork.class, d);
}
}