package org.msh.tb.cases; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Transactional; import org.jboss.seam.faces.FacesMessages; import org.msh.tb.adminunits.AdminUnitGroup; import org.msh.tb.adminunits.CountryLevelInfo; import org.msh.tb.entities.AdministrativeUnit; import org.msh.tb.entities.UserWorkspace; import org.msh.tb.entities.Workspace; import org.msh.tb.entities.enums.CaseClassification; import org.msh.tb.entities.enums.DiagnosisType; import org.msh.tb.entities.enums.UserView; import org.msh.tb.login.UserSession; import org.msh.utils.EntityQuery; import org.msh.utils.ItemSelectHelper; import javax.persistence.EntityManager; import javax.persistence.Query; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; @Name("healthUnitsQuery") public class HealthUnitsQuery extends EntityQuery { private static final long serialVersionUID = -1091248707546402475L; @In protected EntityManager entityManager; @In(create=true) Workspace defaultWorkspace; @In(create=true) UserSession userSession; @In(create=true) protected UserWorkspace userWorkspace; @In(create=true) CaseFilters caseFilters; @In(create=true) FacesMessages facesMessages; @In (create=true) CountryLevelInfo countryLevelInfo; private List resultList; private List> adminUnits; private List adminsLevel1; private final String SECOND_LEVEL_ADMINUNIT_SQL = ", (select name1 from administrativeunit a2 where a2.code like substring(a.code,1,6) and a2.workspace_id = a.workspace_id and length(a2.code) > 5 limit 1) as secLevelAUname "; /* (non-Javadoc) * @see org.jboss.seam.framework.EntityQuery#createQuery() */ @Override protected Query createQuery() { String casecond = generateSQLConditionByCase(); Integer hsID = null; if (userWorkspace.getHealthSystem() != null) hsID = userWorkspace.getHealthSystem().getId(); String sql = "select u.id, u.name1, a.code, " + "(select count(*) from tbcase c where c.notification_unit_id = u.id and c.state <= 2 " + casecond + ") numcases, " + "(select count(*) from tbcase c " + "where c.state=1 and c.owner_unit_id = u.id " + casecond + ") as ontreat, " + "(select count(*) from treatmenthealthunit t inner join tbcase c on c.id = t.case_id " + "where t.inidate > c.initreatmentdate and t.enddate = c.endtreatmentdate and c.state=1 " + "and t.transferring=false and t.unit_id = u.id" + casecond + ") as transferin, " + "(select count(*) from treatmenthealthunit t inner join tbcase c on c.id = t.case_id " + "where t.enddate < c.endtreatmentdate and c.state in (1,2) and t.unit_id = u.id" + casecond + ") as transferout, " + "(select count(*) from tbcase c " + "where c.state=0 and c.owner_unit_id = u.id " + casecond + ") as notontreat " + (countryLevelInfo.getLevelsWorspace().isHasLevel2() ? SECOND_LEVEL_ADMINUNIT_SQL : "") + "from tbunit u inner join administrativeunit a on a.id = u.adminunit_id " + "where u.treatmentHealthUnit = true and u.workspace_id = " + defaultWorkspace.getId().toString() + generateSQLConditionByUserView() + (hsID != null? " and u.healthsystem_id = " + hsID: "") + " group by u.id, u.name1, a.code order by a.code, " + (countryLevelInfo.getLevelsWorspace().isHasLevel2() ? "secLevelAUname, " : "") + "u.name1"; Query query = entityManager.createNativeQuery(sql); if ( getFirstResult()!=null) query.setFirstResult( getFirstResult() ); if ( getMaxResults()!=null) query.setMaxResults( getMaxResults()+1 ); //add one, so we can tell if there is another page return query; } /** * Generate SQL condition by user view * @return SQL condition to be used in a WHERE clause */ public String generateSQLConditionByUserView() { if (userWorkspace.getView() == null) return ""; String cond; switch (userWorkspace.getView()) { case ADMINUNIT: String code = userWorkspace.getAdminUnit().getCode(); cond = " and (a.code like '" + code + "%')"; break; case TBUNIT: cond = " and u.id = " + userWorkspace.getTbunit().getId(); break; default: cond = ""; } return cond; } /** * Generate SQL condition to filter cases * @return SQL condition to be used in a where clause */ protected String generateSQLConditionByCase() { //Classifications selected List classifs = caseFilters.getClassifications().getSelectedItems(); String caseCondition = ""; String clasSel = ""; String diagTypesSel = ""; if (classifs.size() == 0) return ""; else{ for (CaseClassification cla: classifs) { if (!clasSel.isEmpty()) clasSel += ", "; clasSel += cla.ordinal(); } } //diagnosis types selected List diagTypes = caseFilters.getDiagnosisTypes().getSelectedItems(); if (diagTypes.size() == 0) return ""; else{ for (DiagnosisType dt: diagTypes) { if (!diagTypesSel.isEmpty()) diagTypesSel += ", "; diagTypesSel += dt.ordinal(); } } if(!clasSel.isEmpty()) caseCondition = " and (c.classification in (" + clasSel + "))"; if(!diagTypesSel.isEmpty()) caseCondition = caseCondition + " and (c.diagnosisType in (" + diagTypesSel + "))"; return caseCondition; } @Override public String getCountEjbql() { return "select count(*) from tbunit u where u.workspace.id = #{defaultWorkspace.id}"; } @Override public String getEjbql() { // just to avoid "validate" exception return "from tbunit u where u.workspace.id = #{defaultWorkspace.id}"; } @Override public List getResultList() { if (resultList == null) { resultList = createResultList(); } return resultList; } @Override public Integer getMaxResults() { return null; } /** * Create the result to be exposed by the component * @return */ public List createResultList() { javax.persistence.Query query = createQuery(); List lst = query==null ? null : query.getResultList(); return fillResultList(lst); } /** * Create the result list from the resultset of the query * @param lst * @return */ protected List fillResultList(List lst) { List res = new ArrayList(); for (Object[] vals: lst) { HealthUnitInfo info = new HealthUnitInfo(); info.setUnitId((Integer)vals[0]); info.setUnitName((String)vals[1]); info.setAdminUnitCode((String)vals[2]); info.setCasesNotifs(readLongValue(vals[3])); info.setCasesOnTreatment(readLongValue(vals[4])); info.setCasesTransferIn(readLongValue(vals[5])); info.setCasesTransferOut(readLongValue(vals[6])); info.setCasesNotOnTreatment(readLongValue(vals[7])); if (countryLevelInfo.getLevelsWorspace().isHasLevel2()) { info.setSecondAdminUnitLevel((String)vals[8]); } res.add(info); } return res; } protected Long readLongValue(Object val) { if (val == null) return null; Long longval = ((BigInteger)val).longValue(); if (longval == 0) return null; else return longval; } @Override @Transactional public boolean isNextExists() { boolean b = (resultList!=null) && (resultList.size() > getMaxResults()); return b; } @Override public void refresh() { resultList = null; super.refresh(); } public String checkDiagnosticClassificationFilters(){ boolean showMessage = false; List c = ItemSelectHelper.getSelectedItems(caseFilters.getClassifications(), true); if(c == null || c.size() == 0){ caseFilters.setClassifications(null); showMessage = true; } List d = ItemSelectHelper.getSelectedItems(caseFilters.getDiagnosisTypes(), true); if(d == null || d.size() == 0){ caseFilters.setDiagnosisTypes(null); showMessage = true; } if(showMessage) return "reload-message"; else return null; } protected void createAdminUnits() { adminUnits = new ArrayList>(); for (HealthUnitInfo info: getResultList()) { AdminUnitGroup adminUnitGroup = findAdminUnitGroup(info.getAdminUnitCode()); adminUnitGroup.getItems().add(info); if(adminUnitGroup.getCasesOnTreatment() == null) adminUnitGroup.setCasesOnTreatment(new Long(0)); if(info.getCasesOnTreatment() != null) adminUnitGroup.setCasesOnTreatment(adminUnitGroup.getCasesOnTreatment() + info.getCasesOnTreatment()); } Collections.sort(adminUnits, new Comparator>() { @Override public int compare(AdminUnitGroup o1, AdminUnitGroup o2) { return o1.getAdminUnit().getName().getName1().compareToIgnoreCase(o2.getAdminUnit().getName().getName1()); } }); } protected AdminUnitGroup findAdminUnitGroup(String adminUnitCode) { for (AdminUnitGroup adm: adminUnits) { if (adm.getAdminUnit().isSameOrChildCode(adminUnitCode)) { return adm; } } AdminUnitGroup adm = new AdminUnitGroup(); AdministrativeUnit aux = findAdminUnitByCode(adminUnitCode); if (aux == null) throw new RuntimeException("Admin unit parent of code " + adminUnitCode + " not found"); adm.setAdminUnit( aux ); adminUnits.add(adm); return adm; } /** * Search for an administrative level 1 unit by its code or a code of a child * @param code * @return */ private AdministrativeUnit findAdminUnitByCode(String code) { // if user just "see" an administrative unit, just return it if (userWorkspace.getView() == UserView.ADMINUNIT) return userWorkspace.getAdminUnit(); // get list of administrative units of first level if (adminsLevel1 == null) adminsLevel1 = caseFilters.getAuselection().getOptionsLevel1(); for (AdministrativeUnit adm: adminsLevel1) { if (adm.isSameOrChildCode(code)) { return adm; } } return null; } /** * @return the adminUnits */ public List> getAdminUnits() { if (adminUnits == null) createAdminUnits(); return adminUnits; } }