/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package beans.user.client.updater;
import beans.user.client.facilityClient.FacilityClientDetails;
import framework.beans.SecuredBean;
import framework.beans.security.BeanRights;
import java.util.ArrayList;
import java.util.List;
import framework.generic.ClipsServerException;
import beans.UserRightsSet;
import beans.contract.entity.Contract;
import beans.contract.entity.PolisDetails;
import beans.directory.district.entity.AddressDistrict;
import beans.directory.district.entity.District;
import beans.directory.enterprise.Enterprise;
import beans.directory.simple.entities.Appointment;
import beans.directory.simple.entities.Excemption;
import beans.user.client.ClientBeanRemote;
import beans.doctor.emc.Emc;
import beans.service.ServiceRender;
import beans.user.client.ClientBean;
import beans.user.client.entity.Client;
import beans.user.client.entity.ClientDetails;
import beans.user.client.facilityClient.FacilityClient;
import beans.user.client.facilityClient.FacilityDocument;
import beans.user.client.facilityClient.FacilityDocumentDetails;
import beans.user.job.entity.Job;
import framework.beans.address.DirectoryKladrBean;
import framework.beans.address.DirectoryKladrBeanRemote;
import framework.beans.address.entities.AddressDetails;
import framework.beans.address.entities.AddressObject;
import framework.beans.client.clientDocument.ClientDocumentDetails;
import framework.beans.directory.DirectoryEntity;
import framework.beans.directory.simple.entities.ClientDocumentType;
import framework.beans.directory.simple.entities.Name;
import framework.beans.directory.simple.entities.Patronymic;
import framework.beans.directory.simple.entities.Sex;
import framework.beans.directory.simple.entities.Surname;
import framework.generic.EDataIntegrity;
import framework.utils.DateTimeUtils;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.UUID;
import javax.ejb.Stateful;
import javax.persistence.Query;
/**
*
* @author axe
*/
@Stateful(mappedName="clips-beans/UpdaterClientBean")
public class UpdaterClientBean extends SecuredBean
implements UpdaterClientBeanRemote {
public static final int COMMAND_UPDATE = 0;
private static HashMap<ClientUniq, Integer> mapClient;
private ClientBeanRemote clientBean;
private DirectoryKladrBeanRemote kladrBean;
private Contract contract;
private int counter;
/**
* мап ClientID, EMC
*/
public static HashMap<Integer, Emc> emcMap;
@Override
protected void initBeanRights() throws ClipsServerException {
int[] r = new int[1];
r[COMMAND_UPDATE] = RightPresence(UserRightsSet.WRITE_CLIENT_PUBLIC_INFO.id);
rights = new BeanRights(r);
}
private void init() throws ClipsServerException {
//checkCommandAccessibility(COMMAND_UPDATE);
clientBean = getBean(ClientBean.class);
kladrBean = getBean(DirectoryKladrBean.class);
kladrBean.setSession(getSessionId());
contract = null;
Query q = manager.createQuery("SELECT a FROM Contract a WHERE "
+ "(a.type = :ctype) "
+ "AND (a.begin <= :current) "
+ "AND ((a.end IS NULL) OR (a.end > :current))");
q.setParameter("ctype", Contract.TYPE_OMI);
q.setParameter("current", GregorianCalendar.getInstance().getTime());
@SuppressWarnings("unchecked")
List<Contract> contrList = q.getResultList();
if (contrList.isEmpty()) {
throw new ClipsServerException("Не найден контракт ОМС");
} else {
contract = contrList.get(0);
}
}
@Override
public void update(ClientChunk c) throws ClipsServerException {
if (clientBean == null || contract == null) {
init();
}
if (!c.isValid()) {
throw new EDataIntegrity("Неполные данные пациента");
}
//CLIENT
ClientDetails clientDetails = new ClientDetails();
clientDetails.surnameId = c.famID;
clientDetails.nameId = c.nameID;
clientDetails.pathronId = c.patronID;
clientDetails.sexId = c.sexID;
clientDetails.born = c.dateBorn;
clientDetails.socialStatusId = c.socStatusID;
clientDetails.districtId = c.districtID;
clientDetails.inn = c.inn;
clientDetails.snils = c.snils;
clientDetails.numberEmc = c.numambk;
ClientUniq cu = new ClientUniq(c.famID, c.nameID, c.patronID, c.dateBorn);
Integer clientID = mapClient.get(cu);
Client client = null;
if (clientID != null && clientID != 0) {
client = findEntity(Client.class, clientID);
}
if (client != null) {
ClientDetails d2 = client.getDetails(this);
d2.surnameId = clientDetails.surnameId;
d2.nameId = clientDetails.nameId;
d2.pathronId = clientDetails.pathronId;
d2.sexId = clientDetails.sexId;
d2.born = clientDetails.born;
d2.socialStatusId = clientDetails.socialStatusId;
d2.districtId = c.districtID;
d2.inn = clientDetails.inn;
d2.snils = clientDetails.snils;
d2.numberEmc = c.numambk;
clientDetails = d2;
}
clientBean.initByID(clientDetails.id, getSessionId());
clientDetails.noCheckEmcNum = true;
//TODO yam yam, return modification info to the client
clientDetails.id = clientBean.update(clientDetails).getId();
if(client == null) {
client = manager.find(Client.class, clientDetails.id);
}
//АДРЕС
AddressDetails addDet = new AddressDetails();
String code = c.kladrCode;
Field[] f = new Field[]{new Field("kladrCode", code)};
List<AddressObject> list = findEntityList(AddressObject.class, f);
if (list.isEmpty() && code.length() >= 11) {
//Если не найдена улица, то найдем хотябы нас пункт
code = code.substring(0, 11) + "00000000";
f = new Field[]{new Field("kladrCode", code)};
list = findEntityList(AddressObject.class, f);
}
if (list.isEmpty() && code.length() >= 8) {
//Если не найден поселок в городе, найдем хотябы город
code = code.substring(0, 8) + "00000000000";
f = new Field[]{new Field("kladrCode", code)};
list = findEntityList(AddressObject.class, f);
}
if (list.isEmpty() && code.length() >= 5) {
//Если не найден город найдем хотябы район
code = code.substring(0, 5) + "00000000000000";
f = new Field[]{new Field("kladrCode", code)};
list = findEntityList(AddressObject.class, f);
}
if (!list.isEmpty()) {
AddressObject ao = list.get(0);
addDet.objectId = ao.getId();
if (c.letter.length() > 0
&& c.letter.charAt(0) >= '0'
&& c.letter.charAt(0) <= '9') {
addDet.building = c.house + "/" + c.letter;
} else {
addDet.building = c.house + c.letter;
}
addDet.flat = c.room;
try {
addDet = kladrBean.correctDetails(addDet);
} catch (Exception ex) {
if (ex instanceof ClipsServerException) {
throw (ClipsServerException) ex;
} else {
throw new ClipsServerException("Неизвестная ошибка ", ex);
}
}
clientBean.setAddress(addDet);
} else {
if (!code.isEmpty()) {
throw new ClipsServerException("В КЛАДРе отсутствует нас. пункт с кодом " + code);
}
}
//ДОКУМЕНТ, УДОСТОВЕРЯЮЩИЙ ЛИЧНОСТЬ
ClientDocumentDetails docdet = new ClientDocumentDetails();
docdet.typeID = c.docTypeID;
docdet.series = c.docSeria;
docdet.number = c.docNumber;
clientBean.setClientDocument(docdet);
//ПОЛИС ОМС
if (c.insurOrgID != 0 && c.insurAreaID != 0 && !c.polNumber.isEmpty()) {
PolisDetails polDet = new PolisDetails();
polDet.insurerID = c.insurOrgID;
polDet.regionCodeId = c.insurAreaID;
polDet.series = c.polSeria;
polDet.number = c.polNumber;
polDet.member = true;
polDet.contractID = contract.getId();
polDet.tillDate = null;
polDet.fromDate = null;
polDet.addressDetail = addDet;
//флаг что полис надо перезаписать а не создавать новый
polDet.id = -1;
clientBean.setPolisOMI(polDet);
}
//МЕСТО РАБОТЫ И ДОЛЖНОСТЬ
if (!c.job.isEmpty()) {
Field f1[] = { new Field("client", client) };
List<Job> jobList = findEntityList(Job.class, f1);
Job job = null;
for (Job item : jobList) {
if (item.getEnterprise().getTitle().equals(c.job)) {
job = item;
break;
}
}
if (job == null) {
//Создание новой работы, возможно с созданием нового предприятия
Field f2[] = { new Field("title", c.job) };
List<Enterprise> entList = findEntityList(Enterprise.class, f2);
Enterprise enterprise;
if (entList.size() > 0) {
//хотябы одно предприятие с совпадающим тайтлом
enterprise = entList.get(0);
} else {
enterprise = new Enterprise();
enterprise.setTitle(c.job);
manager.persist(enterprise);
manager.flush();
manager.refresh(enterprise);
enterprise.setTreePath(enterprise.getId() + ".");
manager.persist(enterprise);
}
job = new Job();
job.setClient(client);
job.setEnterprise(enterprise);
job.setBegin(DateTimeUtils.getDateOnly());
manager.persist(job);
manager.flush();
manager.refresh(job);
}
if (c.appointmentID == 0) {
job.setAppointment(null);
} else {
job.setAppointment(findEntity(Appointment.class, c.appointmentID));
}
manager.persist(job);
manager.flush();
}
if (counter % 1000 == 0) {
manager.flush();
manager.clear();
System.gc();
}
/*if ((i%10) == 0) {
System.out.println("Обновление пациентов : " + i/cList.size() + "% (" + i + ") запись");
System.out.println("timeClient " + timeClient);
System.out.println("timeEmc " + timeEmc);
System.out.println("timeAddress " + timeAddress);
System.out.println("timePolis " + timePolis);
}*/
counter ++;
}
private HashSet<String> loadDirectory(Class<? extends DirectoryEntity> clazz) {
HashSet<String> set = new HashSet<String>();
Field f[] = { new Field("id", "", Field.OPERATOR_NOT_NULL) };
List<? extends DirectoryEntity> list = findEntityList(clazz, f);
for (DirectoryEntity directoryEntity: list) {
set.add(directoryEntity.getTitle());
}
return set;
}
@Override
public void updateSurnames(HashSet<String> famList) {
HashSet<String> set = loadDirectory(Surname.class);
for (String fam : famList) {
if (!set.contains(fam)) {
Surname surname = new Surname();
surname.setTitle(fam);
surname.setDirty(false);
manager.persist(surname);
set.add(surname.getTitle());
}
}
}
@Override
public void updateNames(HashSet<String> namList) {
HashSet<String> set = loadDirectory(Name.class);
for (String nam : namList) {
if (!set.contains(nam)) {
Name name = new Name();
name.setTitle(nam);
name.setDirty(false);
manager.persist(name);
set.add(name.getTitle());
}
}
}
@Override
public void updatePatrons(HashSet<String> patronList) {
HashSet<String> set = loadDirectory(Patronymic.class);
for (String tiste : patronList) {
if (!set.contains(tiste)) {
Patronymic patronymic = new Patronymic();
patronymic.setTitle(tiste);
patronymic.setDirty(false);
manager.persist(patronymic);
set.add(patronymic.getTitle());
}
}
}
@Override
public void updateAppointments(HashSet<String> appList) {
HashSet<String> set = loadDirectory(Appointment.class);
for (String title : appList) {
if (!set.contains(title)) {
Appointment entity = new Appointment();
entity.setTitle(title);
entity.setDirty(false);
manager.persist(entity);
set.add(entity.getTitle());
}
}
}
@Override
public void updateDistricts(HashSet<String> districtList) {
HashSet<String> set = loadDirectory(District.class);
for (String title : districtList) {
if (!set.contains(title)) {
District entity = new District();
entity.setTitle(title);
manager.persist(entity);
set.add(entity.getTitle());
}
}
}
/**
* Вызывается для массового апдейта пациентов - для оптимизации скорости
* после завершения апдейта ОБЯЗАТЕЛЬНО вызвать процедуру с параметром false
* @param f
*/
@Override
public void setUseStaticMap(boolean f) {
if (f) {
if (emcMap == null) {
System.out.println("Start Loading EmcList");
emcMap = new HashMap<Integer, Emc>();
String sql = "select e.client.id, e from Emc e";
Query query = manager.createQuery(sql);
System.out.println("End Loading EmcList");
@SuppressWarnings("unchecked")
List<Object[]> list = query.getResultList();
for (Object[] line: list) {
Integer clientID = (Integer) line[0];
Emc emc = (Emc) line[1];
emcMap.put(clientID, emc);
}
System.out.println("End Mapping EmcList");
}
if (mapClient == null) {
System.out.println("Start Loading Clients");
mapClient = new HashMap<ClientUniq, Integer>();
String sql = "select c.id, c.surname, c.name, c.pathronymic, c.born from Client c";
Query query = manager.createQuery(sql);
@SuppressWarnings("unchecked")
List<Object[]> list = query.getResultList();
System.out.println("Start Mapping Clients");
int i = 0;
for (Object[] line: list) {
ClientUniq cu = new ClientUniq();
Integer clientID = (Integer) line[0];
Surname surname = (Surname) line[1];
Name name = (Name) line[2];
Patronymic pathronymic = (Patronymic) line[3];
cu.surnameID = surname == null ? 0 : surname.getId();
cu.nameID = name == null ? 0 : name.getId();
cu.pathronID = pathronymic == null ? 0 : pathronymic.getId();
cu.dateBorn = (Date) line[4];
mapClient.put(cu, clientID);
}
System.out.println("End Mapping Clients");
}
} else {
emcMap = null;
mapClient = null;
}
}
@Override
public void updateFacilityClients(ArrayList<FacilityClientDetails> list,
ArrayList<FacilityDocumentDetails> docList) throws ClipsServerException {
String sql = "DELETE a FROM FacilityClient a";
Query query = manager.createQuery(sql);
query.executeUpdate();
for (int i = 0; i < list.size(); i++) {
FacilityClientDetails d = list.get(i);
FacilityClient entity = new FacilityClient();
entity.setSnils(d.snils);
entity.setPolisSN(d.polisSN);
entity.setSurname(d.surnameId == 0 ? null : findEntity(Surname.class, d.surnameId));
entity.setName(d.nameId == 0 ? null : findEntity(Name.class, d.nameId));
entity.setPathronymic(d.pathronId == 0 ? null : findEntity(Patronymic.class, d.pathronId));
entity.setSex(findEntity(Sex.class, d.sexId));
entity.setBorn(d.bornDate);
entity.setDocumentType(d.docTypeId == 0 ? null : findEntity(ClientDocumentType.class, d.docTypeId));
entity.setDocumentSN(d.docSN);
entity.setAddress(d.address);
entity.setBuilding(d.building);
entity.setCorpus(d.corpus);
entity.setFlat(d.flat);
entity.setOkatoReg(d.okatoReg);
entity.setFlagNSU(d.flagNSU);
entity.setNsuBegin(d.nsuBegin);
entity.setNsuEnd(d.nsuEnd);
entity.setExcemption1(d.exemp1Id == 0 ? null : findEntity(Excemption.class, d.exemp1Id));
entity.setExcemption2(d.exemp2Id == 0 ? null : findEntity(Excemption.class, d.exemp2Id));
entity.setRegBegin(d.regBegin);
entity.setRegEnd(d.regEnd);
entity.setuType(d.uType);
entity.setdType(d.dType);
entity.setcReg(d.c_reg);
saveEntity(entity);
}
sql = "DELETE a FROM FacilityDocument a";
query = manager.createQuery(sql);
query.executeUpdate();
for (int i = 0; i < docList.size(); i++) {
FacilityDocumentDetails d = docList.get(i);
FacilityDocument entity = new FacilityDocument();
entity.setSnils(d.snils);
entity.setExcemption(d.exempId == 0 ? null : findEntity(Excemption.class, d.exempId));
entity.setDocumentName(d.docType);
entity.setDocumentSN(d.docSN);
entity.setGspBegin(d.gspBegin);
entity.setGspEnd(d.gspEnd);
saveEntity(entity);
}
}
@Override
public void setDistricts() throws ClipsServerException {
throwNeedAdminSecurityException("Доступно только суперпользователю");
List<District> districtList = findEntityList(District.class);
int maxLength = 0;
deleteEntityList(AddressDistrict.class, null);
Field[] f = new Field[]{
new Field("kladrCode", "02%", Field.OPERATOR_LIKE),
new Field("type.level", 5, Field.OPERATOR_EQUAL_OR_MORE),
};
List<AddressObject> addressList = findEntityList(AddressObject.class, f);
//Мап потомков
HashMap<AddressObject, HashSet<AddressObject>> childrenMap = new HashMap<AddressObject, HashSet<AddressObject>>();
for (AddressObject addressObject : addressList) {
AddressObject parent = addressObject.getParent();
if (parent != null) {
HashSet<AddressObject> children = childrenMap.get(parent);
if (children == null) {
children = new HashSet<AddressObject>();
childrenMap.put(parent, children);
}
children.add(addressObject);
}
}
//Сет ID записанных улиц для избежания дублирования
HashSet<Integer> streetSet = new HashSet<Integer>();
for (int i = 0; i < addressList.size(); i++) {
if ((i % 100) == 0) {
System.out.println("Выполнено " + i/((float)addressList.size())*100 + "%");
}
AddressObject it = addressList.get(i);
while (it != null) {
if (it.getType().getLevel() == 5) {
break;
}
it = it.getParent();
}
if (it != null && it.getType().getLevel() == 5 && !streetSet.contains(it.getId())) {
streetSet.add(it.getId());
if (maxLength < it.getTitle().length()) {
maxLength = it.getTitle().length();
System.out.println("maxLength=" + maxLength);
System.out.println("title = '" + it.getTitle() + "'");
}
HashSet<AddressObject> children = childrenMap.get(it);
if (children != null && children.size() != 0) {
//создаем несколько записей
for (AddressObject chield : children) {
AddressDistrict addressDistrict = new AddressDistrict();
addressDistrict.setTitle(chield.getTitle());
addressDistrict.setAddressObject(it);
int pos = Math.abs(chield.getTitle().hashCode()) % districtList.size();
addressDistrict.setDistrict(districtList.get(pos));
manager.persist(addressDistrict);
}
} else {
//создаем новую запись
AddressDistrict addressDistrict = new AddressDistrict();
addressDistrict.setTitle("");
addressDistrict.setAddressObject(it);
int pos = Math.abs(it.getTitle().hashCode()) % districtList.size();
addressDistrict.setDistrict(districtList.get(pos));
manager.persist(addressDistrict);
}
}
}
}
@Override
public void generatePhones() throws ClipsServerException {
throwNeedAdminSecurityException("Доступно только суперпользователю");
List<Client> clientList = findEntityList(Client.class);
Random r = new Random();
for (int i = 0; i < clientList.size(); i++) {
Client client = clientList.get(i);
if ((i % 100) == 0) {
System.out.println("Выполнено " + i/((float)clientList.size())*100 + "%");
}
String phone = "";
int n = 1 + r.nextInt(4);
for (int j = 0; j < n; j++) {
phone = phone + getRandomPhone() + ";" + (j<n ? " " : "");
}
client.setTelephones(phone);
manager.merge(client);
}
}
private String getRandomPhone() {
Random r = new Random();
String phone = "2";
phone = phone + Integer.toString(10 + r.nextInt(90));
phone = phone + Integer.toString(10 + r.nextInt(90));
phone = phone + Integer.toString(10 + r.nextInt(90));
return phone;
}
@Override
public void generateAddressCashe() throws ClipsServerException {
throwNeedAdminSecurityException("Доступно только суперпользователю");
System.out.println("Start");
List<Client> clientList = findEntityList(Client.class);
System.out.println("Loaded");
for (Client client : clientList) {
client.setAddress(client.getAddress());
manager.merge(client);
}
System.out.println("Finished");
}
@Override
public void generateUUID() throws ClipsServerException{
throwNeedAdminSecurityException("Доступно только суперпользователю");
System.out.println("Start");
List<ServiceRender> serrenList = findEntityList(ServiceRender.class);
System.out.println("Loaded");
for (ServiceRender serviceRender : serrenList) {
serviceRender.setUuid(UUID.randomUUID().toString());
}
System.out.println("Finished");
}
}