Index: forgon-core/src/main/java/com/forgon/security/service/UserManagerImpl.java =================================================================== diff -u -r36766 -r37663 --- forgon-core/src/main/java/com/forgon/security/service/UserManagerImpl.java (.../UserManagerImpl.java) (revision 36766) +++ forgon-core/src/main/java/com/forgon/security/service/UserManagerImpl.java (.../UserManagerImpl.java) (revision 37663) @@ -61,6 +61,7 @@ import com.forgon.tools.GB2WB; import com.forgon.tools.SpringBeanManger; import com.forgon.tools.SqlBuilder; +import com.forgon.tools.StrutsParamUtils; import com.forgon.tools.crypto.coder.CoderEncryption; import com.forgon.tools.db.DatabaseUtil; import com.forgon.tools.hibernate.BasePoManagerImpl; @@ -1049,4 +1050,16 @@ } return userIdAndNameMap; } + @Override + public Set findUsersOfTousseOperationDepart(String orgUnitNams) { + StringBuffer sbf = new StringBuffer(); + sbf.append("select s.fullName from "+ OrgUserRelation.class.getSimpleName() + + " our join " + + OrgUnit.class.getSimpleName() + +" ou on ou.id=our.orgUnitId " + + "join SS_USERS s on s.id=our.userId where exists (select 1 from SupplyRoomConfig sc where sc.SUPPLYROOMTYPE=6 and ou.orgUnitCoding=sc.orgUnitCoding) " + + SqlUtils.getInStringListSql("ou.name", SqlUtils.splitStringToSet(orgUnitNams, ",")) + + " order by our.userOrder ASC"); + return objectDao.getStringSet(sbf.toString(), "", true); + } } Index: ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/util/OperationTousseOperationRepartHelper.java =================================================================== diff -u --- ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/util/OperationTousseOperationRepartHelper.java (revision 0) +++ ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/util/OperationTousseOperationRepartHelper.java (revision 37663) @@ -0,0 +1,1014 @@ +package com.forgon.disinfectsystem.jasperreports.util; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.forgon.Constants; +import com.forgon.databaseadapter.service.DateQueryAdapter; +import com.forgon.directory.acegi.tools.AcegiHelper; +import com.forgon.directory.model.BarcodeDevice; +import com.forgon.directory.vo.LoginUserData; +import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; +import com.forgon.disinfectsystem.entity.basedatamanager.position.TousseOperation; +import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseDefinition; +import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseInstance; +import com.forgon.disinfectsystem.entity.basedatamanager.warehouse.StorageLocation; +import com.forgon.disinfectsystem.entity.basedatamanager.warehouse.StorageRecord; +import com.forgon.disinfectsystem.entity.invoicemanager.Invoice; +import com.forgon.disinfectsystem.entity.useRecord.UseRecord; +import com.forgon.disinfectsystem.jasperreports.javabeansource.TousseOperationDetailVo; +import com.forgon.disinfectsystem.jasperreports.javabeansource.TousseOperationSumVo; +import com.forgon.disinfectsystem.jasperreports.javabeansource.TousseOperationUserVo; +import com.forgon.disinfectsystem.jasperreports.service.dataindex.DataIndex; +import com.forgon.disinfectsystem.reportforms.vo.ReportQueryParams; +import com.forgon.security.service.UserManager; +import com.forgon.tools.MathTools; +import com.forgon.tools.date.DateTools; +import com.forgon.tools.db.DatabaseUtil; +import com.forgon.tools.hibernate.ObjectDao; +import com.forgon.tools.util.SqlUtils; + +import edu.emory.mathcs.backport.java.util.Arrays; + +/** + * 手术器械闭环信息追溯报表 + */ +@Component +public class OperationTousseOperationRepartHelper { + @Autowired + private DateQueryAdapter dateQueryAdapter; + @Autowired + private ObjectDao objectDao; + @Autowired + private DataIndex dataIndex; + @Autowired + private SupplyRoomConfigManager supplyRoomConfigManager; + @Autowired + private UserManager userManager; + /** + * 获取工作量及收入统计报表数据 + * @param requestParameters 请求参数 + * @param parametMap 报表参数 + * @return + */ + public List getWorkloadAndIncomeStatisticsReportData(Map requestParameters, Map parametMap){ + String queryMode = requestParameters.get("queryMode");//查询模式 + String startDateStr = requestParameters.get("startDateStr"); + String endDateStr = requestParameters.get("endDateStr"); + String betweenSql = String.format(" between %s and %s ", dateQueryAdapter.dateAdapter(startDateStr),dateQueryAdapter.dateAdapter(endDateStr)); + if("明细查询".equals(queryMode)){ + String barcode = requestParameters.get("barcode"); + String tousseName = requestParameters.get("tousseName"); + String used = requestParameters.get("used");//是否已使用 + String noOperationRecord = requestParameters.get("noOperationRecord");// 领出后无后续操作 + return queryDetail(betweenSql, barcode, tousseName, used, noOperationRecord); + }else if("汇总查询".equals(queryMode)){ + String tousseOperationDepart = requestParameters.get("tousseOperationDepart");//流转科室 + return querySum(betweenSql, tousseOperationDepart); + }else if("人员失误查询".equals(queryMode)){ + String tousseOperationDepart = requestParameters.get("tousseOperationDepart");//流转科室 + String useNames = requestParameters.get("userNames");//人员 + return queryUser(betweenSql, tousseOperationDepart, useNames); + } + return null; + } + /** + * 科室器械包流转汇总查询报表 + * @param betweenSql 时间过滤 + * @param tousseOperationDepart 流转科室 + * @param useNames 用户名 + * @return + */ + private List queryUser(String betweenSql, String tousseOperationDepart, String useNames){ + Map userMap = new HashMap(); + Set useNameSet = null; + if(StringUtils.isBlank(useNames) && StringUtils.isNotBlank(tousseOperationDepart)){ + useNameSet = userManager.findUsersOfTousseOperationDepart(tousseOperationDepart); + }else{ + useNameSet = SqlUtils.splitStringToSet(useNames, ","); + } + setStorageRecordAmountOfUser(betweenSql, useNameSet, userMap); + setOutStorageRecordAmountOfUser(betweenSql, useNameSet, userMap); + setUseAmountOfUser(betweenSql, useNameSet, userMap); + setSecondaryStorageAmountOfUser(betweenSql, useNameSet, userMap); + setOutboundErrorOfUser(betweenSql, useNameSet, userMap); + setTimeoutErrorOfUser(betweenSql, useNameSet, userMap); + return Arrays.asList(userMap.values().toArray()); + } + + /** + * 超时无操作包数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setTimeoutErrorOfUser(String betweenSql, Set useNameSet , Map userMap){ + String todaySql = dateQueryAdapter.getTodayAdapter(); + String storageRecordSql = "select t.operator,count(*) amount from " + + TousseOperation.class.getSimpleName() + + " t join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=t.tousseInstanceId where " + + " exists (select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice_id and i.sendTime " + + betweenSql + + "union all select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice2_id and i.sendTime " + + betweenSql + + " )" + + SqlUtils.getInStringListSql("t.operator", useNameSet) + + " and (t.nextOperationTime > t.nextOperationLimitTime " + + "or (t.nextOperationTime is null and t.nextOperationLimitTime < " + + todaySql + +")) " + + " group by t.operator "; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setTimeoutError(MathTools.add(vo.getTimeoutError(), rs.getInt("amount")).intValue()); + userMap.put(operator, vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + + } + /** + * 出库失误包数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setOutboundErrorOfUser(String betweenSql, Set useNameSet, Map userMap){ + String storageRecordSql = "select ur.operator,count(*) amount from " + + UseRecord.class.getSimpleName() + + " ur join " + + TousseInstance.class.getSimpleName() + + " ti on ti.useRecord_id=ur.id where " + + " exists (select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice_id and i.sendTime " + + betweenSql + + "union all select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice2_id and i.sendTime " + + betweenSql + + " )" + + SqlUtils.getInStringListSql("ur.operator", useNameSet) + + " and exists (select 1 from " + + StorageRecord.class.getSimpleName() + + " si where si.tousseInstanceId=ti.id and si.status='存入' and not exists (select 1 from " + + StorageRecord.class.getSimpleName() + + " sii where sii.tousseInstanceId=si.tousseInstanceId and si.status='取出' and sii.time>si.time )) group by ur.operator "; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setOutboundError(MathTools.add(vo.getOutboundError(), rs.getInt("amount")).intValue()); + userMap.put(operator, vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 二次入库包数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setSecondaryStorageAmountOfUser(String betweenSql, Set useNameSet, Map userMap){ + String storageRecordSql = "select sr.operator,count(*) amount from " + + StorageRecord.class.getSimpleName() + + " sr where sr.status='取出' " + + " and exists (select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + "union all " + + "select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice2_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + ") " + + "and exists (select 1 from StorageRecord si where si.tousseInstanceId=sr.tousseInstanceId and si.status='存入' and si.time>sr.time ) " + + SqlUtils.getInStringListSql("sr.operator", useNameSet) + + " group by sr.operator "; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setSecondaryStorageAmount(MathTools.add(vo.getSecondaryStorageAmount(), rs.getInt("amount")).intValue()); + userMap.put(operator, vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 使用记录录入包数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setUseAmountOfUser(String betweenSql, Set useNameSet, Map userMap){ + String storageRecordSql = "select ur.operator,count(*) amount from " + + TousseInstance.class.getSimpleName() + + " ti join " + + UseRecord.class.getSimpleName() + +" ur on ur.id=ti.useRecord_id where " + + " exists (select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice_id and i.sendTime " + + betweenSql + + "union all select 1 from " + + Invoice.class.getSimpleName() + +" i where i.id=ti.invoice2_id and i.sendTime " + + betweenSql + + " )" + + SqlUtils.getInStringListSql("ur.operator", useNameSet) + + " group by ur.operator"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setUseAmount(MathTools.add(vo.getUseAmount(), rs.getInt("amount")).intValue()); + userMap.put(operator, vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 出库数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setOutStorageRecordAmountOfUser(String betweenSql, Set useNameSet, Map userMap){ + String storageRecordSql = "select sr.operator,count(*) amount from " + + StorageRecord.class.getSimpleName() + + " sr where sr.status='取出' " + + " and exists (select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + "union all " + + "select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice2_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + ") " + + SqlUtils.getInStringListSql("sr.operator", useNameSet) + + " group by sr.operator"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setOutStorageRecordAmount(MathTools.add(vo.getOutStorageRecordAmount(), rs.getInt("amount")).intValue()); + userMap.put(operator, vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 入库数 + * @param betweenSql 时间 + * @param useNameSet 用户 + * @param userMap 用户数据map + */ + private void setStorageRecordAmountOfUser(String betweenSql , Set useNameSet, Map userMap){ + String storageRecordSql = "select sr.operator,count(*) amount from " + + StorageRecord.class.getSimpleName() + + " sr where sr.status='存入' and exists (" + + "select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + "union all " + + "select 1 from " + + TousseInstance.class.getSimpleName() + +" ti join Invoice i on i.id=ti.invoice2_id " + + "where sr.tousseInstanceId=ti.id and i.sendTime " + + betweenSql + + ") " + + SqlUtils.getInStringListSql("sr.operator", useNameSet) + + " group by sr.operator"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String operator = rs.getString("operator"); + if(StringUtils.isBlank(operator)){ + operator = ""; + } + TousseOperationUserVo vo = null; + if(userMap.containsKey(operator)){ + vo = userMap.get(operator); + }else{ + vo = new TousseOperationUserVo(); + vo.setUserName(operator); + userMap.put(operator, vo); + } + vo.setStorageRecordAmount(MathTools.add(vo.getStorageRecordAmount(), rs.getInt("amount")).intValue()); + + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 科室器械包流转汇总查询报表 + * @param betweenSql 时间过滤 + * @param tousseOperationDepart 流转科室 + * @return + */ + private List querySum(String betweenSql, String tousseOperationDepart){ + //判断当前登录用户是否为匿名用户.如果为匿名用户则只查询一级供应室的数据,否则根据实际情况的条件查询 + LoginUserData user = AcegiHelper.getLoginUser(); + String orgUnitCoding = user.getOrgUnitCodingFromSupplyRoomConfig(); + Map tousseOperationSumVoMap = new HashMap(); + setInvocieAmount(betweenSql, orgUnitCoding, tousseOperationDepart, tousseOperationSumVoMap); + if(MapUtils.isEmpty(tousseOperationSumVoMap)){ + return new ArrayList(); + } + String conditionalFiltering = " and i.orgUnitCoding='"+ orgUnitCoding +"'"; + if(StringUtils.isNotBlank(tousseOperationDepart)){ + conditionalFiltering += SqlUtils.getInStringListSql("i.depart", SqlUtils.splitStringToSet(tousseOperationDepart, ",")); + } + setStorageRecordAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setOutStorageRecordAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setUseAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setSecondaryStorageAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setUsedAndNoOutStorageAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setNoOperationRecordAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + setInvoicedNoInStorageAmount(betweenSql, conditionalFiltering, tousseOperationSumVoMap); + return calcTousseOperationSumVo(tousseOperationSumVoMap); + } + /** + * 查询发货包数 + * @param betweenSql 时间过滤 + * @param orgUnitCoding 供应室 + * @param tousseOperationDepart 流转科室 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setInvocieAmount(String betweenSql, String orgUnitCoding, String tousseOperationDepart, Map tousseOperationSumVoMap){ + ReportQueryParams params = new ReportQueryParams(objectDao); + params.betweenSql = betweenSql; + params.querySupplyRoom = orgUnitCoding; + params.includeDisposableGoods = false; + params.extraGroupBy = "i.depart"; + params.isGroup = true; + params.extraSelectColumns = ",i.depart"; + if(StringUtils.isNotBlank(tousseOperationDepart)){ + params.extraWhereSql = SqlUtils.getInStringListSql("i.depart", SqlUtils.splitStringToSet(tousseOperationDepart, ",")); + } + String sql = String.format("select sum(tl.amount) amount,depart from (" + +dataIndex.getWorkAmountByPackageSQL("发货数量", params) + + ") tl group by depart "); + + ResultSet rs = null; + try { + rs = objectDao.executeSql(sql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setInvocieAmount(MathTools.add(vo.getInvocieAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中有登记使用记录的器械包数 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setUseAmount(String betweenSql, String conditionalFiltering, Map tousseOperationSumVoMap){ + String useSql = "select depart,count(distinct id) amount from (select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(useSql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setUseAmount(MathTools.add(vo.getUseAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中有出库记录的器械包数 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setOutStorageRecordAmount(String betweenSql, String conditionalFiltering, Map tousseOperationSumVoMap){ + String outStorageRecordSql = "select depart,count(distinct id) amount from (select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where sr.status='取出' and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where sr.status='取出' and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(outStorageRecordSql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setOutStorageRecordAmount(MathTools.add(vo.getOutStorageRecordAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中有入库记录的器械包数 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setStorageRecordAmount(String betweenSql, String conditionalFiltering, Map tousseOperationSumVoMap){ + String storageRecordSql = "select depart,count(distinct id) amount from (select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where sr.status='存入' and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where sr.status='存入' and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(storageRecordSql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setStorageRecordAmount(MathTools.add(vo.getStorageRecordAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 计算汇总数据 + * @param tousseOperationSumVoMap 汇总vo的Map + * @return + */ + private List calcTousseOperationSumVo(Map tousseOperationSumVoMap){ + if(MapUtils.isEmpty(tousseOperationSumVoMap)){ + return new ArrayList(); + } + DecimalFormat df = new DecimalFormat("0.0000"); + df.applyPattern("0.00"); + for (Entry entry : tousseOperationSumVoMap.entrySet()) { + String depart = entry.getKey(); + TousseOperationSumVo vo = entry.getValue(); + vo.setDepart(depart); + if(MathTools.equals(vo.getInvocieAmount(), 0)){ + vo.setInventoryRate("-"); + }else{ + vo.setInventoryRate(df.format(100.00 * vo.getStorageRecordAmount() / vo.getInvocieAmount()) + "%"); + } + if(MathTools.equals(vo.getStorageRecordAmount(), 0)){ + vo.setDeliveryRate("-"); + }else{ + vo.setDeliveryRate(df.format(100.00 * vo.getInvocieAmount() / vo.getStorageRecordAmount()) + "%"); + } + if(MathTools.equals(vo.getOutStorageRecordAmount(), 0)){ + vo.setUsedRate("-"); + }else{ + vo.setUsedRate(df.format(100.00 * vo.getUseAmount() / vo.getOutStorageRecordAmount()) + "%"); + } + if(MathTools.equals(vo.getOutStorageRecordAmount(), 0)){ + vo.setReturnStorageRate("-"); + }else{ + vo.setReturnStorageRate(df.format(100.00 * vo.getSecondaryStorageAmount() / vo.getOutStorageRecordAmount()) + "%"); + } + } + return Arrays.asList(tousseOperationSumVoMap.values().toArray()); + } + /** + * 获取指定日期发货中的二次入库包总数 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setSecondaryStorageAmount(String betweenSql, String conditionalFiltering , Map tousseOperationSumVoMap){ + String useSql = "select depart,count(distinct srid) - 1 amount from (select i.depart,ti.id,sr.id srid from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id,sr.id srid from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where i.sendTime " + + betweenSql + + conditionalFiltering + + ") t " + + " where exists (select 1 from " + + StorageRecord.class.getSimpleName() + +" sr where sr.status='存入' and sr.tousseInstanceId=t.id group by sr.tousseInstanceId having count(*)>1) " + + "group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(useSql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setSecondaryStorageAmount(MathTools.add(vo.getSecondaryStorageAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中 漏录出库包总数 登记了使用记录,但是没有人工操作的出库记录器械包,以包为单位; + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setUsedAndNoOutStorageAmount(String betweenSql, String conditionalFiltering, Map tousseOperationSumVoMap){ + String sql = "select depart,count(distinct id) amount from (select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t where not exists (select 1 from " + + StorageRecord.class.getSimpleName() + +" sr where sr.tousseInstanceId=t.id and sr.operateDetail='手动取出')" + + " group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(sql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setUsedAndNoOutStorageAmount(MathTools.add(vo.getUsedAndNoOutStorageAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中 漏入库包总数 发货后没有入库记录的器械包 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setInvoicedNoInStorageAmount(String betweenSql,String conditionalFiltering, Map tousseOperationSumVoMap){ + String sql = "select depart,count(distinct id) amount from (select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + TousseInstance.class.getSimpleName() + +" ti join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where ti.useRecord_id is not null and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t where not exists (select 1 from " + + StorageRecord.class.getSimpleName() + +" sr where sr.tousseInstanceId=t.id and sr.status='存入')" + + " group by depart"; + ResultSet rs = null; + try { + rs = objectDao.executeSql(sql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setInvoicedNoInStorageAmount(MathTools.add(vo.getInvoicedNoInStorageAmount(), rs.getInt("amount")).intValue()); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 获取指定日期发货中 领出后无操作记录包总数 指定时间段内器械包领出之后,超出指定时限后,一直没有操作的器械包总数量 + * @param betweenSql 时间过滤 + * @param conditionalFiltering 额外的条件过滤 + * @param tousseOperationSumVoMap 汇总vo的map + */ + private void setNoOperationRecordAmount(String betweenSql, String conditionalFiltering, Map tousseOperationSumVoMap){ + String conditionSql = " (lastManualOpe.nextOperationTime > lastManualOpe.nextOperationLimitTime " + + "or (lastManualOpe.nextOperationTime is null and lastManualOpe.nextOperationLimitTime < " + + dateQueryAdapter.getTodayAdapter() +")) " + + " and lastManualOpe.storageRecordId is null "; + String useSql = "select depart,count(distinct id) amount " + + " from (select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice_id where invoice2_id is null and ti.status in ('已发货','已签收') and i.sendTime " + + betweenSql + + conditionalFiltering + + " union all select i.depart,ti.id from " + + StorageRecord.class.getSimpleName() + + " sr join " + + TousseInstance.class.getSimpleName() + +" ti on ti.id=sr.tousseInstanceId join " + + Invoice.class.getSimpleName() + +" i on i.id=ti.invoice2_id where ti.status in ('已发货','已签收') and i.sendTime " + + betweenSql + + conditionalFiltering + + ") t1 " + + " join (select t.tousseInstanceId,t.nextOperationTime,t.nextOperationLimitTime,t.storageRecordId from " + + TousseOperation.class.getSimpleName() +" t where t.id =(select max(tn.id) id from " + + TousseOperation.class.getSimpleName() +" tn where " + + "tn.operationType='"+ TousseOperation.OPERATION_TYPE_MANUAL + +"' and tn.tousseInstanceId=t.tousseInstanceId)) lastManualOpe on lastManualOpe.tousseInstanceId=t1.id where " + + conditionSql + + " group by depart "; + ResultSet rs = null; + try { + rs = objectDao.executeSql(useSql); + while (rs.next()) { + String depart = rs.getString("depart"); + if(StringUtils.isBlank(depart)){ + depart = ""; + } + TousseOperationSumVo vo = null; + if(tousseOperationSumVoMap.containsKey(depart)){ + vo = tousseOperationSumVoMap.get(depart); + }else{ + vo = new TousseOperationSumVo(); + tousseOperationSumVoMap.put(depart, vo); + } + vo.setNoOperationRecordAmount(MathTools.add(vo.getNoOperationRecordAmount(), rs.getInt("amount")).intValue()); + + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + } + /** + * 器械包流转明细查询报表 + * @param startDateStr 开始时间 + * @param endDateStr 结束时间 + * @param barcode 包条码 + * @param tousseName 包名称 + * @param used 是否已使用 + * @param noOperationRecord 领出后无后续操作 + * @return + */ + private List queryDetail(String betweenSql, String barcode + , String tousseName, String used, String noOperationRecord){ + StringBuffer sbf = new StringBuffer(); + List vos = new ArrayList(); + StringBuffer conditionSql = new StringBuffer(); + conditionSql.append("i.sendTime"); + conditionSql.append(betweenSql); + if(StringUtils.isNotBlank(barcode)){ + conditionSql.append(" and bd.barcode='"); + conditionSql.append(barcode).append("' "); + } + if(StringUtils.isNotBlank(tousseName)){ + conditionSql.append(SqlUtils.getInStringListSql("td.name", SqlUtils.splitStringToSet(tousseName, ","))); + } + if(Constants.STR_YES.equals(used)){ + conditionSql.append(" and ti.useRecord_id is not null "); + }else if(Constants.STR_NO.equals(used)){ + conditionSql.append(" and ti.useRecord_id is null "); + } + String todaySql = dateQueryAdapter.getTodayAdapter(); + if(Constants.STR_YES.equals(noOperationRecord)){//异常=是 + conditionSql.append(" and (lastManualOpe.nextOperationTime > lastManualOpe.nextOperationLimitTime " + + "or (lastManualOpe.nextOperationTime is null and lastManualOpe.nextOperationLimitTime < "+ todaySql +")) " + + "and ti.status in ('已发货','已签收') and lastManualOpe.storageRecordId is null "); + }else if(Constants.STR_NO.equals(noOperationRecord)){//正常=否 + conditionSql.append(" and (lastManualOpe.nextOperationLimitTime is null " + + "or lastManualOpe.nextOperationTime <= lastManualOpe.nextOperationLimitTime " + + "or lastManualOpe.nextOperationLimitTime > " + todaySql + " " + + "or ti.status not in ('" + TousseInstance.STATUS_SHIPPED + "','" + TousseInstance.STATUS_SIGNED + "') " + + "or lastManualOpe.storageRecordId is not null) "); + } + sbf.append("select bd.barcode,ti.signedUser,ti.signedDate,td.name,i.sendTime,i.sender" + + ",lastIntoSto.time lastIntoStoTime,lastIntoSto.operator lastIntoStoOperator,ti.lastStorageLocationId" + + ",lastInvoiceOpe.operator lastInvoiceOpeOperator " + + ",lastInvoiceOpe.operationTime lastInvoiceOpeOperationTime,ur.enteringDate,ur.operator useRecordOperator " + + ",(select count(*) from " + + TousseOperation.class.getSimpleName() + +" t where t.tousseInstanceId=ti.id and t.operation in('回退','发货')) tousseOperationAmount " + + ",case when (lastManualOpe.nextOperationTime > lastManualOpe.nextOperationLimitTime " + + "or (lastManualOpe.nextOperationTime is null and lastManualOpe.nextOperationLimitTime < "+ todaySql +")) " + + "and ti.status in ('" + TousseInstance.STATUS_SHIPPED + "','" + TousseInstance.STATUS_SIGNED + "') " + + "and lastManualOpe.storageRecordId is null then '异常' else '正常' end status " + + ",(select max(s.wareHouseName) from " + + StorageLocation.class.getSimpleName() + +" s join Storage_TousseInstance st on st.storageLocationId=s.id and st.tousseInstanceId=ti.id ) wareHouseName " + + "from "+ TousseInstance.class.getSimpleName() + +" ti join " + + TousseDefinition.class.getSimpleName() + +" td on td.id=ti.TousseDefinition_id join " + + BarcodeDevice.class.getSimpleName() + +" bd on bd.id=ti.id left join " + + UseRecord.class.getSimpleName() +" ur on ur.id=ti.useRecord_id left join " + + Invoice.class.getSimpleName() +" i on i.id =ti.invoice_id left join (select sr.tousseInstanceId,sr.time,sr.operator from " + + StorageRecord.class.getSimpleName() + +" sr where sr.id =(select max(sri.id) from " + + StorageRecord.class.getSimpleName() + +" sri where sri.status='存入')) lastIntoSto on lastIntoSto.tousseInstanceId=ti.id " + + "left join (select t.id,t.tousseInstanceId,t.operator,t.operationTime from " + + TousseOperation.class.getSimpleName() + +" t where id =(select max(id) from " + + TousseOperation.class.getSimpleName() + + " where operation='发货')) lastInvoiceOpe on lastInvoiceOpe.tousseInstanceId=ti.id " + + " left join (select t.tousseInstanceId,t.nextOperationTime,t.nextOperationLimitTime,t.storageRecordId from " + + TousseOperation.class.getSimpleName() +" t where t.id =(select max(tn.id) id from " + + TousseOperation.class.getSimpleName() +" tn where " + + "tn.operationType='"+ TousseOperation.OPERATION_TYPE_MANUAL + +"' and tn.tousseInstanceId=t.tousseInstanceId)) lastManualOpe on lastManualOpe.tousseInstanceId=ti.id where " + + conditionSql + + " order by i.sendTime desc;"); + ResultSet rs = null; + try { + rs = objectDao.executeSql(sbf.toString()); + DateFormat df = DateTools.YMDHMFORMAT.get(); + while (rs.next()) { + TousseOperationDetailVo vo = new TousseOperationDetailVo(); + vo.setBarcode(rs.getString("barcode")); + vo.setTousseName(rs.getString("name")); + vo.setLastIntoStoOperator(rs.getString("lastIntoStoOperator")); + Date lastIntoStoTime = rs.getTimestamp("lastIntoStoTime"); + if(lastIntoStoTime != null){ + vo.setLastIntoStoTime(df.format(lastIntoStoTime)); + } + + Date lastInvoiceOpeOperationTime = rs.getTimestamp("lastInvoiceOpeOperationTime"); + if(lastInvoiceOpeOperationTime != null){ + vo.setLastInvoiceOpeOperationTime(df.format(lastInvoiceOpeOperationTime)); + } + vo.setLastInvoiceOpeOperator(rs.getString("lastInvoiceOpeOperator")); + String status = rs.getString("status"); + if("异常".equals(status)){ + vo.setNoOperationRecord(Constants.STR_YES); + }else{ + vo.setNoOperationRecord(Constants.STR_NO); + } + vo.setTousseOperationAmount(rs.getInt("tousseOperationAmount")); + vo.setSender(rs.getString("sender")); + Date sendTime = rs.getTimestamp("sendTime"); + if(sendTime != null){ + vo.setSendTime(df.format(sendTime)); + } + Date signedDate = rs.getTimestamp("signedDate"); + if(signedDate != null){ + vo.setSignedDate(df.format(signedDate)); + } + vo.setSignedUser(rs.getString("signedUser")); + Date enteringDate = rs.getTimestamp("enteringDate"); + if(enteringDate != null){ + vo.setUseRecordEnteringDate(df.format(enteringDate)); + } + vo.setUseRecordOperator(rs.getString("useRecordOperator")); + if(StringUtils.isNotBlank(vo.getUseRecordEnteringDate())){ + vo.setUsed(Constants.STR_YES); + }else{ + vo.setUsed(Constants.STR_NO); + } + vos.add(vo); + } + } catch (SQLException e) { + e.printStackTrace(); + }finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + return vos; + } +} Index: ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationUserVo.java =================================================================== diff -u --- ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationUserVo.java (revision 0) +++ ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationUserVo.java (revision 37663) @@ -0,0 +1,80 @@ +package com.forgon.disinfectsystem.jasperreports.javabeansource; +/** + * 人员失误查询报表 + * @author zc.li + * + */ +public class TousseOperationUserVo { + /** + * 用户名称 + */ + private String userName; + /** + * 入库数 指定时间内,由该用户登记的入库器械包的数量; + */ + private Integer storageRecordAmount = 0; + /** + * 出库数 指定时间内,由该用户登记的入库器械包的数量; + */ + private Integer outStorageRecordAmount = 0; + /** + * 使用记录录入包数 指定时间内,当前用户登记到使用记录中的器械包数量,以包为单位; + */ + private Integer useAmount = 0; + /** + * 二次入库包数 该器械包最后一条流转记录的操作人为当前用户,且该器械包出库后被再次入库,以包为单位; + */ + private Integer secondaryStorageAmount = 0; + /** + * 出库失误包数 + */ + private Integer outboundError = 0; + /** + * 超时无操作包数 + */ + private Integer timeoutError = 0; + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + public Integer getStorageRecordAmount() { + return storageRecordAmount; + } + public void setStorageRecordAmount(Integer storageRecordAmount) { + this.storageRecordAmount = storageRecordAmount; + } + public Integer getOutStorageRecordAmount() { + return outStorageRecordAmount; + } + public void setOutStorageRecordAmount(Integer outStorageRecordAmount) { + this.outStorageRecordAmount = outStorageRecordAmount; + } + public Integer getUseAmount() { + return useAmount; + } + public void setUseAmount(Integer useAmount) { + this.useAmount = useAmount; + } + public Integer getSecondaryStorageAmount() { + return secondaryStorageAmount; + } + public void setSecondaryStorageAmount(Integer secondaryStorageAmount) { + this.secondaryStorageAmount = secondaryStorageAmount; + } + public Integer getOutboundError() { + return outboundError; + } + public void setOutboundError(Integer outboundError) { + this.outboundError = outboundError; + } + public Integer getTimeoutError() { + return timeoutError; + } + public void setTimeoutError(Integer timeoutError) { + this.timeoutError = timeoutError; + } + + +} Index: forgon-core/src/main/java/com/forgon/security/service/UserManager.java =================================================================== diff -u -r36766 -r37663 --- forgon-core/src/main/java/com/forgon/security/service/UserManager.java (.../UserManager.java) (revision 36766) +++ forgon-core/src/main/java/com/forgon/security/service/UserManager.java (.../UserManager.java) (revision 37663) @@ -184,4 +184,10 @@ * @return */ public Map getUserIdAndNameMapByIds(Set userIdSet); + /** + * 获取流转科室的用户 + * @param orgUnitNams 流转科室名称 + * @return + */ + public Set findUsersOfTousseOperationDepart(String orgUnitNams); } Index: ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationSumVo.java =================================================================== diff -u --- ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationSumVo.java (revision 0) +++ ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationSumVo.java (revision 37663) @@ -0,0 +1,141 @@ +package com.forgon.disinfectsystem.jasperreports.javabeansource; +/** + * 科室器械包流转汇总查询报表 + * @author zc.li + * + */ +public class TousseOperationSumVo { + /** + * 部门 + */ + private String depart; + /** + * 发货包数 + */ + private Integer invocieAmount = 0; + /** + * 有入库记录的器械包数 + */ + private Integer storageRecordAmount = 0; + /** + * 入库率 = (有入库记录的器械包数/发货包数)X 100% + */ + private String inventoryRate; + /** + * 出库率 = (被领出器械包数/有入库记录的器械包数)X 100% + */ + private String deliveryRate; + /** + * 有出库记录的器械包数 + */ + private Integer outStorageRecordAmount = 0; + /** + * 登记使用记录的器械包数 + */ + private Integer useAmount = 0; + /** + * 使用率 = (登记使用记录的器械包数/有出库记录的器械包数)X 100% + */ + private String usedRate; + /** + * 二次入库包总数 统计指定时间段内,出库后被再次入库的器械包总数,以包为单位 ;n-1; 一个包入库10次为值为9 + */ + private Integer secondaryStorageAmount = 0; + /** + * 漏录出库包总数 登记了使用记录,但是没有人工操作的出库记录器械包,以包为单位; + */ + private Integer usedAndNoOutStorageAmount = 0; + /** + * 退库率 = (二次入库的器械包数/有出库记录的器械包数)X 100% + */ + private String returnStorageRate; + /** + * 领出后无操作记录包总数 指定时间段内器械包领出之后,超出指定时限后,一直没有操作的器械包总数量 + */ + private Integer noOperationRecordAmount = 0; + /** + * 漏入库包总数 发货后没有入库记录的器械包 + * @return + */ + private Integer invoicedNoInStorageAmount = 0; + public String getDepart() { + return depart; + } + public void setDepart(String depart) { + this.depart = depart; + } + public Integer getInvocieAmount() { + return invocieAmount; + } + public void setInvocieAmount(Integer invocieAmount) { + this.invocieAmount = invocieAmount; + } + public Integer getStorageRecordAmount() { + return storageRecordAmount; + } + public void setStorageRecordAmount(Integer storageRecordAmount) { + this.storageRecordAmount = storageRecordAmount; + } + public String getInventoryRate() { + return inventoryRate; + } + public void setInventoryRate(String inventoryRate) { + this.inventoryRate = inventoryRate; + } + public String getDeliveryRate() { + return deliveryRate; + } + public void setDeliveryRate(String deliveryRate) { + this.deliveryRate = deliveryRate; + } + public Integer getOutStorageRecordAmount() { + return outStorageRecordAmount; + } + public void setOutStorageRecordAmount(Integer outStorageRecordAmount) { + this.outStorageRecordAmount = outStorageRecordAmount; + } + public Integer getUseAmount() { + return useAmount; + } + public void setUseAmount(Integer useAmount) { + this.useAmount = useAmount; + } + public Integer getSecondaryStorageAmount() { + return secondaryStorageAmount; + } + public void setSecondaryStorageAmount(Integer secondaryStorageAmount) { + this.secondaryStorageAmount = secondaryStorageAmount; + } + + public Integer getUsedAndNoOutStorageAmount() { + return usedAndNoOutStorageAmount; + } + public void setUsedAndNoOutStorageAmount(Integer usedAndNoOutStorageAmount) { + this.usedAndNoOutStorageAmount = usedAndNoOutStorageAmount; + } + public Integer getNoOperationRecordAmount() { + return noOperationRecordAmount; + } + public void setNoOperationRecordAmount(Integer noOperationRecordAmount) { + this.noOperationRecordAmount = noOperationRecordAmount; + } + public String getUsedRate() { + return usedRate; + } + public void setUsedRate(String usedRate) { + this.usedRate = usedRate; + } + public String getReturnStorageRate() { + return returnStorageRate; + } + public void setReturnStorageRate(String returnStorageRate) { + this.returnStorageRate = returnStorageRate; + } + public Integer getInvoicedNoInStorageAmount() { + return invoicedNoInStorageAmount; + } + public void setInvoicedNoInStorageAmount(Integer invoicedNoInStorageAmount) { + this.invoicedNoInStorageAmount = invoicedNoInStorageAmount; + } + +} Index: ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/action/JasperreportsAction.java =================================================================== diff -u -r37618 -r37663 --- ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/action/JasperreportsAction.java (.../JasperreportsAction.java) (revision 37618) +++ ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/action/JasperreportsAction.java (.../JasperreportsAction.java) (revision 37663) @@ -106,6 +106,7 @@ import com.forgon.disinfectsystem.jasperreports.util.InstrumentRepairReportHelper; import com.forgon.disinfectsystem.jasperreports.util.LineGraphReportOfWorkloadByTimePeriodHelper; import com.forgon.disinfectsystem.jasperreports.util.MonthReportHelper; +import com.forgon.disinfectsystem.jasperreports.util.OperationTousseOperationRepartHelper; import com.forgon.disinfectsystem.jasperreports.util.TousseTournoverDaysStatisticsReportHelper; import com.forgon.disinfectsystem.jasperreports.util.UrgentNeedGoodsProcessingCycleHelper; import com.forgon.disinfectsystem.jasperreports.util.WorkloadAndIncomeStatisticsReportHelper; @@ -177,7 +178,11 @@ private BorrowingReportReportHelper borrowingReportReportHelper; - + private OperationTousseOperationRepartHelper operationTousseOperationRepartHelper; + public void setOperationTousseOperationRepartHelper( + OperationTousseOperationRepartHelper operationTousseOperationRepartHelper) { + this.operationTousseOperationRepartHelper = operationTousseOperationRepartHelper; + } private YearWorkloadReportHelper yearWorkloadReportHelper; public void setYearWorkloadReportHelper( @@ -1591,6 +1596,8 @@ }else{ return yearWorkloadReportHelper.getWorkloadAndIncomeStatisticsReportData(requestParameters,year, month, departCoding, isAddEndoscopic, isStatisticDisposableGoodsSendAmount, parametMap); } + } else if (reportName.equals("tousseOperationDetailReport")) { + return operationTousseOperationRepartHelper.getWorkloadAndIncomeStatisticsReportData(requestParameters, parametMap); } else if (reportName.equals("statisticalWorkload")) { String startTime = StrutsParamUtils.getPraramValue("startTime", ""); String endTime = StrutsParamUtils.getPraramValue("endTime", ""); Index: ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationDetailVo.java =================================================================== diff -u --- ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationDetailVo.java (revision 0) +++ ssts-reports/src/main/java/com/forgon/disinfectsystem/jasperreports/javabeansource/TousseOperationDetailVo.java (revision 37663) @@ -0,0 +1,187 @@ +package com.forgon.disinfectsystem.jasperreports.javabeansource; + +import org.apache.commons.lang.StringUtils; +/** + * 器械包流转明细查询报表bean + * @author zc.li + * + */ +public class TousseOperationDetailVo { + /** + * 条码 + */ + private String barcode; + /** + * 包名 + */ + private String tousseName; + /** + * 库存状态 + */ + private String storageStatus; + /** + * 库位名称 + */ + private String wareHouseName; + /** + * 发货时间 + */ + private String sendTime; + /** + * 发货人 + */ + private String sender; + /** + * 签收人 + */ + private String signedUser; + /** + * 签收时间 + */ + private String signedDate; + /** + * 最后入库时间 + */ + private String lastIntoStoTime; + /** + * 最后入库操作人 + */ + private String lastIntoStoOperator; + /** + * 最后领出时间 (发货时间) + */ + private String lastInvoiceOpeOperationTime; + /** + * 最后领出人(发货人) + */ + private String lastInvoiceOpeOperator; + /** + * 是否已使用 + */ + private String used; + /** + * 使用记录登记的时间 + */ + private String useRecordEnteringDate; + /** + * 使用记录登记人 + */ + private String useRecordOperator; + /** + * 出库后流转次数 + */ + private Integer tousseOperationAmount; + /** + * 是否领出后无操作记录 + */ + private String noOperationRecord; + public String getBarcode() { + return barcode; + } + public void setBarcode(String barcode) { + this.barcode = barcode; + } + public String getTousseName() { + return tousseName; + } + public void setTousseName(String tousseName) { + this.tousseName = tousseName; + } + public String getWareHouseName() { + return wareHouseName; + } + + public String getStorageStatus() { + return storageStatus; + } + public void setStorageStatus(String storageStatus) { + this.storageStatus = storageStatus; + } + public void setWareHouseName(String wareHouseName) { + if(StringUtils.isNotBlank(wareHouseName)){ + this.storageStatus="在库"; + }else{ + this.storageStatus="出库"; + } + this.wareHouseName = wareHouseName; + } + public String getSendTime() { + return sendTime; + } + public void setSendTime(String sendTime) { + this.sendTime = sendTime; + } + public String getSender() { + return sender; + } + public void setSender(String sender) { + this.sender = sender; + } + public String getSignedUser() { + return signedUser; + } + public void setSignedUser(String signedUser) { + this.signedUser = signedUser; + } + public String getSignedDate() { + return signedDate; + } + public void setSignedDate(String signedDate) { + this.signedDate = signedDate; + } + public String getLastIntoStoTime() { + return lastIntoStoTime; + } + public void setLastIntoStoTime(String lastIntoStoTime) { + this.lastIntoStoTime = lastIntoStoTime; + } + public String getLastIntoStoOperator() { + return lastIntoStoOperator; + } + public void setLastIntoStoOperator(String lastIntoStoOperator) { + this.lastIntoStoOperator = lastIntoStoOperator; + } + public String getLastInvoiceOpeOperationTime() { + return lastInvoiceOpeOperationTime; + } + public void setLastInvoiceOpeOperationTime(String lastInvoiceOpeOperationTime) { + this.lastInvoiceOpeOperationTime = lastInvoiceOpeOperationTime; + } + public String getLastInvoiceOpeOperator() { + return lastInvoiceOpeOperator; + } + public void setLastInvoiceOpeOperator(String lastInvoiceOpeOperator) { + this.lastInvoiceOpeOperator = lastInvoiceOpeOperator; + } + public String getUsed() { + return used; + } + public void setUsed(String used) { + this.used = used; + } + public String getUseRecordEnteringDate() { + return useRecordEnteringDate; + } + public void setUseRecordEnteringDate(String useRecordEnteringDate) { + this.useRecordEnteringDate = useRecordEnteringDate; + } + public String getUseRecordOperator() { + return useRecordOperator; + } + public void setUseRecordOperator(String useRecordOperator) { + this.useRecordOperator = useRecordOperator; + } + public Integer getTousseOperationAmount() { + return tousseOperationAmount; + } + public void setTousseOperationAmount(Integer tousseOperationAmount) { + this.tousseOperationAmount = tousseOperationAmount; + } + public String getNoOperationRecord() { + return noOperationRecord; + } + public void setNoOperationRecord(String noOperationRecord) { + this.noOperationRecord = noOperationRecord; + } + +} Index: forgon-core/src/main/java/com/forgon/security/action/UserAction.java =================================================================== diff -u -r36352 -r37663 --- forgon-core/src/main/java/com/forgon/security/action/UserAction.java (.../UserAction.java) (revision 36352) +++ forgon-core/src/main/java/com/forgon/security/action/UserAction.java (.../UserAction.java) (revision 37663) @@ -1,11 +1,16 @@ package com.forgon.security.action; +import java.util.List; +import java.util.Map; +import java.util.Set; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONArray; import net.sf.json.JSONObject; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts2.convention.annotation.Action; @@ -208,4 +213,28 @@ } StrutsResponseUtils.output(result); } + /** + * 获取流转科室的用户 + */ + public void findUsersOfTousseOperationDepart() { + JSONObject obj = null; + try { + String orgUnitNams = StrutsParamUtils.getPraramValue("orgUnitNams", ""); + Set userNames = userManager.findUsersOfTousseOperationDepart(orgUnitNams); + obj = JSONUtil.buildJsonObject(true); + JSONArray arr = new JSONArray(); + if(CollectionUtils.isNotEmpty(userNames)){ + for (String userName : userNames) { + JSONObject item = new JSONObject(); + item.put("name", userName); + arr.add(item); + } + } + obj.put("data", arr); + } catch (Exception e) { + obj = JSONUtil.buildJsonObject(false,e.getMessage()); + e.printStackTrace(); + } + StrutsResponseUtils.output(obj); + } }