Index: ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/action/UseRecordActionBase.java =================================================================== diff -u -r19266 -r19583 --- ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/action/UseRecordActionBase.java (.../UseRecordActionBase.java) (revision 19266) +++ ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/action/UseRecordActionBase.java (.../UseRecordActionBase.java) (revision 19583) @@ -8,38 +8,27 @@ import net.sf.json.JSONArray; import net.sf.json.JSONObject; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.BooleanUtils; import com.forgon.Constants; import com.forgon.directory.acegi.tools.AcegiHelper; import com.forgon.directory.model.BarcodeDevice; import com.forgon.disinfectsystem.barcode.service.BarcodeManager; import com.forgon.disinfectsystem.basedatamanager.goodsdepartshareconfig.service.GoodsDepartShareConfigManager; -import com.forgon.disinfectsystem.common.CssdUtils; import com.forgon.disinfectsystem.diposablegoods.service.DiposableGoodsManager; -import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoods; import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoodsBatch; import com.forgon.disinfectsystem.entity.assestmanagement.ExpensiveDisposablegoods; -import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseDefinition; import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseInstance; import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseMaterialErrorDamage; -import com.forgon.disinfectsystem.entity.idcarddefinition.IDCardDefinition; -import com.forgon.disinfectsystem.entity.invoicemanager.Invoice; import com.forgon.disinfectsystem.entity.materialerrordamage.MaterialErrorDamageDetail; -import com.forgon.disinfectsystem.entity.tousseitem.TousseItem; import com.forgon.disinfectsystem.entity.useRecord.UseDiposableGoodsItem; import com.forgon.disinfectsystem.entity.useRecord.UseRecord; -import com.forgon.disinfectsystem.idcarddefinition.util.IDCardDefinitionUtils; import com.forgon.disinfectsystem.tousse.toussedefinition.service.TousseInstanceManager; import com.forgon.disinfectsystem.useRecord.service.UseRecordManager; import com.forgon.tools.StrutsParamUtils; import com.forgon.tools.StrutsResponseUtils; -import com.forgon.tools.db.DatabaseUtil; import com.forgon.tools.hibernate.ObjectDao; import com.forgon.tools.json.JSONUtil; -import com.forgon.tools.string.StringTools; public class UseRecordActionBase { @@ -52,264 +41,9 @@ protected void loadBarcode(String barcode, String scanedBarcodes, String currentOrgUnitCode) { - JSONObject obj = new JSONObject(); + JSONObject obj = null; try { - obj.put("success", true); - if (StringUtils.isNotBlank(barcode)) { - BarcodeDevice bd = barcodeManager.getBarcodeByBarcode(barcode); - if (bd != null) { - //检测器械包所属科室是否与当前用户所在科室为物品共用科室 - - if (bd instanceof TousseInstance) { - TousseInstance ti = (TousseInstance) bd; - - // 1.判断是否为聚合包内的普通包实例,如果是则提示该包不能录入使用记录 - if(DatabaseUtil.isPoIdValid(ti.getComboTousseInstanceId())){ - obj.put("success", false); - obj.put("error", "条码为" + barcode + "的包属于聚合包内的器械包,不能录入使用记录"); - return; - } - - // 2.判断是否为聚合包,如果是,则需要验证所录入的使用记录次数是否大于其包内普通包实例个数 - if(ti.isComboTousse()){ - int useTimes = objectDao.countBySql("select count(0) from TousseInstanceUseRecord where tousseInstanceId=" + ti.getId()); - List tousseInstanceList = ti.getTousseInstancesBelongToThisComboTousse(objectDao); - int size = CollectionUtils.isNotEmpty(tousseInstanceList) ? tousseInstanceList.size() : 0; - if(useTimes >= size){ - obj.put("success", false); - obj.put("error", "条码为" + barcode + "的聚合包使用次数已经达到其包内器械包的数量,不能再录入"); - return; - } - - // 如果有签收时间则还原为签收状态,否则还原为器械包实例“已发货”状态,便于继续录使用记录 - if (ti.getSignedDate() != null) { - ti.setStatus(TousseInstance.STATUS_SIGNED); - } else { - ti.setStatus(TousseInstance.STATUS_SHIPPED); - } - } - - // 3.检测该器械包有没有被召回 - if (TousseInstance.STATUS_WAIT_FOR_RECALL.equals(ti.getStatus()) || TousseInstance.STATUS_RECALLED.equals(ti.getStatus())) { - obj.put("msg", "该器械包不能被使用,已被召回!"); - } else if(!TousseInstance.STATUS_SHIPPED.equals(ti.getStatus()) && !TousseInstance.STATUS_SIGNED.equals(ti.getStatus())){ - obj.put("msg", "该器械包状态为" + ti.getStatus() + ",不能录入使用记录!"); - } else { - List acceptStatus = new ArrayList<>(); - boolean notSignedItemsCanRegistUseRecord = CssdUtils.getSystemSetConfigByNameBool("notSignedItemsCanRegistUseRecord"); - if(notSignedItemsCanRegistUseRecord){ - acceptStatus.add(TousseInstance.STATUS_SHIPPED); - } - acceptStatus.add(TousseInstance.STATUS_SIGNED); - TousseInstance older = tousseInstanceManager.getExpireNearest(ti, acceptStatus,StringTools.toCollectionIgnoreNullAndBlank(scanedBarcodes)); - TousseDefinition td = ti.getTousseDefinition(); - //判断当前用户登录科室是否存在共用科室配置 - if(CollectionUtils.isNotEmpty(goodsDepartShareConfigManager.getGoodsShareDepartList(currentOrgUnitCode))){ - //判断包实例所属科室是否与当前用户登录科室配置物品共享 - if(goodsDepartShareConfigManager.canShareGoodsforTwoDepart(currentOrgUnitCode, ti.getLocation())){ - String validUntilStr = ti.getValidUntilStr(Constants.SIMPLEDATEFORMAT_YYYYMMDD); - String tousseDefinitionName = ""; - String tousseType = ""; - String includeImplant = ""; - if (td != null) { - tousseType = td.getTousseType(); - tousseDefinitionName = td.getName(); - includeImplant = td.getIncludeImplantStr(); - } - obj.put("id", ti.getId()); - obj.put("barcode", ti.getBarcode()); - obj.put("tousseDefinitionName", tousseDefinitionName); - obj.put("showTousseName", ti.getShowTousseName()); - obj.put("packageType", ti.getPackageType()); - obj.put("validUntil", validUntilStr); - obj.put("status", ti.getStatus()); - obj.put("location",ti.getLocation()); - obj.put("locationForDisplay",ti.getLocationForDisplay()); - obj.put("materials", null); - obj.put("foreignTousseApp_id",ti.getForeignTousseApp_id()); - obj.put("tousseType", tousseType); - obj.put("includeImplant", includeImplant); - obj.put("actualUsed", Constants.STR_YES); //扫描的时候,都取默认值,为是。以免录了使用记录之后,又删除了,就把包实例这个属性修改了,再扫描,就不是默认的值了 - obj.put("haveUnSupplementMaterials", BooleanUtils.toBooleanDefaultIfNull(ti.getHaveUnSupplementMaterials(), false)); - - //是否回收 - obj.put("isRecycling", td.getIsRecycling()); - //是否转换申请单 - obj.put("isConvertApplyGoods", td.getIsConvertApplyGoods()); - }else{ - obj.put("msg", "该器械包所属科室为" + ti.getLocationForDisplay() + ",未配置与当前科室共用,不能录入使用记录!"); - } - }else{ - //判断包实例所在位置与当前用户所在科室是否一致 - if(StringUtils.equals(currentOrgUnitCode, ti.getLocation())){ - String validUntilStr = ti.getValidUntilStr(Constants.SIMPLEDATEFORMAT_YYYYMMDD); - String tousseDefinitionName = ""; - String tousseType = ""; - String includeImplant = ""; - if (td != null) { - tousseType = td.getTousseType(); - tousseDefinitionName = td.getName(); - includeImplant = td.getIncludeImplantStr(); - } - obj.put("id", ti.getId()); - obj.put("barcode", ti.getBarcode()); - obj.put("tousseDefinitionName", tousseDefinitionName); - obj.put("showTousseName", ti.getShowTousseName()); - obj.put("packageType", ti.getPackageType()); - obj.put("validUntil", validUntilStr); - obj.put("status", ti.getStatus()); - obj.put("location",ti.getLocation()); - obj.put("locationForDisplay",ti.getLocationForDisplay()); - obj.put("materials", null); - obj.put("foreignTousseApp_id",ti.getForeignTousseApp_id()); - obj.put("tousseType", tousseType); - obj.put("includeImplant", includeImplant); - obj.put("actualUsed", Constants.STR_YES); - obj.put("haveUnSupplementMaterials", BooleanUtils.toBooleanDefaultIfNull(ti.getHaveUnSupplementMaterials(), false)); - - //是否回收 - obj.put("isRecycling", td.getIsRecycling()); - //是否转换申请单 - obj.put("isConvertApplyGoods", td.getIsConvertApplyGoods()); - }else{ - obj.put("msg", "该器械包所属科室为" + ti.getLocationForDisplay() + ",不能录入使用记录!"); - } - } - // 使用次数 -// Long idCardInstanceId = ti.getIdCardInstanceID(); -// if(idCardInstanceId != null){ -// IDCardDefinition idCardDefinition = IDCardDefinitionUtils.getIDCardDefinitionsByIdCardInstanceId(objectDao, idCardInstanceId); -// if(idCardDefinition != null){ -// obj.put("idCardUseAmount", idCardDefinition.getUseAmount()); -// } -// } - obj.put("idCardUseAmount", ti.getUseAmount()); - if(older != null){ - JSONObject json = new JSONObject(); - json.put("barcode", older.getBarcode()); - json.put("tousseName", older.getTousseDefinitionName()); - obj.put("older", json); - } - } - } else if (bd instanceof ExpensiveDisposablegoods) { - // 高值耗材 - ExpensiveDisposablegoods expensiveDisposablegoods = (ExpensiveDisposablegoods) bd; - if(!ExpensiveDisposablegoods.STATUS_DELIVERED.equals(expensiveDisposablegoods.getStatus())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材状态为%s,不能录使用记录", barcode,expensiveDisposablegoods.getStatus())); - return; - } - - //判断该高值耗材关联的一次性物品定义的物品类型是否为高值耗材(防止入库时定义为高值耗材,后来修改定义为非高值耗材) - if(expensiveDisposablegoods.getDisposableGoodsID() == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材未找到一次性物品定义", barcode)); - return; - } - DisposableGoods disposableGoods = - diposableGoodsManager.get(expensiveDisposablegoods.getDisposableGoodsID()); - if(disposableGoods == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材一次性物品定义已被删除", barcode)); - return; - } - - if(!DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS.equals(disposableGoods.getGoodsType())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材对应一次性物品不为高值耗材", barcode)); - return; - } - - //需要判断发货单是否存在且发货科室与当前登录用户是否为同一个科室,否则给予提示 - Long invoiceId = expensiveDisposablegoods.getInvoiceId(); - if(invoiceId == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材发货单已被删除", barcode)); - return; - } - - Invoice invoice = useRecordManager.getInvoiceById(invoiceId); - if(invoice == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材发货单已被删除", barcode)); - return; - } - - /*if(!StringUtils.equals(invoice.getDepart(), AcegiHelper.getLoginUser().getCurrentOrgUnitName())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材所属科室与当前登录用户所属科室不一致", barcode)); - return; - }*/ - //判断当前用户登录科室是否存在共用科室配置 - if(CollectionUtils.isNotEmpty(goodsDepartShareConfigManager.getGoodsShareDepartList(currentOrgUnitCode))){ - //判断包实例所属科室是否与当前用户登录科室配置物品共享 - if(!goodsDepartShareConfigManager.canShareGoodsforTwoDepart(currentOrgUnitCode, expensiveDisposablegoods.getLocation())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材所属科室为" + invoice.getDepart() + ",未配置与当前科室共用,不能录入使用记录!", barcode)); - return; - } - }else{ - //判断包实例所在位置与当前用户所在科室是否一致 - if(!StringUtils.equals(currentOrgUnitCode, expensiveDisposablegoods.getLocation())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材所属科室为" + invoice.getDepart() + ",未配置与当前科室共用,不能录入使用记录!", barcode)); - return; - } - } - - Long disposableGoodsBatchId = expensiveDisposablegoods.getDisposableGoodsBatchID(); - if(disposableGoodsBatchId == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材数据异常,批次定义id为空", barcode)); - return; - } - DisposableGoodsBatch batch = diposableGoodsManager.getDisposableGoodsBatchById(disposableGoodsBatchId); - if(batch == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材批次定义已被删除", barcode)); - return; - } - - //扫描时判断该高值耗材是否已录过使用记录(即在UseDisposableGoodsItem表存中,按barcode查询),保存时也要校验,防止多人同时操作同一条码。普通物品暂不用校验 - if(CollectionUtils.isNotEmpty(useRecordManager.getUseDiposableGoodsItemList(barcode))){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的高值耗材已被使用,不能重复添加", barcode)); - return; - } - - obj.put("barcode", bd.getBarcode()); - obj.put("showTousseName", CssdUtils.getDiposableGoodsName(batch.getDiposableGoods())); - obj.put("batchNo", batch.getBatchNumber()); - obj.put("validUntil", batch.getExpDateStr()); - obj.put("tousseType", TousseItem.TYPE_DIPOSABLE_GOODS); - obj.put("goodsType", DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS); - } else if (bd instanceof DisposableGoodsBatch) { - DisposableGoodsBatch batch = (DisposableGoodsBatch) bd; - DisposableGoods disposableGoods = batch.getDiposableGoods(); - if(disposableGoods == null){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的一次性物品定义已被删除", barcode)); - return; - } - if(DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS.equals(disposableGoods.getGoodsType())){ - obj.put("success", false); - obj.put("error", String.format("条码为[%s]的一次性物品为高值耗材,只能扫描高值耗材的条码", barcode)); - return; - } - obj.put("barcode", batch.getBarcode()); - obj.put("showTousseName", CssdUtils.getDiposableGoodsName(batch.getDiposableGoods())); - obj.put("batchNo", batch.getBatchNumber()); - obj.put("validUntil", batch.getExpDateStr()); - obj.put("tousseType", TousseItem.TYPE_DIPOSABLE_GOODS); - } - }else{ - obj.put("success", false); - obj.put("error", "条码" + barcode + "为无效条码!"); - } - }else{ - obj.put("success", false); - obj.put("error", "条码不能为空!"); - } + obj = useRecordManager.loadBarcode(barcode, scanedBarcodes, currentOrgUnitCode); }finally{ StrutsResponseUtils.output(obj); } Index: ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/service/ServiceManagerImpl.java =================================================================== diff -u -r19560 -r19583 --- ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/service/ServiceManagerImpl.java (.../ServiceManagerImpl.java) (revision 19560) +++ ssts-webservice/src/main/java/com/forgon/disinfectsystem/webservice/service/ServiceManagerImpl.java (.../ServiceManagerImpl.java) (revision 19583) @@ -1451,6 +1451,7 @@ } // 在使用记录模块的上下文,根据条码获取信息 + @SuppressWarnings("unchecked") public String getInfoByBarcode_UseRecord(JSONObject params) { String barcode = params.optString("barcode"); String departCode = params.optString("departCode"); @@ -1490,95 +1491,18 @@ return JSONUtil.buildErrorMsgJsonResult("请扫描器械包条码或者诊疗号或者住院号"); } // ***验证器械包*** - TousseInstance tousseInstance = (TousseInstance) barcodeDevice; - // 暂不支持登记除普通器械包以外的包 - /*if (!TousseDefinition.PACKAGE_TYPE_INSIDE.equals(tousseInstance - .getTousseDefinition().getTousseType())) { - return JSONUtil.buildErrorMsgJsonResult("暂不支持登记除普通器械包以外的包"); - }*/ - // 1.判断是否为聚合包内的普通包实例,如果是则提示该包不能录入使用记录 - if(DatabaseUtil.isPoIdValid(tousseInstance.getComboTousseInstanceId())){ - return JSONUtil.buildJsonObject(false, "条码为" + barcode + "的包属于聚合包内的器械包,不能录入使用记录").toString(); - } - - // 2.判断是否为聚合包,如果是,则需要验证所录入的使用记录次数是否大于其包内普通包实例个数 - if(tousseInstance.isComboTousse()){ - int useTimes = objectDao.countBySql("select count(0) from TousseInstanceUseRecord where tousseInstanceId=" + tousseInstance.getId()); - List tousseInstanceList = tousseInstance.getTousseInstancesBelongToThisComboTousse(objectDao); - int size = CollectionUtils.isNotEmpty(tousseInstanceList) ? tousseInstanceList.size() : 0; - if(useTimes >= size){ - return JSONUtil.buildJsonObject(false, "条码为" + barcode + "的聚合包使用次数已经达到其包内器械包的数量,不能再录入").toString(); - } - - // 如果有签收时间则还原为签收状态,否则还原为器械包实例“已发货”状态,便于继续录使用记录 - if (tousseInstance.getSignedDate() != null) { - tousseInstance.setStatus(TousseInstance.STATUS_SIGNED); - }else{ - tousseInstance.setStatus(TousseInstance.STATUS_SHIPPED); - } - } - // 验证所在科室 - if (!StringUtils.equals(tousseInstance.getLocation(), departCode)) { - return JSONUtil.buildErrorMsgJsonResult("该器械包不属于本科室"); - } - // 只能登记已发货的器械包 - if (TousseInstance.STATUS_USED.equals(tousseInstance.getStatus())) { - return JSONUtil.buildErrorMsgJsonResult("器械包已使用,不能重复登记"); - }else if (TousseInstance.STATUS_RETURNED.equals(tousseInstance.getStatus())) { - return JSONUtil.buildErrorMsgJsonResult("器械包已退货,不能登记"); - }else if (TousseInstance.STATUS_WAIT_FOR_RECALL.equals(tousseInstance.getStatus()) - || TousseInstance.STATUS_RECALLED.equals(tousseInstance.getStatus())) { - return JSONUtil.buildErrorMsgJsonResult("该器械包不能被使用,已被召回!"); - } else if(!tousseInstance.canUse()){ - return JSONUtil.buildErrorMsgJsonResult("该器械包状态为" + tousseInstance.getStatus() + ",不能录入使用记录!"); - } -// if (!TousseInstance.STATUS_SHIPPED.equals(tousseInstance.getStatus()) -// && !TousseInstance.STATUS_SIGNED.equals(tousseInstance.getStatus())) { -// return JSONUtil.buildErrorMsgJsonResult("器械包未发货,不能登记"); -// } - // 验证是否过期 - Date validUntil = tousseInstance.getValidUntil(); - if (validUntil == null) { - return JSONUtil.buildErrorMsgJsonResult("器械包无失效日期,不能登记"); - } - if (validUntil.before(new Date())) { - return JSONUtil.buildErrorMsgJsonResult("器械包已过期,不能登记"); - } - // 检测当前器械包有没有被召回 -// if (tousseInstanceManager -// .checkTousseInstanceHasRecallByTousseInstanceId(tousseInstance -// .getId())) { -// return JSONUtil.buildErrorMsgJsonResult("器械包已被召回,不能登记"); -// } - - List acceptStatus = new ArrayList<>(); - boolean notSignedItemsCanRegistUseRecord = CssdUtils.getSystemSetConfigByNameBool("notSignedItemsCanRegistUseRecord"); - if(notSignedItemsCanRegistUseRecord){ - acceptStatus.add(TousseInstance.STATUS_SHIPPED); - } - acceptStatus.add(TousseInstance.STATUS_SIGNED); + //已经扫描了的包条码需要传回来 + String scanedBarcodes = null; JSONObject extraParam = params.optJSONObject("extraParam"); - Object barcodeCol = null; + Collection barcodeCol = null; if(extraParam != null){ JSONArray tousseInstanceBarcodeJsonArray = extraParam.getJSONArray("scanedBarcodes"); if(CollectionUtils.isNotEmpty(tousseInstanceBarcodeJsonArray)){ barcodeCol = JSONArray.toCollection(tousseInstanceBarcodeJsonArray, String.class); + scanedBarcodes = StringUtils.join(barcodeCol, ","); } } - - TousseInstance older = tousseInstanceManager.getExpireNearest(tousseInstance, acceptStatus,(Collection)barcodeCol); - JSONObject olderJson = new JSONObject(); - if(older != null){ - olderJson.put("barcode", older.getBarcode()); - olderJson.put("tousseName", older.getTousseDefinitionName()); - } - JSONObject dataJson = JSONObject.fromObject(tousseInstance, - buildJsonConfigForTousseInstance()); - JSONObject json = JSONUtil.buildJsonObject(true); - json.put("type", "tousseInstance"); - json.put("data", dataJson); - json.put("older", olderJson); - json.put("olderTousseComfirmForUserecord", CssdUtils.getSystemSetConfigByNameBool("olderTousseComfirmForUserecord")); + JSONObject json = useRecordManager.loadBarcode(barcode, scanedBarcodes, AcegiHelper.getCurrentOrgUnitCode()); return json.toString(); } Index: ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManager.java =================================================================== diff -u -r18072 -r19583 --- ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManager.java (.../UseRecordManager.java) (revision 18072) +++ ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManager.java (.../UseRecordManager.java) (revision 19583) @@ -5,6 +5,8 @@ import java.util.List; import java.util.Map; +import net.sf.json.JSONObject; + import com.forgon.disinfectsystem.entity.invoicemanager.Invoice; import com.forgon.disinfectsystem.entity.useRecord.UseDiposableGoodsItem; import com.forgon.disinfectsystem.entity.useRecord.UseRecord; @@ -232,4 +234,13 @@ * @return */ public Invoice getInvoiceById(Long id); + + /** + * 录使用记录时扫描物品条码 + * @param barcode 条码(可能是器械包、一次性物品、高值耗材等条码) + * @param scanedBarcodes 页面上已经有的条码 + * @param currentOrgUnitCode 科室编码(通常为当前用户所属科室条码) + * @return JSONObject + */ + public JSONObject loadBarcode(String barcode, String scanedBarcodes,String currentOrgUnitCode); } Index: ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManagerImpl.java =================================================================== diff -u -r19561 -r19583 --- ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManagerImpl.java (.../UseRecordManagerImpl.java) (revision 19561) +++ ssts-userecord/src/main/java/com/forgon/disinfectsystem/useRecord/service/UseRecordManagerImpl.java (.../UseRecordManagerImpl.java) (revision 19583) @@ -4,6 +4,7 @@ import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -15,11 +16,15 @@ import net.sf.json.JSONArray; import net.sf.json.JSONObject; +import net.sf.json.JsonConfig; +import net.sf.json.util.PropertyFilter; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.collections4.Predicate; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.log4j.Logger; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -32,10 +37,14 @@ import com.forgon.directory.model.OrgUnit; import com.forgon.directory.vo.LoginUserData; import com.forgon.disinfectsystem.barcode.service.BarcodeManager; +import com.forgon.disinfectsystem.basedatamanager.goodsdepartshareconfig.service.GoodsDepartShareConfigManager; import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; import com.forgon.disinfectsystem.common.CssdUtils; import com.forgon.disinfectsystem.datasynchronization.model.PatientInfoVO; import com.forgon.disinfectsystem.datasynchronization.service.DataSynchronizationManager; +import com.forgon.disinfectsystem.diposablegoods.service.DiposableGoodsManager; +import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoods; +import com.forgon.disinfectsystem.entity.assestmanagement.DisposableGoodsBatch; import com.forgon.disinfectsystem.entity.assestmanagement.ExpensiveDisposablegoods; import com.forgon.disinfectsystem.entity.basedatamanager.materialdefinition.MaterialDefinition; import com.forgon.disinfectsystem.entity.basedatamanager.supplyroomconfig.SupplyRoomConfig; @@ -62,12 +71,14 @@ import com.forgon.disinfectsystem.tousseitem.service.TousseItemManager; import com.forgon.disinfectsystem.toussetransition.service.TousseTransitionPlanItemManager; import com.forgon.disinfectsystem.toussetransition.service.TousseTransitionPlanManager; +import com.forgon.disinfectsystem.vo.TousseSimpleVO; import com.forgon.disinfectsystem.vo.UseMaterialGoodsItem; import com.forgon.log.model.Log; import com.forgon.log.service.LogManager; import com.forgon.tools.MathTools; import com.forgon.tools.db.DatabaseUtil; import com.forgon.tools.hibernate.ObjectDao; +import com.forgon.tools.json.DateJsonValueProcessor; import com.forgon.tools.json.JSONUtil; import com.forgon.tools.string.StringTools; @@ -110,7 +121,20 @@ private LogManager appLogManager; private TousseInstanceUseRecordManager tousseInstanceUseRecordManager; + + private DiposableGoodsManager diposableGoodsManager; + + private GoodsDepartShareConfigManager goodsDepartShareConfigManager; + + public void setDiposableGoodsManager(DiposableGoodsManager diposableGoodsManager) { + this.diposableGoodsManager = diposableGoodsManager; + } + public void setGoodsDepartShareConfigManager( + GoodsDepartShareConfigManager goodsDepartShareConfigManager) { + this.goodsDepartShareConfigManager = goodsDepartShareConfigManager; + } + public void setTousseInstanceUseRecordManager( TousseInstanceUseRecordManager tousseInstanceUseRecordManager) { this.tousseInstanceUseRecordManager = tousseInstanceUseRecordManager; @@ -3502,6 +3526,7 @@ * @param barcode * @return */ + @Override public List getUseDiposableGoodsItemList(String barcode){ return objectDao.findBySql(UseDiposableGoodsItem.class.getSimpleName(), " where barcode = '" + barcode + "'"); } @@ -3512,7 +3537,364 @@ * @param id * @return */ + @Override public Invoice getInvoiceById(Long id){ return (Invoice)objectDao.getBySql(Invoice.class.getSimpleName(), " where id=" + id); } + + @Override + public JSONObject loadBarcode(String barcode, String scanedBarcodes, + String currentOrgUnitCode) { + JSONObject obj = new JSONObject(); + try { + obj.put("success", true); + if (StringUtils.isNotBlank(barcode)) { + BarcodeDevice bd = barcodeManager.getBarcodeByBarcode(barcode); + if (bd != null) { + //检测器械包所属科室是否与当前用户所在科室为物品共用科室 + + if (bd instanceof TousseInstance) { + TousseInstance ti = (TousseInstance) bd; + + //判断该条码的包实例是否为固定条码包实例(如果为固定条码则找出该包定义符合录使用记录条件的且失效期还未过且最早失效的包实例) + if(ti.getTousseFixedBarcode()){ + ti = getTousseInstanceForUseRecord(ti.getTousseDefinition(), scanedBarcodes, currentOrgUnitCode); + if(ti == null){ + obj.put("success", false); + obj.put("error", "未找到符合录入使用记录条件的包"); + return obj; + } + } + + // 1.判断是否为聚合包内的普通包实例,如果是则提示该包不能录入使用记录 + if(DatabaseUtil.isPoIdValid(ti.getComboTousseInstanceId())){ + obj.put("success", false); + obj.put("error", "条码为" + barcode + "的包属于聚合包内的器械包,不能录入使用记录"); + return obj; + } + + // 2.判断是否为聚合包,如果是,则需要验证所录入的使用记录次数是否大于其包内普通包实例个数 + if(ti.isComboTousse()){ + int useTimes = objectDao.countBySql("select count(0) from TousseInstanceUseRecord where tousseInstanceId=" + ti.getId()); + List tousseInstanceList = ti.getTousseInstancesBelongToThisComboTousse(objectDao); + int size = CollectionUtils.isNotEmpty(tousseInstanceList) ? tousseInstanceList.size() : 0; + if(useTimes >= size){ + obj.put("success", false); + obj.put("error", "条码为" + barcode + "的聚合包使用次数已经达到其包内器械包的数量,不能再录入"); + return obj; + } + + // 如果有签收时间则还原为签收状态,否则还原为器械包实例“已发货”状态,便于继续录使用记录 + if (ti.getSignedDate() != null) { + ti.setStatus(TousseInstance.STATUS_SIGNED); + } else { + ti.setStatus(TousseInstance.STATUS_SHIPPED); + } + } + + // 3.检测该器械包有没有被召回 + if (TousseInstance.STATUS_WAIT_FOR_RECALL.equals(ti.getStatus()) || TousseInstance.STATUS_RECALLED.equals(ti.getStatus())) { + obj.put("msg", "该器械包不能被使用,已被召回!"); + } else if(!TousseInstance.STATUS_SHIPPED.equals(ti.getStatus()) && !TousseInstance.STATUS_SIGNED.equals(ti.getStatus())){ + obj.put("msg", "该器械包状态为" + ti.getStatus() + ",不能录入使用记录!"); + } else { + List acceptStatus = new ArrayList<>(); + //已发货未签收的包是否可以录使用记录 + boolean notSignedItemsCanRegistUseRecord = CssdUtils.getSystemSetConfigByNameBool("notSignedItemsCanRegistUseRecord"); + if(notSignedItemsCanRegistUseRecord){ + acceptStatus.add(TousseInstance.STATUS_SHIPPED); + } + acceptStatus.add(TousseInstance.STATUS_SIGNED); + TousseInstance older = tousseInstanceManager.getExpireNearest(ti, acceptStatus,StringTools.toCollectionIgnoreNullAndBlank(scanedBarcodes)); + TousseDefinition td = ti.getTousseDefinition(); + //判断当前用户登录科室是否存在共用科室配置 + if(CollectionUtils.isNotEmpty(goodsDepartShareConfigManager.getGoodsShareDepartList(currentOrgUnitCode))){ + //判断包实例所属科室是否与当前用户登录科室配置物品共享 + if(goodsDepartShareConfigManager.canShareGoodsforTwoDepart(currentOrgUnitCode, ti.getLocation())){ + String validUntilStr = ti.getValidUntilStr(Constants.SIMPLEDATEFORMAT_YYYYMMDD); + String tousseDefinitionName = ""; + String tousseType = ""; + String includeImplant = ""; + if (td != null) { + tousseType = td.getTousseType(); + tousseDefinitionName = td.getName(); + includeImplant = td.getIncludeImplantStr(); + } + obj.put("id", ti.getId()); + obj.put("barcode", ti.getBarcode()); + obj.put("tousseDefinitionName", tousseDefinitionName); + obj.put("showTousseName", ti.getShowTousseName()); + obj.put("packageType", ti.getPackageType()); + obj.put("validUntil", validUntilStr); + obj.put("status", ti.getStatus()); + obj.put("location",ti.getLocation()); + obj.put("locationForDisplay",ti.getLocationForDisplay()); + obj.put("materials", null); + obj.put("foreignTousseApp_id",ti.getForeignTousseApp_id()); + obj.put("tousseType", tousseType); + obj.put("includeImplant", includeImplant); + obj.put("actualUsed", Constants.STR_YES); //扫描的时候,都取默认值,为是。以免录了使用记录之后,又删除了,就把包实例这个属性修改了,再扫描,就不是默认的值了 + obj.put("haveUnSupplementMaterials", BooleanUtils.toBooleanDefaultIfNull(ti.getHaveUnSupplementMaterials(), false)); + + //是否回收 + obj.put("isRecycling", td.getIsRecycling()); + //是否转换申请单 + obj.put("isConvertApplyGoods", td.getIsConvertApplyGoods()); + }else{ + obj.put("msg", "该器械包所属科室为" + ti.getLocationForDisplay() + ",未配置与当前科室共用,不能录入使用记录!"); + } + }else{ + //判断包实例所在位置与当前用户所在科室是否一致 + if(StringUtils.equals(currentOrgUnitCode, ti.getLocation())){ + String validUntilStr = ti.getValidUntilStr(Constants.SIMPLEDATEFORMAT_YYYYMMDD); + String tousseDefinitionName = ""; + String tousseType = ""; + String includeImplant = ""; + if (td != null) { + tousseType = td.getTousseType(); + tousseDefinitionName = td.getName(); + includeImplant = td.getIncludeImplantStr(); + } + obj.put("id", ti.getId()); + obj.put("barcode", ti.getBarcode()); + obj.put("tousseDefinitionName", tousseDefinitionName); + obj.put("showTousseName", ti.getShowTousseName()); + obj.put("packageType", ti.getPackageType()); + obj.put("validUntil", validUntilStr); + obj.put("status", ti.getStatus()); + obj.put("location",ti.getLocation()); + obj.put("locationForDisplay",ti.getLocationForDisplay()); + obj.put("materials", null); + obj.put("foreignTousseApp_id",ti.getForeignTousseApp_id()); + obj.put("tousseType", tousseType); + obj.put("includeImplant", includeImplant); + obj.put("actualUsed", Constants.STR_YES); + obj.put("haveUnSupplementMaterials", BooleanUtils.toBooleanDefaultIfNull(ti.getHaveUnSupplementMaterials(), false)); + + //是否回收 + obj.put("isRecycling", td.getIsRecycling()); + //是否转换申请单 + obj.put("isConvertApplyGoods", td.getIsConvertApplyGoods()); + }else{ + obj.put("msg", "该器械包所属科室为" + ti.getLocationForDisplay() + ",不能录入使用记录!"); + } + } + // 使用次数 +// Long idCardInstanceId = ti.getIdCardInstanceID(); +// if(idCardInstanceId != null){ +// IDCardDefinition idCardDefinition = IDCardDefinitionUtils.getIDCardDefinitionsByIdCardInstanceId(objectDao, idCardInstanceId); +// if(idCardDefinition != null){ +// obj.put("idCardUseAmount", idCardDefinition.getUseAmount()); +// } +// } + obj.put("idCardUseAmount", ti.getUseAmount()); + if(older != null){ + JSONObject json = new JSONObject(); + json.put("barcode", older.getBarcode()); + json.put("tousseName", older.getTousseDefinitionName()); + obj.put("older", json); + } + //pda需要用到以下两个属性 + obj.put("type", "tousseInstance"); + JSONObject dataJson = JSONObject.fromObject(ti, + buildJsonConfigForTousseInstance()); + obj.put("data", dataJson); + } + } else if (bd instanceof ExpensiveDisposablegoods) { + // 高值耗材 + ExpensiveDisposablegoods expensiveDisposablegoods = (ExpensiveDisposablegoods) bd; + if(!ExpensiveDisposablegoods.STATUS_DELIVERED.equals(expensiveDisposablegoods.getStatus())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材状态为%s,不能录使用记录", barcode,expensiveDisposablegoods.getStatus())); + return obj; + } + + //判断该高值耗材关联的一次性物品定义的物品类型是否为高值耗材(防止入库时定义为高值耗材,后来修改定义为非高值耗材) + if(expensiveDisposablegoods.getDisposableGoodsID() == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材未找到一次性物品定义", barcode)); + return obj; + } + DisposableGoods disposableGoods = + diposableGoodsManager.get(expensiveDisposablegoods.getDisposableGoodsID()); + if(disposableGoods == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材一次性物品定义已被删除", barcode)); + return obj; + } + + if(!DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS.equals(disposableGoods.getGoodsType())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材对应一次性物品不为高值耗材", barcode)); + return obj; + } + + //需要判断发货单是否存在且发货科室与当前登录用户是否为同一个科室,否则给予提示 + Long invoiceId = expensiveDisposablegoods.getInvoiceId(); + if(invoiceId == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材发货单已被删除", barcode)); + return obj; + } + + Invoice invoice = getInvoiceById(invoiceId); + if(invoice == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材发货单已被删除", barcode)); + return obj; + } + + /*if(!StringUtils.equals(invoice.getDepart(), AcegiHelper.getLoginUser().getCurrentOrgUnitName())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材所属科室与当前登录用户所属科室不一致", barcode)); + return; + }*/ + //判断当前用户登录科室是否存在共用科室配置 + if(CollectionUtils.isNotEmpty(goodsDepartShareConfigManager.getGoodsShareDepartList(currentOrgUnitCode))){ + //判断包实例所属科室是否与当前用户登录科室配置物品共享 + if(!goodsDepartShareConfigManager.canShareGoodsforTwoDepart(currentOrgUnitCode, expensiveDisposablegoods.getLocation())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材所属科室为" + invoice.getDepart() + ",未配置与当前科室共用,不能录入使用记录!", barcode)); + return obj; + } + }else{ + //判断包实例所在位置与当前用户所在科室是否一致 + if(!StringUtils.equals(currentOrgUnitCode, expensiveDisposablegoods.getLocation())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材所属科室为" + invoice.getDepart() + ",未配置与当前科室共用,不能录入使用记录!", barcode)); + return obj; + } + } + + Long disposableGoodsBatchId = expensiveDisposablegoods.getDisposableGoodsBatchID(); + if(disposableGoodsBatchId == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材数据异常,批次定义id为空", barcode)); + return obj; + } + DisposableGoodsBatch batch = diposableGoodsManager.getDisposableGoodsBatchById(disposableGoodsBatchId); + if(batch == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材批次定义已被删除", barcode)); + return obj; + } + + //扫描时判断该高值耗材是否已录过使用记录(即在UseDisposableGoodsItem表存中,按barcode查询),保存时也要校验,防止多人同时操作同一条码。普通物品暂不用校验 + if(CollectionUtils.isNotEmpty(getUseDiposableGoodsItemList(barcode))){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的高值耗材已被使用,不能重复添加", barcode)); + return obj; + } + + obj.put("barcode", bd.getBarcode()); + obj.put("showTousseName", CssdUtils.getDiposableGoodsName(batch.getDiposableGoods())); + obj.put("batchNo", batch.getBatchNumber()); + obj.put("validUntil", batch.getExpDateStr()); + obj.put("tousseType", TousseItem.TYPE_DIPOSABLE_GOODS); + obj.put("goodsType", DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS); + } else if (bd instanceof DisposableGoodsBatch) { + DisposableGoodsBatch batch = (DisposableGoodsBatch) bd; + DisposableGoods disposableGoods = batch.getDiposableGoods(); + if(disposableGoods == null){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的一次性物品定义已被删除", barcode)); + return obj; + } + if(DisposableGoods.TYPE_EXPENSIVEDIPOSABLEGOODS.equals(disposableGoods.getGoodsType())){ + obj.put("success", false); + obj.put("error", String.format("条码为[%s]的一次性物品为高值耗材,只能扫描高值耗材的条码", barcode)); + return obj; + } + obj.put("barcode", batch.getBarcode()); + obj.put("showTousseName", CssdUtils.getDiposableGoodsName(batch.getDiposableGoods())); + obj.put("batchNo", batch.getBatchNumber()); + obj.put("validUntil", batch.getExpDateStr()); + obj.put("tousseType", TousseItem.TYPE_DIPOSABLE_GOODS); + } + }else{ + obj.put("success", false); + obj.put("error", "条码" + barcode + "为无效条码!"); + } + }else{ + obj.put("success", false); + obj.put("error", "条码不能为空!"); + } + }catch(Exception e){ + + } + obj.put("olderTousseComfirmForUserecord", CssdUtils.getSystemSetConfigByNameBool("olderTousseComfirmForUserecord")); + return obj; + } + + private static JsonConfig buildJsonConfigForTousseInstance() { + JsonConfig config = new JsonConfig(); + config.registerJsonValueProcessor(Date.class, + new DateJsonValueProcessor("yyyy-MM-dd")); + final String[] retainPropertys = { "id", "tousseDefinition", + "tousseName", "barcode", "validUntil", "sterilingType", + "orgUnitCoding", "orgUnitName","sterilizerPosition","actualUsed" }; + PropertyFilter filter = new PropertyFilter() { + @Override + public boolean apply(Object source, String name, Object value) { + // 返回 true, 表示这个属性将被过滤掉 + // 返回 false, 表示这个属性将被保留 + + Class clazz = source.getClass(); + + if (clazz == TousseDefinition.class) { + String[] retainPropertys = { "name" }; + if (ArrayUtils.contains(retainPropertys, name)) { + return false; + } + } else if (clazz == TousseInstance.class) { + + if (ArrayUtils.contains(retainPropertys, name)) { + return false; + } + } else if (clazz == TousseSimpleVO.class) { + if (ArrayUtils.contains(retainPropertys, name)) { + return false; + } + } + return true; + } + }; + config.setJsonPropertyFilter(filter); + return config; + } + + /** + * 根据包定义、已扫描到的条码(进行排除)、科室编码等查询最近一个未过期却将最早过期的包实例(有多个符合录使用记录条件但失效期相同的话取id最小的那个)用于录入使用记录 + * 查询过滤条件包括 1.器械包所在位置为当前科室 2.未过期 3.指定包定义下的包 4.状态为已签收(也可有包含已发货,具体根据配置情况) + * @param td 包定义 + * @param scanedBarcodes 已经扫描了的条码(用于查询时进行排除) + * @param currentOrgUnitCode 科室编码(用于按器械包所在位置进行过滤) + * @return + */ + private TousseInstance getTousseInstanceForUseRecord(TousseDefinition td,String scanedBarcodes, + String currentOrgUnitCode){ + String sql = "where location = '"+ currentOrgUnitCode +"' and validUntil > " + dateQueryAdapter.dateAdapter(new Date()); + //如果已扫描的条码不为空的话,需要排除 + if(StringUtils.isNotBlank(scanedBarcodes)){ + List scanedBarcodeList = Arrays.asList(scanedBarcodes.split(",")); + for(String scanedBarcode : scanedBarcodeList){ + scanedBarcode = "'" + scanedBarcode + "'"; + } + sql += " and barcode not in ("+ StringUtils.join(scanedBarcodeList, ",") +") "; + } + if(td.isDisinfection() || td.isForeignProxyTousse()){ + sql += " and tousseDefinition.ancestorID = " + td.getId(); + }else{ + sql += " and tousseDefinition.id = " + td.getId(); + } + String statusCondition = "'"+ TousseInstance.STATUS_SIGNED +"'"; + //已发货未签收的包是否可以录使用记录 + boolean notSignedItemsCanRegistUseRecord = CssdUtils.getSystemSetConfigByNameBool("notSignedItemsCanRegistUseRecord"); + if(notSignedItemsCanRegistUseRecord){ + statusCondition = ",'"+ TousseInstance.STATUS_SHIPPED +"'"; + } + sql += " and status in ("+ statusCondition +")"; + sql += " order by validUntil "; + return (TousseInstance)objectDao.getBySql(TousseInstance.class.getSimpleName(), sql); + } }