Package beans.service

Source Code of beans.service.ServiceRenderBean

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.service;

import beans.doctor.prescriptiondlo.PrescriptionDloDetails;
import framework.beans.EntityDetails;
import beans.discount.CalcDiscount;
import framework.beans.FacadeBean;
import framework.beans.security.BeanRights;
import beans.doctor.PacketService;
import beans.contract.entity.Polis;
import beans.contract.entity.PolisDetails;
import beans.contract.entity.ServicePrice;
import beans.contract.entity.ServicePriceDetails;
import beans.discount.entity.DiscountCard;
import beans.discount.entity.DiscountCardDetails;
import beans.doctor.checkup.Checkup;
import beans.doctor.checkup.CheckupDetails;
import beans.doctor.contraindication.Contraindication;
import beans.doctor.contraindication.ContraindicationDetails;
import beans.doctor.diagnosis.Diagnosis;
import beans.doctor.diagnosis.DiagnosisDetails;
import beans.doctor.direction.Direction;
import beans.doctor.direction.DirectionDetails;
import beans.doctor.prescription.Prescription;
import beans.doctor.prescription.PrescriptionDetails;
import beans.doctor.recommendation.Recommendation;
import beans.doctor.recommendation.RecommendationDetails;
import beans.expenditure.entity.Expenditure;
import beans.expenditure.entity.ExpenditureDetails;
import beans.directory.expenditure.entity.ExpenditureType;
import beans.directory.service.entity.Service;
import beans.doctor.disease.Disease;
import beans.user.collaborator.entities.Collaborator;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import framework.generic.ESecurity;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.ejb.Stateful;
import javax.persistence.Query;
import beans.UserRightsSet;
import beans.directory.simple.entities.ReceptionType;
import beans.followup.entity.Followup;
import beans.directory.simple.entities.ServicingPlace;
import beans.doctor.prescriptiondlo.PrescriptionDlo;
import beans.service.medexam.MedSerrenResult;
import beans.doctor.sicklist.entity.SickLong;
import beans.doctor.sicklist.entity.Sicklist;
import beans.user.collaborator.entities.CollaboratorFunctions;
import framework.audit.AuditDetails;
import framework.audit.AuditDoc;
import framework.beans.ModificationInfo;
import framework.beans.collaborator.CollaboratorAbstract;
import framework.security.RightChecker;
import framework.utils.DateTimeUtils;
import java.util.LinkedList;
import javax.ejb.EJBException;
import javax.persistence.EntityManager;

/**
* Security - Ok.
* Integriy - may be Ok.
* @author axe
*/
@Stateful(mappedName="clips-beans/ServiceRenderBean")
public class ServiceRenderBean extends FacadeBean<ServiceRender>
    implements ServiceRenderBeanRemote, ServiceRenderBeanLocal {

//    public static final UserRights RIGHT_CREATION = UserRights.WRITE_PUBLIC_DATA;
    public static final int COMMAND_READ_CONTRACT_MEMBER = 4;
    public static final int COMMAND_READ_MEDICAL_DATA = 5;
    public static final int COMMAND_SERVICE_RENDER_TRANSACTION_DETAIL = 6;
    public static final int COMMAND_READ_SERVICE_RENDER_TRANSACTION_SUMM = 7;
   
    public static final String NEED_SPECIFY_RECEPTION_TYPE = "Пользователь не имеет требуемого для оказания услуги типа приема";
    public static final String HAVE_NOT_RECEPTION_TYPE = "Пользователь не имеет требуемого для оказания услуги типа приема";
    public static final String NOT_COMPLIANCE_SPECIALITY = "Специальность врача должна не соответствует оказываемой услуге";


    public ServiceRenderBean() {
        super(ServiceRender.class);
    }

   
    @Override
    protected void initBeanRights() throws ClipsServerException {
        ServiceRender entity = (getId() == 0) ? null : getExistentEntity();
       
        int[] r = new int[8];
        r[COMMAND_READ] = RightPresence(UserRightsSet.READ_SERVICE_RENDER_DATA.id);
        if (isSuperUser()) {
            r[COMMAND_READ] = UserRightsSet.READ_SERVICE_RENDER_DATA.id;
        }
        /* команда создания услуги всегда недоступна - создание услуги
         осуществляется через CreateServiceBean
         */
        r[COMMAND_CREATE] = -UserRightsSet.CREATE_SERVICE_RENDER.id;

        /* команда модификации и удаления
         * Если услуга не в заболевании то команда доступна по праву записи
         * мед. данных либо суперпользователю
         * Если в заболевании то проверка такая же как и для других мед. данных
         * (см. MedicalDataBean)
         */
        if (entity != null) {
            if (entity.getDisease() == null) {
                //не в заболевании
                r[COMMAND_MODIFY] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
                r[COMMAND_REMOVE] = RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id);
                if (isSuperUser()) {
                    r[COMMAND_MODIFY] = UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id;
                    r[COMMAND_REMOVE] = UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id;
                }
            } else {
                //в заболевании
                int modifyRight = 0;
                if (RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id) > 0){
                    //Начинаем проверять со слабого права
                    modifyRight = entity.canWriteDuringDay(
                            isSuperUser(),
                            UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY,
                            getCollaboratorId());
                }
                if (RightPresence(UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME.id) > 0){
                    //Если есть более сильное право, то команда перезаписывается им
                    modifyRight = entity.canWriteAnyTime(
                            isSuperUser(),
                            UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME,
                            findEntity(Collaborator.class, getCollaboratorId()));
                }
                if (isSuperUser() && modifyRight <= 0) {
                    //Если суперюзер, и прав нету или запрет то всеравно разрешаем по самому сильному праву
                    modifyRight = UserRightsSet.WRITE_MEDICAL_DATA_ANY_TIME.id;
                }
                if (modifyRight == 0) {
                    modifyRight = -UserRightsSet.WRITE_MEDICAL_DATA_DURING_DAY.id;
                }
                r[COMMAND_MODIFY] = modifyRight;
                r[COMMAND_REMOVE] = modifyRight;

            }
        }

        /* Set Discount Card is out of there
        int ds =  (entity.getDiscountCard() == null) ?
        RightPresence(UserRights.WRITE_SERVICE_RENDER_DISCOUNT_CARD.id) : 0;
        r[COMMAND_WRITE_SERVICE_RENDER_DISCOUNT_CARD] = ds;
         */
        r[COMMAND_READ_MEDICAL_DATA] = RightPresence(UserRightsSet.READ_MEDICAL_DATA.id);
        r[COMMAND_READ_SERVICE_RENDER_TRANSACTION_SUMM] = RightPresence(UserRightsSet.READ_SERVICE_RENDER_TRANSACTION_SUMM.id);
        r[COMMAND_SERVICE_RENDER_TRANSACTION_DETAIL] = RightPresence(UserRightsSet.READ_SERVICE_RENDER_TRANSACTION_DETAIL.id);
        if (isSuperUser()) {
            r[COMMAND_READ_MEDICAL_DATA] = UserRightsSet.READ_MEDICAL_DATA.id;
            r[COMMAND_READ_SERVICE_RENDER_TRANSACTION_SUMM] = UserRightsSet.READ_SERVICE_RENDER_TRANSACTION_SUMM.id;
            r[COMMAND_SERVICE_RENDER_TRANSACTION_DETAIL] = UserRightsSet.READ_SERVICE_RENDER_TRANSACTION_DETAIL.id;
        }

       
        rights = new BeanRights(r);
    }

    /**
     * Обновляет данные сущности.
   * @param entity
   * @param details новые детали сущности
     * @throws ClipsServerException в случае если обновление отвергнуто системой
     *          безопастности либо произошла ошибка
     *
     * Безопасность: Создание - запрещено, создание делает бин CreateServiceBean
     * Модификация - свободная.
     * Когда выполнена, снять флажёк выполненности можно только по WRITE_ADMIN_SERVICE_RENDER.
     * Поля date, director, polis, service - можно установить только при создании.
     * TODO переписать начисто
     */
    @Override
    protected void onUpdate(ServiceRender entity, EntityDetails details,
            AuditDoc auditDoc, List<AuditDoc> auditDocList)
            throws ClipsServerException {
        checkPossibilityUpdate(entity, details);

        ServiceRenderDetails d = (ServiceRenderDetails) details;

        entity.setDate(d.date);

        CollaboratorFunctions cf = d.functionsID == 0 ? null : findEntity(CollaboratorFunctions.class, d.functionsID);
        //особо заебатые случаи проверки вынесены сюды
        if (!entity.isRendered()) {//услуга не оказана
            //услуга не оказана
            if (d.functionsID != 0
                    && findEntity(CollaboratorFunctions.class, d.functionsID).getCollaborator().getId() != getCollaboratorId()
                    && !hasRight(UserRightsSet.WRITE_STATISTIC_MEDICAL_DATA)) {
                throwNeedAdminSecurityException("У вас недостаточно прав, чтоб оказать услугу от имени другого пользователя");
            }
            if (d.functionsID != 0 && d.servPlaceID == 0) {
                throw new EDataIntegrity("При оказании услуги необходимо указывать место обслуживания");
            }
            if (d.functionsID != 0
                    && !DateTimeUtils.belongsToCurrentDay(d.renderDate)
                    && !hasRight(UserRightsSet.WRITE_STATISTIC_MEDICAL_DATA)) {
                throwNeedAdminSecurityException("У вас недостаточно прав, чтоб оказать услугу другой датой");
            }
            entity.setRenderedDate(d.functionsID == 0 ? null : d.renderDate);

            //Если в услуге указана специальность врача, которым должна быть оказана услуга,
            //то cf должен соответствовать
            if (entity.getSpeciality() != null) {
                if (entity.getSpeciality().getId() != cf.getSpeciality().getId()) {
                    throw new EDataIntegrity();
                }
            }
            entity.setFunctions(cf);
            if (d.functionsID != 0) {
                //при оказании услуги анализ убираем ее из расписания анализов
                Field fields[] = {
                    new Field("serviceRender", entity),
                };       
                List<Checkup> list = findEntityList(Checkup.class, fields);
                for (int i = 0; i < list.size(); i++) {
                    Checkup checkup = list.get(i);
                    checkup.setCheckupShedule(null);
                    manager.merge(checkup);
                }
            }
        }
    else {//услуга оказана
            if (d.renderDate == null && d.functionsID != 0) {//отмена оказания
                throwNeedAdminSecurityException("У вас недостаточно прав, чтоб отметить услугу как неоказанную");
                entity.setRenderedDate(null);
                entity.setFunctions(null);
            } else if (!entity.getRenderedDate().equals(d.renderDate)) {
                throwNeedAdminSecurityException("У вас недостаточно прав для смены даты оказания услуги");
                entity.setRenderedDate(d.renderDate);
            } else if (entity.getFunctions() != null && entity.getFunctions().getId() != d.functionsID) {
                throwNeedAdminSecurityException("У вас недостаточно прав для смены сотрудника, оказавшего услугу");
                entity.setFunctions(d.functionsID == 0 ? null : findEntity(CollaboratorFunctions.class, d.functionsID));
            }
        }

        if (d.uet == 0) {
            throw new ClipsServerException("Не указана условная единица трудоемкости\n" +
                    "(УЕТ = 1 для не стоматологических приемов)");
        }
        if (cf != null) {
            ReceptionType recType = cf.getReceptionType();
            String code = recType.getExtKey();
            if (!code.contains("29") && d.uet != ServiceRender.DEFAULT_UET) {
                throw new ClipsServerException("Для не стоматологического приема указан УЕТ отличный от единицы");
            }
        }
        entity.setUet(d.uet);
        entity.setReceived(d.received);

        entity.setDiscount(d.discount);
        entity.setDiscountCard(d.cardID == 0 ? null : findEntity(DiscountCard.class, d.cardID));
        entity.setCancelled(d.cancelled);
        entity.setRepeat(d.repeat);
        entity.setPacketService(d.packetServiceID == 0 ? null : findEntity(PacketService.class, d.packetServiceID));
        entity.setDisease(d.diseaseID == 0 ? null : findEntity(Disease.class, d.diseaseID));
        entity.setPolis(findEntity(Polis.class, d.polisID));
        entity.setService(findEntity(Service.class, d.serviceID));
        entity.setDirector(findEntity(Collaborator.class, d.directorID));
        entity.setPlace(d.servPlaceID == 0 ? null : findEntity(ServicingPlace.class, d.servPlaceID));
        entity.setFunctions(d.functionsID == 0 ? null : findEntity(CollaboratorFunctions.class, d.functionsID));

        ServiceRender ref = d.referencedID == 0 ? null : findEntity(ServiceRender.class, d.referencedID);
        if(ref != null
                &&ref.getDisease().getId() != entity.getDisease().getId()) {
            throw new EDataIntegrity("Связанные услуги должны быть в одном заболевании");
        }
       
        entity.setReferenced(ref);
    }

    private void checkPossibilityUpdate(ServiceRender entity, EntityDetails details) throws ClipsServerException {
        ServiceRenderDetails d = (ServiceRenderDetails) details;

        boolean isAdmin = rights.getCommandAccessReason(COMMAND_MODIFY) == UserRightsSet.WRITE_ADMIN_SERVICE_RENDER.id;
        // Основные проверки
        if (entity.getId() != 0 &&
            (entity.getDirector().getId() != d.directorID ||
            entity.getPolis().getId() != d.polisID ||
            entity.getService().getId() != d.serviceID || !entity.getDate().equals(d.date)) && !isAdmin) {
            throw new ESecurity("Изменить поля услуги: направивший сотрудник, " +
                "полис, тип услуги и дату направления на услугу, " +
                "можно только при создании новой услуги или администратору");
        }
        // дополнительные
        if (d.getId() != entity.getId()) {
            throw new EDataIntegrity("Внутренняя ошибка: Попытка присвоить сущности ServiceRender другой ID");
        }
        if (!(d.diseaseID == 0 ||
            findEntity(Disease.class, d.diseaseID).getEmc().getClient().getId() ==
            findEntity(Polis.class, d.polisID).getClient().getId())) {
            throw new EDataIntegrity("Внутренняя ошибка: Заболевание и полис связаны с различными пациентами");
        }
  }

    /**
     * Если нет транзакций услуга удаляется если есть отменяется.
     * Перед вызовом обязательно вызывать checkPossibilityRemove();
     * @param manager
     * @param entity
     * @param collab
     * @param auditDocList
     * @throws ClipsServerException
     */
    public static void remove(EntityManager manager, ServiceRender entity,
            CollaboratorAbstract collab, List<AuditDoc> auditDocList) throws ClipsServerException {

        Query q = manager.createQuery("SELECT COUNT(mt) FROM MoneyTransaction mt " +
                "WHERE mt.serviceRender = :serren");
        q.setParameter("serren", entity);
        Long count = (Long) q.getSingleResult();

        if (count == 0) {
            AuditDoc<ServiceRender> auditDoc = new AuditDoc<ServiceRender>(entity, collab);
            manager.remove(entity);
            auditDoc.check(null);
            auditDocList.add(auditDoc);
        } else {
            AuditDoc<ServiceRender> auditDoc = new AuditDoc<ServiceRender>(entity, collab);
            entity.setCancelled(true);
            manager.persist(entity);
            manager.flush();
            manager.refresh(entity);
            auditDoc.check(entity);
            auditDocList.add(auditDoc);
        }

    }
    /**
     * Переписан FacadeBean
     * Делается попытка удалить услугу, если это невозможно, то услуга отменяется
     * @throws ClipsServerException
     * Особенность у СЕРРЕНА - если нет денежный транзакций, то удаляет иначе отменяет
     */
    @Override
    public ModificationInfo remove() throws ClipsServerException {
        try {
            List<AuditDoc> auditDocList = new LinkedList<AuditDoc>();

            checkCommandAccessibility(COMMAND_REMOVE);
            ServiceRender entity = getExistentEntity();
            onRemove(entity, auditDocList);
            remove(manager, entity, getCollaborator(), auditDocList);
            List<AuditDetails> auditInfo = persistAudit(auditDocList);
            return new ModificationInfo(entity.getId(), auditInfo);
        } catch (ClipsServerException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new ClipsServerException("Ошибка удаления", ex);
        }
    }

    public static void breakPacket(EntityManager manager, ServiceRender entity,
            CollaboratorAbstract collab, List<AuditDoc> auditDocList) throws ClipsServerException {
        //Удаление связанных результатов медосмотров
        Query query = manager.createQuery("SELECT m FROM MedSerrenResult m WHERE m.serren=:serren");
        query.setParameter("serren", entity);
        List<MedSerrenResult> medserrenlist = query.getResultList();
        for (int i = 0; i < medserrenlist.size(); i++) {
            MedSerrenResult medSerrenResult = medserrenlist.get(i);
            AuditDoc<MedSerrenResult> auditMSR = new AuditDoc<MedSerrenResult>(medSerrenResult, collab);
            manager.remove(medSerrenResult);
            auditMSR.check(null);
            auditDocList.add(auditMSR);
        }

        PacketService serpac = entity.getPacketService();

        if (serpac != null) {
            //Убирание услуг из пакета
            query = manager.createQuery("SELECT s From ServiceRender s WHERE s.packetService.id = :pacserID ");
            query.setParameter("pacserID", entity.getPacketService().getId());
            List serrenList = query.getResultList();

            for (Object object : serrenList) {
                ServiceRender sr = (ServiceRender)object;
                AuditDoc<ServiceRender> auditSerren = new AuditDoc<ServiceRender>(sr, collab);
                sr.setPacketService(null);
                manager.merge(sr);
                auditSerren.check(sr);
                auditDocList.add(auditSerren);
            }
            AuditDoc<PacketService> auditSerpac = new AuditDoc<PacketService>(serpac, collab);
            manager.remove(serpac);
            auditSerpac.check(null);
            auditDocList.add(auditSerpac);
        }
    }

    /**
     * Удаляет услугу и разрушает пакет, если выставлена значение true
     * обычный метод remove() выкинет исключение при попытке удалить услугу в пакете
     * @throws ClipsServerException
     */
    @Override
    public ModificationInfo removeAndBreakPacket() throws ClipsServerException{
        ArrayList<AuditDetails> auditDetList = new ArrayList<AuditDetails>();

        List<AuditDoc> auditDocList = new ArrayList<AuditDoc>();
        ServiceRender entity = getExistentEntity();
        breakPacket(manager, entity, getCollaborator(), auditDocList);
        auditDetList.addAll(persistAudit(auditDocList));

        ModificationInfo mi = remove();
        auditDetList.addAll(mi.getAudit());
        return new ModificationInfo(0, auditDetList);
    }

    /**
     * Удаляет сущность из базы данных
     * Удалить СервисРендер можно только если к нему не привязаны рецепты, рекоммендации,
     * направления, диагнозы, противопоказания или чекапы-осмотры или чекапы-анализы с
     * установленной датой взятия пробы.
     * Особеннсть для СЕРРЕНА - производится проверка без учёта транзакций
   * @param entity
   * @throws ClipsServerException
   */
    @Override
    public void onRemove(ServiceRender entity, List<AuditDoc> auditDocList) throws ClipsServerException {
        checkPossibilityRemove(entity);
        //Удаление чекапов идет хитрым способом тут надо знать про метаданные
        String sql = "SELECT a FROM Checkup AS a " +
                "WHERE (a.serviceRender=:serren) " +
                "AND (a.date is null ) " +
                "AND a.checkupType.isAnalyse = true";
        Query query = manager.createQuery(sql);
        query.setParameter("serren", entity);
        List<Checkup> toDeleteList = query.getResultList();
        for (Checkup checkup : toDeleteList) {
            AuditDoc<Checkup> auditDoc = new AuditDoc<Checkup>(checkup, getCollaborator());
            auditDoc.addFieldFormat(checkup, "xml", checkup.getCheckupType().getMetadata());
            auditDoc.check(null);
            removeEntity(checkup);
            auditDocList.add(auditDoc);
        }

        deleteEntityList2(Checkup.class, new Field[]{
                new Field("serviceRender", entity),
                new Field("date", null, Field.OPERATOR_IS_NULL),
                new Field("checkupType.isAnalyse", true)
            },
            auditDocList);
        deleteEntityList2(Expenditure.class,
                new Field[]{new Field("serviceRender", entity)},
                auditDocList);
        deleteEntityList2(MedSerrenResult.class,
                new Field[]{new Field("serren", entity)},
                auditDocList);
    }



    @Override
    public void checkPossibilityRemove(ServiceRender entity) throws ClipsServerException {
        int myId = entity.getId();

        if (!isSuperUser() && entity.isRendered()){
            throwNeedAdminSecurityException("Нельзя удалить оказанную услугу");
        }
        if (entity.getPacketService() != null) {
            throw new  EDataIntegrity("Нельзя удалить услугу, состоящую в пакете услуг");
        }
    checkEntityNotRef(Followup.class, "serrenUp", "Нельзя удалить услугу, связанную с постановкой на диспансерный учет");
     checkEntityNotRef(Followup.class, "serrenDown", "Нельзя удалить услугу, связанную со снятием с диспансерного учета");
     checkEntityNotRef(SickLong.class, "serren", "Нельзя удалить услугу, связанную с открытием или продлением больничного листа");
     checkEntityNotRef(Sicklist.class, "serrenClosed", "Нельзя удалить услугу, связанную с закрытием больничного листа");

    String      msg = "Нельзя удалить услугу, если в её рамках существует %2$s";
    checkEntityNotRef(Prescription.class, "serviceRender", msg);
    checkEntityNotRef(Recommendation.class, "serviceRender", msg);
    checkEntityNotRef(Direction.class, "serviceRender", msg);
    checkEntityNotRef(Diagnosis.class, "serviceRender", msg);
    checkEntityNotRef(Contraindication.class, "serviceRender", msg);
    checkEntityNotRef(Prescription.class, "serviceRender", msg);

        int checkup = getEntityCount(Checkup.class, new Field[]{new Field("serviceRender.id", myId),
                new Field("checkupType.isAnalyse", false)
            });
    if (checkup != 0){
      throw new EDataIntegrity("Нельзя удалить услугу, если в её рамках записан осмотр, удалите сначала осмотр");
    }
        int nrAnalyse = getEntityCount(Checkup.class, new Field[]{new Field("serviceRender.id", myId),
                new Field("date", null, Field.OPERATOR_NOT_NULL),
                new Field("checkupType.isAnalyse", true)
            }, "");       
        if (nrAnalyse != 0){
      throw new EDataIntegrity("Нельзя удалить услугу, если в её рамках есть выполненный анализ, удалите сначала анализ");
    }
    checkEntityNotRef(ServiceRender.class, "referenced", "Есть услуги, привязанные к данной, удалите сначала их");
     }

  /**
     * Возвращает информацию о договоре, по которому оказывается данная услуга
   * @return договор
   * @throws ClipsServerException
     */
    @Override
    public PolisDetails getPolis() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_CONTRACT_MEMBER);
        ServiceRender entity = getExistentEntity();
       
        Polis polis = entity.getPolis();
        return polis.getDetails((RightChecker) this);
    }

    /**
     * Возвращает дисконтную карту услугу
   * @return детали дисконтной карты или null если нет дисконтой карты
   * @throws ClipsServerException
     */
    @Override
    public DiscountCardDetails getDiscountCard() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ);
        ServiceRender entity = getExistentEntity();
       
        DiscountCard dc = entity.getDiscountCard();
        if (dc == null) {
            return null;
        }
        return dc.getDetails((RightChecker) this);
    }

    /**
     * Возвращает список расходных материалов
   * @return список расходных материалов
   * @throws ClipsServerException
     */
    @Override
    public List<ExpenditureDetails> getExpenditureList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ);
        ServiceRender entity = getExistentEntity();
       
        List list = findEntityList(Expenditure.class, "serviceRender", entity);
        List<ExpenditureDetails> res = new ArrayList<ExpenditureDetails>();
        Iterator i = list.iterator();
        while (i.hasNext()) {
            Expenditure j = (Expenditure) i.next();
            res.add(j.getDetails((RightChecker) this));
        }
        return res;
    }

    /**
     * Добавляет или обновляет расходные материалы. Если details.id = 0 сущность создается,
     * иначе обновляется существующая с заданным идентификатором.
     * @param details данные
     * @return идентификатор сущности
   * @throws ClipsServerException
   * @throws EJBException в случае если обновление отвергнуто системой
     *          безопастности либо произошла ошибка     *
     */
    @Override
    public ModificationInfo setExpenditure(ExpenditureDetails details) throws ClipsServerException {
        checkCommandAccessibility(COMMAND_MODIFY);
        ServiceRender entity = getExistentEntity();

        Expenditure exp = null;
        if (details.id != 0) {
            exp = findEntity(Expenditure.class, details.id);
            checkTheSame(exp.getServiceRender());
        } else {
            exp = new Expenditure();
            exp.setServiceRender(entity);
        }
        AuditDoc<Expenditure> auditExp = new AuditDoc<Expenditure>(exp, getCollaborator());
        exp.setQuantity(details.quantity);
        exp.setType(findEntity(ExpenditureType.class, details.expenTypeID));
        int id = saveEntity(exp);
        auditExp.check(exp);
        return new ModificationInfo(id, persistAudit(auditExp));
    }

    /**
     * Удаляет расходные материалы.
     * @param id идентификатор
   * @throws ClipsServerException в случае если обновление отвергнуто системой
     *          безопасности либо произошла ошибка     *
     */
    @Override
    public ModificationInfo removeExpenditure(int id) throws ClipsServerException {
        checkCommandAccessibility(COMMAND_MODIFY);
        checkEntityExist();
        Expenditure exp = findEntity(Expenditure.class, id);
        checkTheSame(exp.getServiceRender());
        AuditDoc<Expenditure> auditExp = new AuditDoc<Expenditure>(exp, getCollaborator());
        manager.remove(exp);
        auditExp.check(null);
        return new ModificationInfo(persistAudit(auditExp));
    }

    /**
     * Возвращает список транзакций, отсортированных по дате создания.
   * @return список транзакций
   * @throws ClipsServerException
     */
    @Override
    public List<MoneyTransactionDetails> getMoneyTransactionList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_SERVICE_RENDER_TRANSACTION_DETAIL);
        ServiceRender entity = getExistentEntity();

        List list = findEntityList(MoneyTransaction.class, "serviceRender", entity,
            " ORDER by a.date");
        List<MoneyTransactionDetails> res = new ArrayList<MoneyTransactionDetails>();
        Iterator i = list.iterator();
        while (i.hasNext()) {
            MoneyTransaction j = (MoneyTransaction) i.next();
            res.add(j.getDetails((RightChecker) this));
        }
        return res;
    }

    /**
     * Возвращает сумму транзакций по данной услуге
   * @return сумма транзакций
   * @throws ClipsServerException
     */
    @Override
    public Long getMoneyTransactionSumm() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_SERVICE_RENDER_TRANSACTION_SUMM);
        ServiceRender entity = getExistentEntity();
       
        String sql = "SELECT SUM(mt.money) FROM MoneyTransaction mt WHERE mt.serviceRender=:serren " +
            "AND mt.permitted=true";
        Query query = manager.createQuery(sql);
        query.setParameter("serren", entity);
        Long summ = (Long) query.getSingleResult();
        if (summ != null) {
            return summ;
        } else {
            return new Long(0);
        }
    }

    /**
     * Возвращает скидку, с которой должна быть оказана услуга.
     * Учитывается пакет услуг, дисконтная карта, скидка введенная вручную
   * @return 1-100 !null
   * @throws ClipsServerException
     */
    @Override
    public int getCalculatedDiscount() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ);
        ServiceRender entity = getExistentEntity();

        DiscountCard discountCard = entity.getDiscountCard();
        PacketService packetService = entity.getPacketService();
        if (discountCard != null || packetService != null) {
            //по дисконтной карте или по пакету услуг
            int cardID = discountCard == null ? 0 : discountCard.getId();
            int packetID = packetService == null ? 0 : packetService.getPacketTemplate().getId();
            return CalcDiscount.calculateDiscount(manager, cardID, entity.getService().getId(), packetID);
        } else {
            return entity.getDiscount();
        }
    }

    /**
     * Оплачена ли услуга полностью
   * @return
   * @throws ClipsServerException
     */
    @Override
    public boolean isSerPayed() throws ClipsServerException {
        //checkCommandAccessibility(COMMAND_READ);
        ServiceRender entity = getExistentEntity();

        //если услуга связанная, то цена 0, соответственно она оплачена
        if (entity.getReferenced() != null) {
      return true;
    }

        /* Ищем цены
         * у оказываемой услуги(посещения) берем договор, тип услуги и тип приема
        *  В таблице цен ищем такие записи, у которых такой же контракт, тип услуги
         * и тип приема либо совпадает либо нул
        */
        String sql;
        if (entity.getFunctions() != null) {
            sql = "SELECT a FROM ServicePrice a WHERE " +
                 "a.contract=:contract " +
                 "AND a.service=:service " +
                 "AND (a.receptionType=:receptionType OR a.receptionType IS NULL)";
        } else {
            sql = "SELECT a FROM ServicePrice a WHERE " +
                 "a.contract=:contract " +
                 "AND a.service=:service " +
                 "AND a.receptionType IS NULL";
        }
        Query q = manager.createQuery(sql);
        q.setParameter("contract", entity.getPolis().getContract());
        q.setParameter("service", entity.getService());
        if (entity.getFunctions() != null) {
            q.setParameter("receptionType", entity.getFunctions().getReceptionType());
        }
   
        List<ServicePrice> servicePriceList = q.getResultList();
        if (servicePriceList.size() < 1) {
            throw new ClipsServerException("Не найдены цены на услугу в договоре");
        }
        if (servicePriceList.size() > 1) {
            throw new ClipsServerException("Найдены различные цены на услугу в договоре");
        }
        ServicePrice cs = servicePriceList.get(0);
        ServicePriceDetails details = cs.getDetails((RightChecker) this);
        int price = details.price;
        int money = details.money;
        //Ищем скидку
        int discount = getCalculatedDiscount();
        //сумма транзакций
          long transactionSumm = getMoneyTransactionSumm();
        //финальные вычисления
        int toPay = Math.round((price - money) * (1 - (float) discount / 100));
        return transactionSumm >= toPay;
    }

    /**
     * Возвращает рекоммендации, привязанные к данной услуге
   * @return список деталей рекомендаций
   * @throws ClipsServerException
     */
    @Override
    public List<RecommendationDetails> getRecommendationList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
        return loadChildDetailsList(Recommendation.class, "serviceRender");
    }

    /**
     * Возвращает направления, привязанные к данной услуге
   * @return список деталей направлений
   * @throws ClipsServerException
     */
    @Override
    public List<DirectionDetails> getDirectionList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
    return loadChildDetailsList(Direction.class, "serviceRender");
    }

    /**
     * Возвращает противопоказания, привязанные к данной услуге
   * @return список деталей противопоказаний
   * @throws ClipsServerException
     */
    @Override
    public List<ContraindicationDetails> getContraindicationList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
    return loadChildDetailsList(Contraindication.class, "serviceRender");
    }

    /**
     * Возвращает диагнозы, привязанные к данной услуге
   * @return список деталей направлений
   * @throws ClipsServerException
     */
    @Override
    public List<DiagnosisDetails> getDiagnosisList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
        ServiceRender entity = getExistentEntity();

        List<Diagnosis> list = findEntityList(Diagnosis.class, "serviceRender", entity,
            "AND a.referenced IS NULL");
        return getEntytyDetailsList(list);
    }

  @Override
    public List<PrescriptionDetails> getPrescriptionList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
    return loadChildDetailsList(Prescription.class, "serviceRender");
    }

    @Override
    public List<CheckupDetails> getCheckupList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
        return loadChildDetailsList(Checkup.class, "serviceRender");
    }

    /**
     * Возвращает серрены из того же пакета что и данный
     * @return сет деталей серренов
     * @throws ClipsServerException
     */
    @Override
    public List<ServiceRenderDetails> getPacketSerrenList() throws ClipsServerException {
        ServiceRenderDetails d = (ServiceRenderDetails) getDetails();
        List<ServiceRenderDetails> res = new ArrayList<ServiceRenderDetails>();
        if (d.packetServiceID == 0) {
            return res;
        }
        PacketService ps = findEntity(PacketService.class, d.packetServiceID);
    return loadChildDetailsList(ps, ServiceRender.class, "packetService");
    }

    @Override
    public List<ServiceRenderDetails> getAccomplichedSerrenList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
    return loadChildDetailsList(ServiceRender.class, "referenced");
    }

    @Override
    public String canRenderService() throws ClipsServerException{
        Collaborator collaborator = findEntity(Collaborator.class, getCollaboratorId());
        String sql = "SELECT COUNT(cf) FROM ServicePrice sp, CollaboratorFunctions cf " +
                "WHERE sp.service =:serv " +
                "AND (sp.receptionType = cf.receptionType OR sp.receptionType IS NULL) AND cf.collaborator=:collab ";
        if (!isSuperUser()){
            sql += "AND cf.trash = FALSE";
        }
        Query q = manager.createQuery(sql);
        q.setParameter("collab", collaborator);
        q.setParameter("serv", getExistentEntity().getService());
        long count = (Long) q.getSingleResult();
        if (count == 0){
            return NEED_SPECIFY_RECEPTION_TYPE;
        }
        count = getEntityCount(CollaboratorFunctions.class, new Field[]{new Field("collaborator", collaborator)});
        if (count == 0){
            return HAVE_NOT_RECEPTION_TYPE;
        }
        //проверка соответствия специальности врача
        if (getExistentEntity().getSpeciality() != null) {
            String sql1 = "SELECT COUNT(cf) FROM CollaboratorFunctions cf " +
                    "WHERE (cf.speciality =:fixedSpeciality) AND cf.collaborator=:collab ";
            if (!isSuperUser()){
                sql1 += "AND cf.trash = FALSE";
            }
            Query q1 = manager.createQuery(sql1);
            q1.setParameter("collab", collaborator);
            q1.setParameter("fixedSpeciality", getExistentEntity().getSpeciality());
            long count1 = (Long) q1.getSingleResult();
            if (count1 == 0){
                return NOT_COMPLIANCE_SPECIALITY;
            }
        }
        return null;
    }

    @Override
    public List<PrescriptionDloDetails> getPrescriptionDloList() throws ClipsServerException {
        checkCommandAccessibility(COMMAND_READ_MEDICAL_DATA);
    return loadChildDetailsList(PrescriptionDlo.class, "serviceRender");
    }
}
TOP

Related Classes of beans.service.ServiceRenderBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.