/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package clips.delegate.contract;
import beans.contract.ContractBean;
import cli_fmw.delegate.cache.ExtraDataManager;
import beans.contract.ContractBeanRemote;
import beans.contract.ContractPolisFilter;
import beans.contract.VisitPrice;
import beans.contract.entity.ContractDetails;
import beans.contract.entity.ServicePriceDetails;
import beans.contract.entity.PolisDetails;
import beans.contract.search.ContractPolisChunk;
import cli_fmw.delegate.directory.complex.DirectoryLocator;
import clips.delegate.directory.complex.DirectoryServicesGroupItem;
import clips.delegate.directory.complex.DirectoryPacketTemplate;
import clips.delegate.directory.complex.DirectoryPacketTemplateItem;
import clips.delegate.directory.filtered.DirectoryService;
import clips.delegate.directory.filtered.DirectoryServiceItem;
import cli_fmw.delegate.DelegateLine2;
import cli_fmw.main.ClipsException;
import cli_fmw.delegate.cache.DelegateExtraData;
import cli_fmw.delegate.lists.DataChunkMapList;
import cli_fmw.utils.Selector;
import cli_fmw.utils.SelectorEditable;
import clips.delegate.client.ClientLocal;
import clips.delegate.directory.complex.DirectoryEnterprise;
import clips.delegate.directory.complex.DirectoryEnterpriseItem;
import clips.delegate.directory.simple.receptionType.DirectoryReceptionType;
import clips.delegate.directory.simple.receptionType.DirectoryReceptionTypeItem;
import beans.directory.service.entity.ServiceGroup;
import cli_fmw.delegate.AuditListener;
import clips.delegate.directory.ro.DirectoryLpu;
import clips.delegate.directory.ro.DirectoryLpuItem;
import framework.beans.ModificationInfo;
import framework.generic.ClipsServerException;
import framework.utils.Pair;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Делегат, представляющий доступ к одной строке таблицы Contract (таблица договоров),
* подгружает список клиентов, которые ссылаются на этот договор
* @author ViP
*/
public class ContractLocal extends DelegateLine2<ContractBeanRemote, ContractDetails> {
public static final int SEL_STATUS_ALL = 0; //Статус "Выбраны все" (Для дерева просмотра услуг в договоре)
public static final int SEL_STATUS_SOME = 1; //Статус "Выбраны некоторые"
public static final int SEL_STATUS_NOTHING = 2; //Статус "Не выбрано ничего"
public static final int SEL_STATUS_EMPTY = 3; //Статус "ПУСТОЙ"
private ServiceSpecialityList serviceRecTypeList = new ServiceSpecialityList(getEDM(), 2);
private TemplateInfo templateSet = new TemplateInfo(getEDM(), 3);
public int polisListSize;
// private class PolisList extends DataChunkMapList<PolisData, Integer> {
//
// public PolisList(ExtraDataManager contaner, int priority) {
// super(contaner, priority);
// }
//
//
// @Override
// protected void deleteDB(PolisData details) throws Exception {
// getBean().removePolis(details.getDetails().getId());
// }
//
// @Override
// protected int saveDB(PolisData details) throws Exception {
// return getBean().setPolis(details.getDetails());
// }
//
// @Override
// protected void loadDB() throws Exception {
// boolean superUser = UserInfo.get().isSuperUser();
// for(PolisDetails d : getBean().getPolisList()) {
// if (superUser || !d.trash) {
// initByDetails(new PolisData(ContractLocal.this, null, d));
// }
// }
// }
//
// }
/**
*
*/
private class TemplateInfo extends DelegateExtraData<Set<DirectoryPacketTemplateItem>> {
public TemplateInfo(ExtraDataManager contaner, int priority) {
super(contaner, priority);
}
@Override
protected Set<DirectoryPacketTemplateItem> init() throws Exception {
DirectoryPacketTemplate dir = (DirectoryPacketTemplate)
DirectoryLocator.getDirectory(DirectoryPacketTemplate.class, false);
Iterator<Integer> it = getBean().getPacketTemplates().iterator();
Set<DirectoryPacketTemplateItem> set = new HashSet<DirectoryPacketTemplateItem>();
while (it.hasNext()) {
DirectoryPacketTemplateItem item = dir.getItemFromID(it.next());
set.add(item);
}
return set;
}
@Override
protected void saveDB() throws Exception {
Set<Integer> set = new HashSet<Integer>();
Iterator<DirectoryPacketTemplateItem> it = get().iterator();
while (it.hasNext()) {
set.add(it.next().getID());
}
ModificationInfo mi = getBean().setPacketTemplates(set);
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
}
@Override
protected Set<DirectoryPacketTemplateItem> initNew() {
return null;
}
}
public ContractLocal(AuditListener al) throws ClipsException {
super(al);
}
public ContractLocal(int id, AuditListener al) {
super(id, al);
}
public ContractLocal(ContractDetails details, AuditListener al) {
super(details, al);
}
@Override
protected ContractDetails getNewDetails() {
return new ContractDetails();
}
public void setTemplates(Set<DirectoryPacketTemplateItem> templates) throws ClipsException {
templateSet.set(new HashSet<DirectoryPacketTemplateItem>(templates));
}
public String getIndex() throws ClipsException {
return getDetails().index;
}
public void setIndex(String index) throws ClipsException {
getDetails().index = index;
fireContentStateEvent();
}
public Date getBegin() throws ClipsException {
return getDetails().begin;
}
public void setBegin(Date begin) throws ClipsException {
getDetails().begin = begin;
fireContentStateEvent();
}
public Date getEnd() throws ClipsException {
return getDetails().end;
}
public void setEnd(Date end) throws ClipsException {
getDetails().end = end;
fireContentStateEvent();
}
public short getType() throws ClipsException {
return getDetails().type;
}
public void setType(int newType) throws ClipsException {
getDetails().type = (short)newType;
fireContentStateEvent();
}
public boolean isOpenForAll() throws ClipsException {
return getDetails().openForAll;
}
public void setOpenForAll(boolean openForAll) throws ClipsException {
getDetails().openForAll = openForAll;
fireContentStateEvent();
}
public DirectoryEnterpriseItem getEnterprise() throws ClipsException {
DirectoryEnterprise di = DirectoryLocator.getDirectory(DirectoryEnterprise.class);
return di.getItemFromID(getDetails().enterpriseID);
}
public void setEnterprise(DirectoryEnterpriseItem item) throws ClipsException {
getDetails().enterpriseID = item.getID();
fireContentStateEvent();
}
public DirectoryLpuItem getLpu() throws ClipsException {
if (getDetails().lpuID == 0) {
return null;
}
DirectoryLpu dir = DirectoryLocator.getDirectory(DirectoryLpu.class);
return dir.getItemFromID(getDetails().lpuID);
}
public void setLpu(DirectoryLpuItem item) throws ClipsException {
if (item == null) {
getDetails().lpuID = 0;
} else {
getDetails().lpuID = item.getID();
}
fireContentStateEvent();
}
public List<PolisData> getPolisList(ContractPolisFilter filter) throws ClipsException {
try {
List<PolisData> polises = new ArrayList<PolisData>();
ContractPolisChunk chunk = getBean().getPolisList(filter);
List<PolisDetails> details = new ArrayList<PolisDetails>(chunk.polisList);
polisListSize = chunk.listSize;
for (PolisDetails detail : details) {
polises.add(new PolisData(this, null, detail));
}
return polises;
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при получении полисов договора", ex);
}
}
public boolean isClientNotYetInContract(ClientLocal client) throws ClipsException {
try {
return getBean().isClientNotYetInContract(client.getID());
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при проверке записи о пациенте в договоре", ex);
}
}
public void savePolisData(PolisData polis) throws ClipsException {
try {
ModificationInfo mi = getBean().setPolis(polis.getDetails());
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
int id = mi.getId();
polis.setId(id);
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при записи полиса в договор", ex);
}
}
public void removePolisData(PolisData polis) throws ClipsException {
try {
ModificationInfo mi = getBean().removePolis(polis.getId());
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при удалении полиса из договора", ex);
}
}
/**
* Возвращает цены на услугу
* подгружает цены на услуги из базы.
* @param serviceID услуга для которой возвратить информацию
* @return информация об услуги или NULL
* @throws cli_fmw.delegate.exception.ClipsException
*/
public ServisePriceData getContractService(Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair) throws ClipsException {
//preload
getContractServiceList();
return serviceRecTypeList.get(pair);
}
public void removeService(Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair) throws ClipsException {
ServisePriceData toDel = getContractService(pair);
if (toDel == null) {
return;
}
SelectorEditable<ServisePriceData> list = getContractServiceList();
for (int i = 0; i < list.size(); i++) {
ServisePriceData service = list.get(i);
if (service == toDel) {
list.remove(i);
break;
}
}
//fireContentStateEvent();
}
/**
* услуги и цены, завязанные на данный договор
* @return
* @throws ClipsException
*/
public SelectorEditable<ServisePriceData> getContractServiceList() throws ClipsException {
return serviceRecTypeList.selector();
}
/**
* Шаблоны пакетов услуг, завязанные на данный договор
* @return
* @throws ClipsException
*/
public Set<DirectoryPacketTemplateItem> getTemplates() throws ClipsException {
if (templateSet.get() != null){
return new HashSet<DirectoryPacketTemplateItem>(templateSet.get());
}else{
return new HashSet<DirectoryPacketTemplateItem>();
}
}
/**
* Просматривает рекурсивно всех детей у данной группы услуг и в зависимости
* от договора возвращает статус (выбраны все, некоторые или ниодной)
* @param group
* @return
* @throws ClipsException
*/
public int getSelectedStatus(DirectoryServicesGroupItem group) throws ClipsException {
/*
* Если дети есть, то статус вычисляется рекурсивно по детям
* выход досрочно при статусе НЕКОТОРЫЕ происходит как только
* встречается дите со статусом НЕКОТОРЫЕ либо встречаются дети с
* разным статусом
* Сначала проверяются услуги, затем вложенные группы услуг
*/
int statAll = 0;
int statNo = 0;
Set<Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>> keySet = serviceRecTypeList.getKeySet();
DirectoryService dirService = DirectoryLocator.getDirectory(DirectoryService.class);
DirectoryReceptionType dirRecType = DirectoryLocator.getDirectory(DirectoryReceptionType.class);
Selector<DirectoryServiceItem> it = dirService.getFilteredItems(group);
for (int i = 0; i < it.size(); i++) {
DirectoryServiceItem service = it.get(i);
int founded = 0;
for (Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair : keySet) {
if (pair.first.getID() == service.getID()) {
founded ++;
}
}
if (service.getGroup().getID() != ServiceGroup.SERVICE_GROUP_VISIT) {
//Если услуга не посещение, то достаточно найти одно значение в кейсете
if (founded > 0) {
statAll ++;
} else {
statNo ++;
}
} else {
//Если услуга посещение, то найденные плюсуем к присутствующим
statAll += founded;
//к отсутствующим плюсуем разницу между общим количеством типов приемов, имеющих код и найденными
statNo += (dirRecType.getCountItemsHasCode() - founded);
}
}
if (statAll > 0 && statNo > 0) {
return SEL_STATUS_SOME;
}
for (int i = 0; i < group.getItems().size(); i++) {
DirectoryServicesGroupItem child = group.getItems().get(i);
int status = getSelectedStatus(child);
switch (status) {
case SEL_STATUS_ALL:
statAll++;
break;
case SEL_STATUS_NOTHING:
statNo++;
break;
case SEL_STATUS_SOME:
return SEL_STATUS_SOME;
case SEL_STATUS_EMPTY:
break;
}
if (statAll > 0 && statNo > 0) {
return SEL_STATUS_SOME;
}
}
if (statAll == 0 && statNo == 0) {
return SEL_STATUS_EMPTY;
} else if (statAll > 0) {
return SEL_STATUS_ALL;
} else if (statNo > 0) {
return SEL_STATUS_NOTHING;
} else {
throw new ClipsException("Ошибка алгоритма");
}
}
/**
* пробегает рекурсивно по всем детям данной группы услуг и добавляет все
* услуги в данный договор, либо удаляет услуги из договора (в зависимости
* от параметра status)
* @param status
*/
public void setSelectedStatus(DirectoryServicesGroupItem group, int status) throws ClipsException {
// комменты смотри в процедуре getSelectedStatus
//Пробегаем по услугам, напрямую входящим в данную группу
if (group.getID() == ServiceGroup.SERVICE_GROUP_VISIT) {
//Реальной нужды нет, а писать код и отлаживать не представляется возможным
throw new ClipsException("Операция не применима к посещениям");
}
DirectoryService ds = DirectoryLocator.getDirectory(DirectoryService.class, false);
DirectoryReceptionType recTypeDir = DirectoryLocator.getDirectory(DirectoryReceptionType.class);
Selector<DirectoryServiceItem> it = ds.getFilteredItems(group);
Set<Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>> keySet = serviceRecTypeList.getKeySet();
for (int i = 0; i < it.size(); i++) {
DirectoryServiceItem service = it.get(i);
if (status == SEL_STATUS_ALL) {
//МОЖЕТ услуга уже есть
int founded = 0;
for (Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair : keySet) {
if (pair.first.getID() == service.getID()) {
founded ++;
}
}
if (founded == 0) {
Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair = new Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>();
pair.first = service;
pair.second = recTypeDir.getItemFromID(0);
ServisePriceData spd = new ServisePriceData(pair);
getContractServiceList().append(spd);
}
} else if (status == SEL_STATUS_NOTHING) {
ArrayList<Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>> forDelete = new ArrayList<Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>>();
for (Iterator<Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>> it1 = keySet.iterator(); it1.hasNext();) {
Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair = it1.next();
if (pair.first.getID() == service.getID()) {
forDelete.add(pair);
}
}
for (Pair<DirectoryServiceItem, DirectoryReceptionTypeItem> pair : forDelete) {
removeService(pair);
}
}
}
//пробегаем по группам, входящим в данную группу
for (int i = 0; i < group.getItems().size(); i++) {
DirectoryServicesGroupItem child = group.getItems().get(i);
setSelectedStatus(child, status);
}
}
public ContractLocal copy() throws ClipsException {
try {
ModificationInfo mi = getBean().copy();
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
return new ContractLocal(mi.getId(), getAuditListener());
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при копировании договора", ex);
}
}
/**
* Проверяет введены ли все цены на услуги
* @return
*/
public boolean isContractServicesGood() throws ClipsException {
Selector<ServisePriceData> it = getContractServiceList();
for (int i = 0; i < it.size(); i++) {
ServisePriceData sp = it.get(i);
if (sp.getMoney() < 0 || sp.getPrice() < 0) {
return false;
}
}
return true;
}
public void updateOMIPrice(HashSet<VisitPrice> visitPriceList) throws ClipsException {
try {
ModificationInfo mi = getBean().updateOMIPrice(visitPriceList);
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
} catch (Exception ex) {
clearBean();
throw new ClipsException("Ошибка при обновлении стоимости посещений по ОМС", ex);
}
}
/**
* Формирует краткие сведенья о договоре
* Параметры говорят что отображать
* @param index номер договора
* @param enterprise предприятие
* @param insurer страховщик
* @param timeBegin время начала
* @param timeEnd время окончания
* @return
* @throws cli_fmw.delegate.exception.ClipsException
*/
public String getInfo(boolean index, boolean enterprise, boolean timeBegin, boolean timeEnd, String separator) throws ClipsException {
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
String info = "";
if (index) {
info += getIndex() + separator;
}
if (enterprise) {
if (getEnterprise() != null) {
info += getEnterprise() + separator;
}
}
if (timeBegin) {
if (getBegin() != null) {
info += formatter.format(getBegin());
} else {
info += "---";
}
}
if (timeEnd) {
info += " - ";
if (getEnd() != null) {
info += formatter.format(getEnd());
} else {
info += "---";
}
}
return info;
}
public String getInfo() throws ClipsException {
return getInfo(true, true, true, true, " / ");
}
public String getHTML(boolean index, boolean enterprise, boolean timeBegin, boolean timeEnd) throws ClipsException {
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
String separator = " <br> ";
String info = "<html>";
if (index) {
info += "<i>Номер: </i>" + getIndex() + separator;
}
if (enterprise) {
if (getEnterprise() != null) {
info += "<i>Предприятие: </i>" + getEnterprise() + separator;
}
}
if (timeBegin) {
info += "<i>Время начала: </i>";
if (getBegin() != null) {
info += formatter.format(getBegin());
} else {
info += "---";
}
}
if (timeEnd) {
info += separator + "<p><i>Время окончания: </i>";
if (getEnd() != null) {
info += formatter.format(getEnd());
} else {
info += "---";
}
}
return info + "</html>";
}
public String getHTML() throws ClipsException {
return getHTML(true, true, true, true);
}
public boolean isOpen() throws ClipsException{
Date now = new Date();
if (getBegin() == null){
return false;
}
if (getEnd() == null){
return true;
}
return getBegin().compareTo(now) <= 0 && getEnd().compareTo(now) > 0;
}
@Override
protected String getBeanName() {
return ContractBean.class.getSimpleName();
}
/**
*
*/
private class ServiceSpecialityList extends DataChunkMapList<ServisePriceData, Pair<DirectoryServiceItem, DirectoryReceptionTypeItem>> {
public ServiceSpecialityList(ExtraDataManager contaner, int priority) {
super(contaner, priority);
}
@Override
protected void deleteDB(ServisePriceData data) throws Exception {
ModificationInfo mi = getBean().removeService(data.getDetails().getId());
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
}
@Override
protected int saveDB(ServisePriceData data) throws Exception {
ModificationInfo mi = getBean().setService(data.getDetails());
auditDetailsList.addAll(mi.getAudit());
fireAuditEvent();
return mi.getId();
}
@Override
protected void loadDB() throws Exception {
for(ServicePriceDetails d : getBean().getServices()) {
initByDetails(new ServisePriceData(d));
}
}
}
@Override
public String toString() {
String info = "Договор: ";
try {
info += getInfo();
} catch (ClipsException ex) {
//ну не получилось и хер с ним
info += "информация недоступна";
}
return info;
}
public void unionPolises() throws ClipsException {
try {
getBean().unionPolises();
} catch (ClipsServerException ex) {
throw new ClipsException("Объединение полисов не завершено", ex);
}
}
}