Index: ssts-web/src/main/webapp/homepage/menuconfigure.js =================================================================== diff -u -r18320 -r18325 --- ssts-web/src/main/webapp/homepage/menuconfigure.js (.../menuconfigure.js) (revision 18320) +++ ssts-web/src/main/webapp/homepage/menuconfigure.js (.../menuconfigure.js) (revision 18325) @@ -344,7 +344,8 @@ singleClickExpand:singleClickExpandTree, hidden:SSTS_TousseManagerView || !enableSurgicalInstrumentsManagement, children:[ - {hidden :SSTS_Tousse,text:"器械包位置管理",href:WWWROOT+'/disinfectsystem/toussemanager/position/changePosition.jsp?editMode=true',hrefTarget:linkTarget,leaf:true} + {hidden :SSTS_Tousse,text:"器械包位置管理",href:WWWROOT+'/disinfectsystem/toussemanager/position/changePosition.jsp?editMode=true&operation=发货',hrefTarget:linkTarget,leaf:true}, + {hidden :SSTS_Tousse,text:"器械包签收",href:WWWROOT+'/disinfectsystem/toussemanager/position/changePosition.jsp?editMode=true&operation=签收',hrefTarget:linkTarget,leaf:true} ] },{ text:"干预管理", Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/action/TousseDefinitionAction.java =================================================================== diff -u -r18212 -r18325 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/action/TousseDefinitionAction.java (.../TousseDefinitionAction.java) (revision 18212) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/action/TousseDefinitionAction.java (.../TousseDefinitionAction.java) (revision 18325) @@ -8,7 +8,6 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; @@ -18,7 +17,6 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -38,7 +36,6 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.StringEscapeUtils; import org.apache.log4j.Logger; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; @@ -57,7 +54,6 @@ import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; import com.forgon.disinfectsystem.basedatamanager.taskGroup.service.TaskGroupManager; import com.forgon.disinfectsystem.common.CssdUtils; -import com.forgon.disinfectsystem.diposablegoods.util.DisposableGoodsUtils; import com.forgon.disinfectsystem.entity.assestmanagement.DiposableGoodsInstance; import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoods; import com.forgon.disinfectsystem.entity.basedatamanager.imagefilemanager.ImageFile; @@ -70,7 +66,6 @@ import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseDefinition; import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseInstance; import com.forgon.disinfectsystem.entity.basedatamanager.warehouse.WareHouse; -import com.forgon.disinfectsystem.entity.invoicemanager.Invoice; import com.forgon.disinfectsystem.entity.tousseitem.TousseItem; import com.forgon.disinfectsystem.goodFilterConfig.service.GoodFilterConfigManager; import com.forgon.disinfectsystem.goodsBindingConfig.vo.BindGoodVo; @@ -84,7 +79,6 @@ import com.forgon.disinfectsystem.tousse.toussedefinition.service.TousseDefinitionManager; import com.forgon.disinfectsystem.tousse.toussedefinition.service.TousseInstanceManager; import com.forgon.disinfectsystem.tousse.videomanager.service.VideoFileManager; -import com.forgon.entity.PageEntity; import com.forgon.log.model.Log; import com.forgon.log.service.LogManager; import com.forgon.tools.FileSystemHelper; @@ -98,10 +92,8 @@ import com.forgon.tools.hibernate.ObjectDao; import com.forgon.tools.json.JSONUtil; import com.forgon.tools.json.JsonPropertyFilter; -import com.forgon.tools.util.ForgonDateUtils; +import com.forgon.tools.string.StringTools; import com.forgon.tools.util.PageUtil; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Preparable; @@ -2582,6 +2574,7 @@ */ public void loadTousseByBarcode(){ String barcode = StrutsParamUtils.getPraramValue("barcode", ""); + String operation = StrutsParamUtils.getPraramValue("operation", TousseOperation.OPERATION_INVOICE); JSONObject obj = new JSONObject(); try { BarcodeDevice barcodeDevice = barcodeManager @@ -2597,9 +2590,17 @@ if(!(tousseInstance.isShipped() || tousseInstance.isSigned())){ throw new RuntimeException(String.format("只能扫描已发货或者已签收的器械包!")); } - if (StringUtils.equals(tousseInstance.getStatus2(), TousseOperation.STATUS_SENDING)) { - throw new RuntimeException("不能扫描运送中的包!"); + if(StringTools.equals(operation, TousseOperation.OPERATION_INVOICE)){ + if (StringUtils.equals(tousseInstance.getStatus2(), TousseOperation.STATUS_SENDING)) { + throw new RuntimeException("不能扫描运送中的包!"); + } + }else{ + if (StringTools.isNotBlank(tousseInstance.getStatus2()) + && !StringUtils.equals(tousseInstance.getStatus2(), TousseOperation.STATUS_SENDING)) { + throw new RuntimeException("器械包未发货!"); + } } + Set orgUnitCoding = new HashSet(); List supplyRoomConfigList = supplyRoomConfigManager.getSupplyRoomList(SupplyRoomConfig.SUPPLYROOM_TYPE_6); if(supplyRoomConfigList != null){ @@ -2618,7 +2619,7 @@ } catch (Exception e) { e.printStackTrace(); obj.put("success", false); - obj.put("errMsg", e.getMessage()); + obj.put("message", e.getMessage()); } StrutsResponseUtils.output(obj); } @@ -2683,20 +2684,27 @@ String operator = StrutsParamUtils.getPraramValue("operator", ""); String destType = StrutsParamUtils.getPraramValue("destType", ""); + String operation = StrutsParamUtils.getPraramValue("operation", TousseOperation.OPERATION_INVOICE); Long destId = StrutsParamUtils.getPraramLongValue("destId", null); String sendOutGoodsStoreData = StrutsParamUtils.getPraramValue("sendOutGoodsStoreData", ""); params.put("destType", destType); params.put("destId", destId); params.put("operator", operator); + params.put("operation", operation); JSONArray sendOutGoodsItems = JSONArray.fromObject(sendOutGoodsStoreData); params.put("items", sendOutGoodsItems); try{ - tousseInstanceManager.saveChangePosition(params); + if(TousseOperation.OPERATION_INVOICE.equals(operation)){ + tousseInstanceManager.saveChangePosition(params); + }else if(TousseOperation.OPERATION_SIGN.equals(operation)){ + tousseInstanceManager.submitSignTousseInstance(params); + } + StrutsResponseUtils.output(true, "保存成功!"); } catch (Exception ex){ ex.printStackTrace(); Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/vo/TousseOperationVo.java =================================================================== diff -u --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/vo/TousseOperationVo.java (revision 0) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/vo/TousseOperationVo.java (revision 18325) @@ -0,0 +1,121 @@ +package com.forgon.disinfectsystem.tousse.toussedefinition.vo; + +import com.forgon.disinfectsystem.entity.basedatamanager.position.TousseOperation; +import com.forgon.tools.string.StringTools; + +/** + * 器械包针对手术室的流转和签收操作的vo对象 + * @author kzh + * + */ +public class TousseOperationVo { + /** + * 操作,流转,签收 + */ + private String operation; + /** + * 操作人 + */ + private String operator; + /** + * 手术仪器管理科室名称 + */ + private String destDepart; + + /** + * 手术仪器管理科室编码 + */ + private String destDepartCoding; + /** + * 手术仪器管理位置,仓库或者手术间名称 + */ + private String destLocation; + /** + * 手术仪器管理位置类型,仓库或者手术间 + */ + private String destLocationType; + /** + * 手术仪器管理位置,仓库id + */ + private Long destWareHouseId; + /** + * 手术仪器管理位置,手术间id + */ + private Long destOperationRoomId; + public String getOperation() { + return operation; + } + public void setOperation(String operation) { + this.operation = operation; + } + public String getOperator() { + return operator; + } + public void setOperator(String operator) { + this.operator = operator; + } + public String getDestDepart() { + return destDepart; + } + public void setDestDepart(String destDepart) { + this.destDepart = destDepart; + } + public String getDestDepartCoding() { + return destDepartCoding; + } + public void setDestDepartCoding(String destDepartCoding) { + this.destDepartCoding = destDepartCoding; + } + public String getDestLocation() { + return destLocation; + } + public void setDestLocation(String destLocation) { + this.destLocation = destLocation; + } + public String getDestLocationType() { + return destLocationType; + } + public void setDestLocationType(String destLocationType) { + this.destLocationType = destLocationType; + } + public Long getDestWareHouseId() { + return destWareHouseId; + } + public void setDestWareHouseId(Long destWareHouseId) { + this.destWareHouseId = destWareHouseId; + } + public Long getDestOperationRoomId() { + return destOperationRoomId; + } + public void setDestOperationRoomId(Long destOperationRoomId) { + this.destOperationRoomId = destOperationRoomId; + } + /** + * 目标位置类型是否是手术间 + * @return + */ + public boolean destTypeOperationRoom(){ + return StringTools.equals(destLocationType, TousseOperation.DESTTYPE_OPERATIONROOM); + } + /** + * 目标位置类型是否是仓库 + * @return + */ + public boolean destTypeWareHouse(){ + return StringTools.equals(destLocationType, TousseOperation.DESTTYPE_WAREHOUSE); + } + /** + * 是否发货操作 + * @return + */ + public boolean operationInvoice(){ + return StringTools.equals(operation, TousseOperation.OPERATION_INVOICE); + } + /** + * 是否签收操作 + * @return + */ + public boolean operationSign(){ + return StringTools.equals(operation, TousseOperation.OPERATION_SIGN); + } +} Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/position/TousseOperation.java =================================================================== diff -u -r18212 -r18325 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/position/TousseOperation.java (.../TousseOperation.java) (revision 18212) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/position/TousseOperation.java (.../TousseOperation.java) (revision 18325) @@ -5,17 +5,18 @@ import java.util.Date; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Transient; -import org.apache.commons.lang.StringUtils; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import com.forgon.Constants; +import com.forgon.tools.string.StringTools; /** * @author jeffli 2017年5月23日 下午4:41:37 @@ -32,6 +33,7 @@ public static final String OPERATION_SIGN = "签收"; public static final String OPERATION_INVOICE = "发货"; + public static final String OPERATION_SIGN_INVOICE = "签收自动发货"; private Long id; @@ -62,7 +64,6 @@ */ private Long srcOperationRoomId; - // /** * 手术仪器管理科室名称 */ @@ -110,7 +111,8 @@ /** * 备注 */ - private Date remark; + @Column(length=4000) + private String remark; @Id @GeneratedValue(strategy=GenerationType.AUTO) @@ -205,11 +207,11 @@ this.operationTime = operationTime; } - public Date getRemark() { + public String getRemark() { return remark; } - public void setRemark(Date remark) { + public void setRemark(String remark) { this.remark = remark; } @@ -264,7 +266,21 @@ public void setDestOperationRoomId(Long destOperationRoomId) { this.destOperationRoomId = destOperationRoomId; } + /** + * 位置是否手术间类型 + * @param destType + * @return + */ + public static boolean destTypeOperationRoom(String destType){ + return StringTools.equals(destType, DESTTYPE_OPERATIONROOM); + } + /** + * 位置是否仓库类型 + * @param destType + * @return + */ + public static boolean destTypeWareHouse(String destType){ + return StringTools.equals(destType, DESTTYPE_WAREHOUSE); + } - - } Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java =================================================================== diff -u -r18235 -r18325 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java (.../TousseInstanceManager.java) (revision 18235) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManager.java (.../TousseInstanceManager.java) (revision 18325) @@ -478,8 +478,16 @@ * @return key为申请项TousseItem的id,value为此申请项下的所有包实例 */ public Map> groupByTousseItemId(List tousseInstances); - + /** + * 器械包流转操作 + * @param params + */ public void saveChangePosition(JSONObject params); + /** + * 手术室的器械包签收。同时可能会有流转的记录 + * @param params + */ + public void submitSignTousseInstance(JSONObject params); /** * 根据装配任务查询出对应的单据项的id(前提条件是装配任务的任务类型为申请单或回收记录) Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java =================================================================== diff -u -r18312 -r18325 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java (.../TousseInstanceManagerImpl.java) (revision 18312) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/toussedefinition/service/TousseInstanceManagerImpl.java (.../TousseInstanceManagerImpl.java) (revision 18325) @@ -87,6 +87,7 @@ import com.forgon.disinfectsystem.inventorymanagement.service.WriteBackInventoryHelper; import com.forgon.disinfectsystem.stockmanage.cssdstock.service.TousseStockManager; import com.forgon.disinfectsystem.tousse.cssdhandletousses.service.CssdHandleTousseManager; +import com.forgon.disinfectsystem.tousse.toussedefinition.vo.TousseOperationVo; import com.forgon.disinfectsystem.vo.ItemDefinitionVO; import com.forgon.disinfectsystem.vo.TousseSimpleVO; import com.forgon.log.model.Log; @@ -218,12 +219,14 @@ /** * 定时器方法,定时检查过期的包实例,并对过期的包实例进行废弃处理 */ + @Override public void autoWasteOutdateTousseInstances(){ List outdateTousseInstanceList = - (List)objectDao.getHibernateSession().createQuery("from TousseInstance where status not in ('"+TousseInstance.STATUS_USED+"','"+TousseInstance.STATUS_RECYCLED+"','"+TousseInstance.STATUS_DISCARD+"') and validUntil < :validUntil").setDate("validUntil", new java.sql.Timestamp(new Date().getTime())).list(); + objectDao.getHibernateSession().createQuery("from TousseInstance where status not in ('"+TousseInstance.STATUS_USED+"','"+TousseInstance.STATUS_RECYCLED+"','"+TousseInstance.STATUS_DISCARD+"') and validUntil < :validUntil").setDate("validUntil", new java.sql.Timestamp(new Date().getTime())).list(); discardTousseInstance(outdateTousseInstanceList,"系统定时器","失效期过期定时废弃处理"); } + @Override public void discardTousseInstance(Collection tousseInstances,String operateUser,String wasteReason) { discardTousseInstances(tousseInstances, operateUser, wasteReason, new Date()); } @@ -571,9 +574,11 @@ } } + @Override public void discardTousseInstance(Collection tousseInstances,String wasteReason){ discardTousseInstance(tousseInstances,AcegiHelper.getLoginUserFullName(),wasteReason); } + @Override public void discardTousseInstance(TousseInstance tousseInstance,String operateUser,String wasteReason,Date wasteDate){ if(tousseInstance == null){ return; @@ -583,12 +588,14 @@ discardTousseInstances(tousseInstances, operateUser, wasteReason, wasteDate); } + @Override public void discardTousseInstance(TousseInstance tousseInstance, String wasteReason) { String operateUser = AcegiHelper.getLoginUser().getUserFullName(); discardTousseInstance(tousseInstance, operateUser, wasteReason, new Date()); } + @Override public void discardTousseInstance(TousseInstance tousseInstance,String operateUser,String wasteReason){ discardTousseInstance(tousseInstance, operateUser, wasteReason, new Date()); } @@ -658,6 +665,7 @@ * @param sqlCondition where子句的Map * @return */ + @Override public List getAllReviewedTousseInstanceWithOutBasket( String orgUnitCode , String beginDate , String endDate , String start , String limit, String searchKeyWord, Map sqlCondition){ String sql = " where po.comboTousseInstanceId is null and po.status = '" + TousseInstance.STATUS_REVIEWED @@ -1413,7 +1421,7 @@ for(int i = kk*sheetSize; i< (kk+1)*sheetSize ; i++ ){ if(i getUnTraceableTousseInstanceListByFictitiousTousseDefinition( TousseDefinition tousseDefinition, Collection sqlWheres){ if(tousseDefinition == null){ @@ -1706,6 +1715,7 @@ return getUnTraceableTousseInstanceListByFictitiousTousseDefinition( tousseDefinition,sqlWheres,null,tousseDefinition.getScanAmount()); } + @Override public int getUnTraceableTousseInstanceAmountByFictitiousTousseDefinition( TousseDefinition tousseDefinition, Collection sqlWheres){ if (tousseDefinition == null @@ -1813,7 +1823,7 @@ try { List waitWasteTousseInstanceList = - (List)objectDao.findBySql(TousseInstance.class.getSimpleName(),sqlCondition); + objectDao.findBySql(TousseInstance.class.getSimpleName(),sqlCondition); if(CollectionUtils.isNotEmpty(waitWasteTousseInstanceList)){ List goodsStockList = new ArrayList<>(); //更新器械包库存 @@ -1855,6 +1865,7 @@ }; } + @Override public Predicate checkTousseInstanceNotInWarningPeriod(){ return new Predicate() { @Override @@ -1964,24 +1975,28 @@ return null; } + @Override public TousseInstance getTousseInstanceByNameAndAPPID(String tousseName,String appid){ String sql = String.format(" where po.tousseName='%s' and po.invoicePlanID=%s", tousseName,appid); return (TousseInstance) objectDao.getBySql( TousseInstance.class.getSimpleName(),sql); } + @Override public List getBySql_ForUpdate(String sql) { List retList = objectDao.findBySql_ForUpdate( TousseInstance.class.getSimpleName(), sql); return retList; } + @Override public List getBySql(String sql){ List retList = objectDao.findBySql( TousseInstance.class.getSimpleName(), sql); return retList; } + @Override public List getByIDs_ForUpdate(String ids){ if(StringUtils.isBlank(ids)){ return null; @@ -2068,6 +2083,7 @@ * 灭菌管理传入TousseInstance.STATUS_REVIEWED,发货计划传入TousseInstance.STATUS_STERILED * @return */ + @Override public Map getTousseInstanceListByRange(String begin , String end , String tousseInstanceStatus){ Map result = new HashMap(); String conditionType = null; @@ -2201,6 +2217,28 @@ } return msg; } + /** + * 签收器械包 + * @param tousseInstance + * @param tousseOperationVo + * @param updatePosition 是否同时更新器械包的位置信息 + * @return + */ + public void signTousseInstance(TousseInstance tousseInstance,TousseOperationVo tousseOperationVo){ + if(tousseInstance == null){ + return; + } + if(tousseInstance.isShipped()){ + if(tousseOperationVo == null || StringTools.isBlank(tousseOperationVo.getOperator())){ + throw new RuntimeException("签收人不能为空"); + } + tousseInstance.setSignedDate(new Date()); + tousseInstance.setSignedUser(tousseOperationVo.getOperator()); + tousseInstance.setStatus(TousseInstance.STATUS_SIGNED); + + saveOrUpdate(tousseInstance); + } + } @Override public boolean canSign(TousseInstance tousseInstance,String signerOrgUnitCoding) { @@ -2472,6 +2510,7 @@ /** * 通过器械包实例id和灭菌记录id获取灭菌位置信息 */ + @Override public String getSterilzerPositionMsg(String tousseInstanceId,String sterilizationID){ if(StringUtils.isBlank(tousseInstanceId) || StringUtils.isBlank(sterilizationID)){ return null; @@ -2533,6 +2572,7 @@ /** * 获取器械包实例的最后一条清洗记录 */ + @Override public WashAndDisinfectRecord getLastWashRecord(TousseInstance tousseInstance){ if(tousseInstance == null){ return null; @@ -2567,6 +2607,7 @@ /** * 获取回收记录 */ + @Override public RecyclingRecord getRecylingRecord(String recyclingRecordId){ if(StringUtils.isNumeric(recyclingRecordId)){ return (RecyclingRecord) objectDao.getByProperty( @@ -2578,6 +2619,7 @@ /** * 获取申请记录 */ + @Override public InvoicePlan getInvoicePlan(String invoicePlanId){ if(StringUtils.isNumeric(invoicePlanId)){ return (InvoicePlan) objectDao.getByProperty( @@ -2589,6 +2631,7 @@ /** * 获取器械包篮筐条码 */ + @Override public String getClassifyBasketBarcodes(TousseInstance tousseInstance){ if(tousseInstance == null){ return null; @@ -2640,6 +2683,7 @@ * 重新计算虚拟篮筐状态(灭菌装载、审核、废弃、发货后都需要重新计算) * @param virtualBasketNameList 虚拟篮筐名称集合 */ + @Override public void countVirtualContainerStatus(List virtualBasketNameList) { if(CollectionUtils.isNotEmpty(virtualBasketNameList)){ for(String virtualBasketName : virtualBasketNameList){ @@ -2719,7 +2763,7 @@ if (DatabaseUtil.isPoIdValid(tousseInstanceId)) { String sql = String.format("where po.id in(select useRecordId from TousseInstanceUseRecord where tousseInstanceId=%s))", tousseInstanceId); - list = (List) objectDao.findBySql("UseRecord", sql); + list = objectDao.findBySql("UseRecord", sql); } return list; @@ -2729,6 +2773,7 @@ * @param barcodes 格式如:'010222333','010444555' * @return true 当器械包的灭菌炉有配了定期监测,并且没有录入了相关的定期监测记录;其他情况均返回false */ + @Override public boolean isNeedRoutineMonitoringWarning(String barcodes){ boolean haveRoutineMonitoring = false; if(StringUtils.isBlank(barcodes)){ @@ -2777,6 +2822,7 @@ } } } + @Override public JSONObject getTodaySignedTousseInstanceOfUser(String departCode,String signedUser){ String todayStr = Constants.SIMPLEDATEFORMAT_YYYYMMDD.format(new Date()); @@ -2940,81 +2986,280 @@ return map; } + @Override public void saveChangePosition(JSONObject params) { - String destType = JSONUtil.optString(params, "destType", null); - String operator = JSONUtil.optString(params, "operator", ""); - Long destId = JSONUtil.optLong(params, "destId", null); + TousseOperationVo tousseOperationVo = parseTousseOperationVo(params); + JSONArray items = params.optJSONArray("items"); + List list = parseAndLockTousseInstances(items); + + for (TousseInstance tousseInstance : list) { + String status2 = tousseInstance.getStatus2(); + if (StringUtils.equals(status2, TousseOperation.STATUS_SENDING)) { + throw new RuntimeException("运送中的包不能流转!"); + } + if(tousseOperationVo.operationInvoice()){}else{} + tousseOperation(tousseOperationVo, tousseInstance); + if(tousseInstance.isShipped() && tousseOperationVo.operationSign()){} + } + } + @Override + public void submitSignTousseInstance(JSONObject params){ + TousseOperationVo tousseOperationVo = parseTousseOperationVo(params); + JSONArray items = params.optJSONArray("items"); + List list = parseAndLockTousseInstances(items); + for (TousseInstance tousseInstance : list) { + String status2 = tousseInstance.getStatus2(); + if (StringUtils.isNotBlank(status2) && !StringUtils.equals(status2, TousseOperation.STATUS_SENDING)) { + throw new RuntimeException("器械包没有发货!"); + } + //如果仓库被修改了,那需要有一条流转记录 + boolean chaned = changePositionIfNeeded(tousseOperationVo, tousseInstance); + if(!chaned){ + updatePosition(tousseInstance, TousseOperation.STATUS_SENDING); + } + //是已发货状态,并且是签收操作,那需要处理签收 + signTousseInstance(tousseInstance, tousseOperationVo); + //签收并记录签收记录 + tousseOperationSign(tousseOperationVo, tousseInstance); + + } + } + /** + * 更新位置。在第一次签收后调用。把器械包位置的信息,修改为发货时的仓库对应的信息 + * @param tousseInstance + * @param status2 + */ + private void updatePosition(TousseInstance tousseInstance,String status2){ + if(tousseInstance != null && tousseInstance.isShipped()){ + tousseInstance.setStatus2(status2); + tousseInstance.setDepart2(tousseInstance.getLocationForDisplay()); + tousseInstance.setDepartCoding2(tousseInstance.getLocation()); + tousseInstance.setLocation2(tousseInstance.getWareHouseName()); + tousseInstance.setLocation2Type(TousseOperation.DESTTYPE_WAREHOUSE); + tousseInstance.setWareHouseId2(tousseInstance.getWareHouseId()); + objectDao.saveOrUpdate(tousseInstance); + } + } + private boolean changePositionIfNeeded(TousseOperationVo tousseOperationVo, + TousseInstance tousseInstance) { + if(tousseOperationVo == null || tousseInstance == null){ + return false; + } + + TousseOperation tousseOperation = new TousseOperation(); + tousseOperation.setDestDepart(tousseOperationVo.getDestDepart()); + tousseOperation.setDestDepartCoding(tousseOperationVo.getDestDepartCoding()); + tousseOperation.setDestLocation(tousseOperationVo.getDestLocation()); + tousseOperation.setDestLocationType(tousseOperationVo.getDestLocationType()); + tousseOperation.setDestOperationRoomId(tousseOperationVo.getDestOperationRoomId()); + tousseOperation.setDestWareHouseId(tousseOperationVo.getDestWareHouseId()); + tousseOperation.setOperator(tousseOperationVo.getOperator()); + tousseOperation.setOperation(TousseOperation.OPERATION_SIGN_INVOICE); + tousseOperation.setOperationTime(new Date()); + tousseOperation.setRemark("签收修改了仓库"); + tousseOperation.setTousseInstanceId(tousseInstance.getId()); + boolean changed = false; + + if(tousseInstance.isShipped()){ + //已发货状态,那是第一次签收,与原先的仓库比较。需要分两种情况。1、如果要签收到手术间,肯定不一样。2、如果要签收到仓库,需要看是不是跟原先的仓库一样 + if(tousseOperationVo.destTypeOperationRoom()){ + changed = true; + }else if(tousseOperationVo.destTypeWareHouse()){ + Long wareHouseId = tousseInstance.getWareHouseId(); + if(wareHouseId != null && !wareHouseId.equals(tousseOperationVo.getDestWareHouseId())){ + changed = true; + } + } + if(changed){ + tousseOperation.setSrcDepart(tousseInstance.getDepart()); + tousseOperation.setSrcDepartCoding(tousseInstance.getDepartCoding()); + tousseOperation.setSrcLocation(tousseInstance.getWareHouseName()); + tousseOperation.setSrcLocationType(TousseOperation.DESTTYPE_WAREHOUSE); + tousseOperation.setSrcWareHouseId(tousseInstance.getWareHouseId()); + } + }else if(tousseInstance.isSigned()){ + //已签收,那与仓库2或者是手术间比较 + if(TousseOperation.destTypeOperationRoom(tousseInstance.getLocation2Type())){ + //原来是在手术间的,需要分两种情况。1、如果要签收到手术间,需要比较是否是不同的手术间。2、如果要签收到仓库,那肯定跟手术间是不一样的 + if(tousseOperationVo.destTypeOperationRoom()){ + Long operationRoomId = tousseInstance.getOperationRoomId(); + if(operationRoomId != null && !operationRoomId.equals(tousseOperationVo.getDestOperationRoomId())){ + changed = true; + } + }else if(tousseOperationVo.destTypeWareHouse()){ + changed = true; + } + if(changed){ + tousseOperation.setSrcOperationRoomId(tousseInstance.getOperationRoomId()); + } + }else if(TousseOperation.destTypeWareHouse(tousseInstance.getLocation2Type())){ + //原来是在仓库的,需要分两种情况。1、如果要签收到手术间,肯定不一样。2、如果要签收到仓库,需要看是不是跟原先的仓库一样 + if(tousseOperationVo.destTypeOperationRoom()){ + changed = true; + }else if(tousseOperationVo.destTypeWareHouse()){ + Long wareHouseId = tousseInstance.getWareHouseId2(); + if(wareHouseId != null && !wareHouseId.equals(tousseOperationVo.getDestWareHouseId())){ + changed = true; + } + } + if(changed){ + tousseOperation.setSrcWareHouseId(tousseInstance.getWareHouseId2()); + } + } + if(changed){ + //不是第一次签收,并且签收的目的地址与发货的地址不一样,抛出异常 + throw new RuntimeException(String.format("条码为%s的%s签收位置与发送位置不一致", + tousseInstance.getBarcode(),tousseInstance.getTousseName())); +// tousseOperation.setSrcDepart(tousseInstance.getDepart2()); +// tousseOperation.setSrcDepartCoding(tousseInstance.getDepartCoding2()); +// tousseOperation.setSrcLocation(tousseInstance.getLocation2()); +// tousseOperation.setSrcLocationType(tousseInstance.getLocation2Type()); + } + } + if(changed){ + objectDao.save(tousseOperation); + //同时修改器械包的信息,以便于后面的签收操作 + tousseInstance.setStatus2(TousseOperation.STATUS_SENDING); + tousseInstance.setDepart2(tousseOperation.getDestDepart()); + tousseInstance.setDepartCoding2(tousseOperation.getDestDepartCoding()); + tousseInstance.setLocation2(tousseOperation.getDestLocation()); + tousseInstance.setLocation2Type(tousseOperation.getDestLocationType()); + tousseInstance.setOperationRoomId(tousseOperation.getDestOperationRoomId()); + tousseInstance.setWareHouseId2(tousseOperation.getDestWareHouseId()); + tousseInstance.setTousseOperationId(tousseOperation.getId()); + objectDao.saveOrUpdate(tousseInstance); + } + return changed; + } + /** + * 器械包流转操作 + * @param tousseOperationVo + * @param tousseInstance + */ + private void tousseOperation(TousseOperationVo tousseOperationVo, + TousseInstance tousseInstance) { + TousseOperation tousseOperation = new TousseOperation(); + tousseOperation.setOperation(tousseOperationVo.getOperation()); + tousseOperation.setOperationTime(new Date()); + tousseOperation.setOperator(tousseOperationVo.getOperator()); + tousseOperation.setDestDepart(tousseOperationVo.getDestDepart()); + tousseOperation.setDestDepartCoding(tousseOperationVo.getDestDepartCoding()); + tousseOperation.setDestLocation(tousseOperationVo.getDestLocation()); + tousseOperation.setDestLocationType(tousseOperationVo.getDestLocationType()); + tousseOperation.setDestOperationRoomId(tousseOperationVo.getDestOperationRoomId()); + tousseOperation.setDestWareHouseId(tousseOperationVo.getDestWareHouseId()); + tousseOperation.setTousseInstanceId(tousseInstance.getId()); + objectDao.saveOrUpdate(tousseOperation); + + tousseInstance.setStatus2(TousseOperation.STATUS_SENDING); + tousseInstance.setDepart2(tousseOperationVo.getDestDepart()); + tousseInstance.setDepartCoding2(tousseOperationVo.getDestDepartCoding()); + tousseInstance.setLocation2(tousseOperationVo.getDestLocation()); + tousseInstance.setLocation2Type(tousseOperationVo.getDestLocationType()); + tousseInstance.setOperationRoomId(tousseOperationVo.getDestOperationRoomId()); + tousseInstance.setWareHouseId2(tousseOperationVo.getDestWareHouseId()); + tousseInstance.setTousseOperationId(tousseOperation.getId()); + objectDao.saveOrUpdate(tousseInstance); + } + /** + * 器械包签收并记录签收记录 + * @param tousseOperationVo + * @param tousseInstance + */ + private void tousseOperationSign(TousseOperationVo tousseOperationVo, + TousseInstance tousseInstance){ + //签收的时候,可能并没有选择目的位置,此时使用器械包中上一次操作的信息。说明位置没有变,就是发往哪里,就签收到哪里 + String destDepart = StringTools.defaultIfBlank(tousseOperationVo.getDestDepart(), tousseInstance.getDepart2()); + String destDepartCoding = StringTools.defaultIfBlank(tousseOperationVo.getDestDepartCoding(), tousseInstance.getDepartCoding2()); + String destLocation = StringTools.defaultIfBlank(tousseOperationVo.getDestLocation(), tousseInstance.getLocation2()); + String destLocationType = StringTools.defaultIfBlank(tousseOperationVo.getDestLocationType(), tousseInstance.getLocation2Type()); + Long destOperationRoomId = null; + if(TousseOperation.destTypeOperationRoom(destLocationType)){ + destOperationRoomId = tousseOperationVo.getDestOperationRoomId() == null?tousseInstance.getOperationRoomId():tousseOperationVo.getDestOperationRoomId(); + } + Long destWareHouseId = null; + if(TousseOperation.destTypeWareHouse(destLocationType)){ + destWareHouseId = tousseOperationVo.getDestWareHouseId() == null?tousseInstance.getWareHouseId2():tousseOperationVo.getDestWareHouseId(); + } + + TousseOperation tousseOperation = new TousseOperation(); + tousseOperation.setOperation(tousseOperationVo.getOperation()); + tousseOperation.setOperationTime(new Date()); + tousseOperation.setOperator(tousseOperationVo.getOperator()); + tousseOperation.setDestDepart(destDepart); + tousseOperation.setDestDepartCoding(destDepartCoding); + tousseOperation.setDestLocation(destLocation); + tousseOperation.setDestLocationType(destLocationType); + tousseOperation.setDestOperationRoomId(destOperationRoomId); + tousseOperation.setDestWareHouseId(destWareHouseId); + tousseOperation.setTousseInstanceId(tousseInstance.getId()); + objectDao.saveOrUpdate(tousseOperation); + + tousseInstance.setStatus2(TousseOperation.STATUS_SIGNED); + tousseInstance.setDepart2(destDepart); + tousseInstance.setDepartCoding2(destDepartCoding); + tousseInstance.setLocation2(destLocation); + tousseInstance.setLocation2Type(destLocationType); + tousseInstance.setOperationRoomId(destOperationRoomId); + tousseInstance.setWareHouseId2(destWareHouseId); + tousseInstance.setTousseOperationId(tousseOperation.getId()); + objectDao.saveOrUpdate(tousseInstance); + } + /** + * 解析并锁定器械包实例 + * @param items + * @return + */ + private List parseAndLockTousseInstances(JSONArray items) { Set idSet = new HashSet(); - JSONArray items = params.optJSONArray("items"); for (int i = 0; i < items.size(); ++i) { JSONObject item = items.getJSONObject(i); Long id = JSONUtil.optLong(item, "id", null); if (id != null) { idSet.add(id); } } - String depart2; - String departCoding2; - String location2; - Long wareHouseId2 = null; - Long operationRoomId = null; - if (StringUtils.isBlank(destType)) { + String sql = String.format(" where %s ", SqlUtils + .getNonStringFieldInCollectionsPredicate("po.id", idSet)); + List list = getBySql_ForUpdate(sql); + if (CollectionUtils.isEmpty(list)) { + throw new RuntimeException("器械包不能为空!"); + } + return list; + } + /** + * 获取器械包流转操作和签收操作的参数 + * @param params + * @return + */ + private TousseOperationVo parseTousseOperationVo(JSONObject params) { + TousseOperationVo tousseOperationVo = new TousseOperationVo(); + tousseOperationVo.setDestLocationType(JSONUtil.optString(params, "destType", null)); + tousseOperationVo.setOperator(JSONUtil.optString(params, "operator", "")); + tousseOperationVo.setOperation(JSONUtil.optString(params, "operation", TousseOperation.OPERATION_INVOICE)); + Long destId = JSONUtil.optLong(params, "destId", null); + + if (tousseOperationVo.operationInvoice() && StringUtils.isBlank(tousseOperationVo.getDestLocationType())) { throw new RuntimeException("位置类型不能为空!"); } - if (StringUtils - .equals(destType, TousseOperation.DESTTYPE_OPERATIONROOM)) { + if (tousseOperationVo.destTypeOperationRoom()) { OperationRoom operationRoom = (OperationRoom) objectDao .getByProperty(OperationRoom.class.getSimpleName(), "id", destId); - operationRoomId = operationRoom.getId(); - depart2 = operationRoom.getOrgUnitName(); - departCoding2 = operationRoom.getOrgUnitCoding(); - location2 = operationRoom.getOperationRoomName(); - } else { + tousseOperationVo.setDestOperationRoomId(operationRoom.getId()); + tousseOperationVo.setDestDepart(operationRoom.getOrgUnitName()); + tousseOperationVo.setDestDepartCoding(operationRoom.getOrgUnitCoding()); + tousseOperationVo.setDestLocation(operationRoom.getOperationRoomName()); + } else if(tousseOperationVo.destTypeWareHouse()) { WareHouse wareHouse = (WareHouse) objectDao.getByProperty( WareHouse.class.getSimpleName(), "id", destId); - wareHouseId2 = wareHouse.getId(); - depart2 = wareHouse.getOrgUnitName(); - departCoding2 = wareHouse.getOrgUnitCode(); - location2 = wareHouse.getName(); + tousseOperationVo.setDestWareHouseId(wareHouse.getId()); + tousseOperationVo.setDestDepart(wareHouse.getOrgUnitName()); + tousseOperationVo.setDestDepartCoding(wareHouse.getOrgUnitCode()); + tousseOperationVo.setDestLocation(wareHouse.getName()); } - - String sql = String.format(" where %s ", SqlUtils - .getNonStringFieldInCollectionsPredicate("po.id", idSet)); - List list = getBySql_ForUpdate(sql); - if (CollectionUtils.isEmpty(list)) { - throw new RuntimeException("器械包不能为空!"); - } - - for (TousseInstance tousseInstance : list) { - String status2 = tousseInstance.getStatus2(); - if (StringUtils.equals(status2, TousseOperation.STATUS_SENDING)) { - throw new RuntimeException("运送中的包不能流转!"); - } - TousseOperation tousseOperation = new TousseOperation(); - tousseOperation.setOperation(TousseOperation.OPERATION_INVOICE); - tousseOperation.setOperationTime(new Date()); - tousseOperation.setOperator(operator); - tousseOperation.setDestDepart(depart2); - tousseOperation.setDestDepartCoding(departCoding2); - tousseOperation.setDestLocation(location2); - tousseOperation.setDestLocationType(destType); - tousseOperation.setDestOperationRoomId(operationRoomId); - tousseOperation.setDestWareHouseId(wareHouseId2); - tousseOperation.setTousseInstanceId(tousseInstance.getId()); - objectDao.saveOrUpdate(tousseOperation); - - tousseInstance.setStatus2(TousseOperation.STATUS_SENDING); - tousseInstance.setDepart2(depart2); - tousseInstance.setDepartCoding2(departCoding2); - tousseInstance.setLocation2(location2); - tousseInstance.setLocation2Type(destType); - tousseInstance.setWareHouseId2(wareHouseId2); - tousseInstance.setOperationRoomId(operationRoomId); - tousseInstance.setTousseOperationId(tousseOperation.getId()); - objectDao.saveOrUpdate(tousseInstance); - } + return tousseOperationVo; } @Override Index: ssts-web/src/main/webapp/disinfectsystem/toussemanager/position/changePosition.jsp =================================================================== diff -u -r18213 -r18325 --- ssts-web/src/main/webapp/disinfectsystem/toussemanager/position/changePosition.jsp (.../changePosition.jsp) (revision 18213) +++ ssts-web/src/main/webapp/disinfectsystem/toussemanager/position/changePosition.jsp (.../changePosition.jsp) (revision 18325) @@ -1,3 +1,4 @@ +<%@page import="com.forgon.disinfectsystem.entity.basedatamanager.position.TousseOperation"%> <%@page import="java.text.SimpleDateFormat"%> <%@page import="com.forgon.disinfectsystem.entity.tousseitem.TousseItem"%> <%@page import="java.util.Calendar"%> @@ -80,6 +81,8 @@ var selectedApplyDate = ""; var selectedTousseType = ""; var selectedInvoicePlanId = ""; + var operation = '${param.operation}'; + var OPERATION_SIGN = '<%=TousseOperation.OPERATION_SIGN%>';