Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java =================================================================== diff -u -r30141 -r30153 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java (.../RecyclingApplicationManagerImpl.java) (revision 30141) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java (.../RecyclingApplicationManagerImpl.java) (revision 30153) @@ -78,6 +78,8 @@ 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.becleanitem.ClassifiedItem; +import com.forgon.disinfectsystem.entity.becleanitem.ClassifyBasket; import com.forgon.disinfectsystem.entity.foreigntousseapplication.ForeignTousseApplication; import com.forgon.disinfectsystem.entity.goodsstock.GoodsStock; import com.forgon.disinfectsystem.entity.invoicemanager.Invoice; @@ -7156,29 +7158,37 @@ return result; } + @SuppressWarnings("unchecked") @Override public void interfereInvoicePlan(String resultStr) { if(StringUtils.isNotBlank(resultStr)){ try { JSONObject result = JSONObject.fromObject(resultStr); String soureceId = result.getString("invoicePlanId"); + String depart = result.getString("depart"); + String departCoding = result.getString("departCoding"); + String settleAccountsDepart = result.getString("settleAccountsDepart"); + String settleAccountsDepartCoding = result.getString("settleAccountsDepartCoding"); + String remark = result.getString("remark"); RecyclingApplication oldPlan = getRecyclingApplicationById(soureceId); if (oldPlan != null) { - if (!InvoicePlan.RECYCLINGSTATUS_AWAITRECYCLE + if (InvoicePlan.RECYCLINGSTATUS_PARTRECYCLE .equals(oldPlan.getRecyclingStatus())) { - throw new RuntimeException("该申请单已回收!"); + throw new RuntimeException("单上存在部分回收的物品,不支持拆单!"); } if (!InvoicePlan.DELIVERSTATUS_AWAITDELIVER.equals(oldPlan .getDeliverStatus())) { - throw new RuntimeException("该申请单已发货!"); + throw new RuntimeException("单上的物品已经发货,不支持拆单!"); } if (StringUtils.isNotBlank(oldPlan.getEndStatus())) { throw new RuntimeException("该申请单已终止"); } if (!oldPlan.getCommittedStatus()) { throw new RuntimeException("该申请单未提交!"); } - if (InvoicePlan.TYPE_COMBO_FORM.equals(oldPlan.getType())) { + if (InvoicePlan.TYPE_COMBO_FORM.equals(oldPlan.getType()) + || InvoicePlan.TYPE_TOUSSE_APPLICATION_FORM.equals(oldPlan.getType()) + || InvoicePlan.TYPE_RECYCLINGCREATE_APPLICATION.equals(oldPlan.getType())) { String handleDepartCode = result.optString("newAppHandleDepartCode"); @@ -7198,14 +7208,39 @@ oldPlan.setHandleDepart(node.getName()); oldPlan.setHandleDepartCoding(handleDepartCode); - saveOrUpdate(oldPlan); + oldPlan.setDepart(depart); + oldPlan.setDepartCoding(departCoding); + oldPlan.setSettleAccountsDepart(settleAccountsDepart); + oldPlan.setSettleAccountsDepartCoding(settleAccountsDepartCoding); + oldPlan.setRemark(remark); + + if(InvoicePlan.RECYCLINGSTATUS_RECYCLED + .equals(oldPlan.getRecyclingStatus())){ + RecyclingRecord recyclingRecord = oldPlan.getRecyclingRecord(objectDao); + recyclingRecord.setDepart(depart); + recyclingRecord.setDepartCode(departCoding); + // 修改装配任务 + String packingTaskSql = String.format("update %s set departCoding = '%s', Department = '%s', settleAccountsDepartCoding = '%s' " + + " where (sourceId = %s and taskType = %s) or (sourceId = %s and taskType = %s) ", + PackingTask.class.getSimpleName(), departCoding, depart, + settleAccountsDepartCoding, recyclingRecord.getId(), PackingTask.TASK_RECYCLINGRECORD, + recyclingRecord.getRecyclingApplication().getId(), PackingTask.TASK_APPLICATION); + objectDao.excuteSQL(packingTaskSql); + // 修改包实例 + String sql = " where po.invoicePlanID = " + oldPlan.getId(); + List tousseList = objectDao.findBySql(TousseInstance.class.getSimpleName(), sql); + for (TousseInstance tousseInstance : tousseList) { + tousseInstance.setDepart(oldPlan.getDepart()); + tousseInstance.setDepartCoding(oldPlan.getDepartCoding()); + tousseInstance.setSettleAccountsDepartCode(oldPlan.getSettleAccountsDepartCoding()); + } + } } String description = ""; if(!isOnlyUpdateHandleDepart){ - saveRecyclingApplication(oldPlan, oldItemVos, true); //新申请单 RecyclingApplication newApplicaiton = new RecyclingApplication(); try { @@ -7221,6 +7256,11 @@ newApplicaiton.setApplicationItems(null); newApplicaiton.setHandleDepart(node.getName()); newApplicaiton.setHandleDepartCoding(handleDepartCode); + newApplicaiton.setDepart(depart); + newApplicaiton.setDepartCoding(departCoding); + newApplicaiton.setSettleAccountsDepart(settleAccountsDepart); + newApplicaiton.setSettleAccountsDepartCoding(settleAccountsDepartCoding); + newApplicaiton.setRemark(remark); newApplicaiton.setInvoice(null); newApplicaiton.setRecyclingApplications(null); @@ -7235,11 +7275,26 @@ saveRecyclingApplication(newApplicaiton, newItemVos, true); + if(InvoicePlan.RECYCLINGSTATUS_AWAITRECYCLE + .equals(oldPlan.getRecyclingStatus())){ + // 待回收的申请单直接修改旧单上的物品 + saveRecyclingApplication(oldPlan, oldItemVos, true); + }else{ + splitApplication(oldPlan, newItemVos, newApplicaiton); + updateOldRecyclingApplication(oldPlan, oldItemVos); + } + + if(StringUtils.equals(newApplicaiton.getType(), InvoicePlan.TYPE_RECYCLINGCREATE_APPLICATION)){ + for (TousseItem tousseItem : newApplicaiton.getApplicationItems()) { + tousseItem.setAmount(0); + } + } + description = "申请单干预,流水号为" + oldPlan.getSerialNumber() + "的申请被拆分,拆分的子单号为:" + newApplicaiton.getSerialNumber(); }else{ description = "申请单干预,流水号为" + oldPlan.getSerialNumber() - + "的申请修改了处理科室"; + + "的申请修改了申请科室"; } LoginUserData loginUser = AcegiHelper.getLoginUser(); @@ -7257,6 +7312,336 @@ } } + /** + * 修改旧的申请单 + * @param oldPlan + * @param oldItemVos + */ + private void updateOldRecyclingApplication(RecyclingApplication oldPlan, Collection oldItemVos) { + List items = oldPlan.getApplicationItems(); + List delItems = new ArrayList(); + delItems.addAll(items); + for (TousseItem tousseItem : items) { + for (TousseItemVo tousseItemVo : oldItemVos) { + if(tousseItemVo.getTousseDefinitionID().longValue() == tousseItem.getTousseDefinitionId().longValue()){ + delItems.remove(tousseItem); + if(tousseItem.getAmount().intValue() == tousseItemVo.getAmount().intValue()){ + break; + } + tousseItem.setAmount(tousseItemVo.getAmount()); + tousseItem.setRecyclingAmount(tousseItemVo.getAmount()); + break; + } + } + } + for (TousseItem tousseItem : delItems) { + tousseItem.setInvoicePlan(null); + objectDao.delete(tousseItem); + } + items.removeAll(delItems); + if(StringUtils.equals(oldPlan.getType(), InvoicePlan.TYPE_RECYCLINGCREATE_APPLICATION)){ + for (TousseItem tousseItem : items) { + tousseItem.setAmount(0); + } + } + objectDao.saveOrUpdate(oldPlan); + } + + /** + * 从旧申请单上拆分物品; + * 新申请单生成回收记录; + * @param oldRecyclingApplication + * @param splitedItemVos + */ + private void splitApplication(RecyclingApplication oldRecyclingApplication, Collection splitedItemVos, RecyclingApplication newRecyclingApplication) { + if(CollectionUtils.isEmpty(splitedItemVos)){ + return; + } + + for (TousseItemVo tousseItemVo : splitedItemVos) { + if(StringUtils.equals(tousseItemVo.getDiposable(), com.forgon.Constants.STR_YES)){ + throw new SystemException("一次性物品暂不支持拆单!"); + } + if(StringUtils.equals(tousseItemVo.getTousseType(), TousseDefinition.PACKAGE_TYPE_DISINFECTION)){ + throw new SystemException("消毒物品不支持拆单!"); + } + } + + RecyclingRecord oldRecyclingRecord = oldRecyclingApplication.getRecyclingRecord(objectDao); + List oldClassifyBaskets = oldRecyclingRecord.getClassifyBaskets(); + // 拆分旧单篮筐内物品 + List items = new ArrayList(); + List splitItems = new ArrayList(); + if(CollectionUtils.isNotEmpty(oldClassifyBaskets)){ + for (ClassifyBasket basket : oldClassifyBaskets) { + items.addAll(basket.getClassfiedItems()); + } + splitItems = splitClassifiedItem(items, splitedItemVos); + } + // 新单增加回收记录 + RecyclingRecord newRecyclingRecord = addRecyclingRecord(splitItems, newRecyclingApplication, oldRecyclingApplication, oldRecyclingRecord); + // 拆分旧申请单的回收记录 + splitRecyClingItems(splitedItemVos, newRecyclingRecord, oldRecyclingRecord); + // 拆分装配任务,待装配任务的所属科室名称、所属科室编码、sourceId字段记录了来源申请单或者回收记录的id,相关字段的值需要更新 + splitPackingTask(newRecyclingRecord, oldRecyclingRecord, splitedItemVos); + // 拆分包实例,包实例的来源申请单号、科室等属性要进行修改 + splitTousseInstance(newRecyclingApplication, oldRecyclingApplication, splitedItemVos); + } + + /** + * 拆分包实例 + * @param newPlan + * @param oldPlan + * @param splitedItemVos + */ + @SuppressWarnings("unchecked") + private void splitTousseInstance(RecyclingApplication newPlan, RecyclingApplication oldPlan, Collection splitedItemVos) { + + List tousseDefinitionIdList = new ArrayList(); + Map amountMap = new HashMap(); + Map itemMap = new HashMap(); + RecyclingRecord newRecyclingRecord = newPlan.getRecyclingRecord(objectDao); + List items = newRecyclingRecord.getItems(); + for (RecyclingItem recyclingItem : items) { + itemMap.put(recyclingItem.getTousseDefinitionId(), recyclingItem); + } + for (TousseItemVo tousseItemVo : splitedItemVos) { + tousseDefinitionIdList.add(tousseItemVo.getTousseDefinitionId()); + amountMap.put(tousseItemVo.getTousseDefinitionId(), tousseItemVo.getAmount()); + } + String sql = " where po.invoicePlanID = " + oldPlan.getId() + " and " + SqlUtils.getNonStringFieldInLargeCollectionsPredicate("po.tousseDefinition.id", tousseDefinitionIdList); + List tousseList = objectDao.findBySql(TousseInstance.class.getSimpleName(), sql); + if(CollectionUtils.isEmpty(tousseList)){ + return; + } + + for (TousseInstance tousseInstance : tousseList) { + TousseDefinition td = tousseInstance.getTousseDefinition(); + Integer amount = amountMap.get(td.getId()); + if(amount.intValue() > 0){ + tousseInstance.setDepart(newPlan.getDepart()); + tousseInstance.setDepartCoding(newPlan.getDepartCoding()); + tousseInstance.setSettleAccountsDepartCode(newPlan.getSettleAccountsDepartCoding()); + tousseInstance.setInvoicePlanID(newPlan.getId()); + tousseInstance.setInvoicePlanSerialNum(newPlan.getSerialNumber()); + tousseInstance.setRecyclingRecordId(newRecyclingRecord.getId()); + tousseInstance.setRecyclingItemId(itemMap.get(td.getId()).getId()); + amountMap.put(tousseInstance.getTousseDefinition().getId(), --amount); + } + } + } + + /** + * 拆分装配任务 + * @param newRecyclingRecord + * @param oldRecyclingRecord + * @param splitedItemVos + */ + @SuppressWarnings("unchecked") + private void splitPackingTask(RecyclingRecord newRecyclingRecord, RecyclingRecord oldRecyclingRecord, Collection splitedItemVos) { + String sql = "where (po.sourceId = " + oldRecyclingRecord.getId() + " and po.taskType = " + + PackingTask.TASK_RECYCLINGRECORD + ") " + + "or (po.sourceId = " + oldRecyclingRecord.getRecyclingApplication().getId() + " and po.taskType = " + + PackingTask.TASK_APPLICATION + ") "; + List packingTaskList = objectDao.findBySql(PackingTask.class.getSimpleName(), sql); + InvoicePlan newInvoicePlan = newRecyclingRecord.getRecyclingApplication(); + for (PackingTask packingTask : packingTaskList) { + if(packingTask.getAmount().intValue() != packingTask.getUnPackAmount().intValue()){ + throw new SystemException(packingTask.getTousseDefinition().getName() + "进行了部分装配,不允许拆单,请完成装配后再拆单!"); + } + for (TousseItemVo tousseItemVo : splitedItemVos) { + if(packingTask.getTousseDefinition().getId().longValue() == tousseItemVo.getTousseDefinitionId().longValue()){ + if(packingTask.getAmount().intValue() == tousseItemVo.getAmount().intValue()){ + packingTask.setSourceId(newRecyclingRecord.getId()); + packingTask.setDepartCoding(newRecyclingRecord.getDepartCode()); + packingTask.setDepartment(newRecyclingRecord.getDepart()); + packingTask.setSettleAccountsDepartCoding(newInvoicePlan.getSettleAccountsDepartCoding()); + }else{ + PackingTask newPackingTask = new PackingTask(); + try { + Integer amount = packingTask.getAmount() - tousseItemVo.getAmount(); + packingTask.setAmount(amount); + packingTask.setUnPackAmount(amount); + BeanUtils.copyProperties(newPackingTask, packingTask); + newPackingTask.setId(null); + newPackingTask.setAmount(tousseItemVo.getAmount()); + newPackingTask.setUnPackAmount(tousseItemVo.getAmount()); + newPackingTask.setSourceId(newRecyclingRecord.getId()); + newPackingTask.setDepartCoding(newRecyclingRecord.getDepartCode()); + newPackingTask.setDepartment(newRecyclingRecord.getDepart()); + newPackingTask.setSettleAccountsDepartCoding(newInvoicePlan.getSettleAccountsDepartCoding()); + objectDao.saveOrUpdate(newPackingTask); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + } + + /** + * 拆分旧申请单的回收记录 + * @param splitedItemVos + * @param newRecyclingRecord + * @param oldRecyclingRecord + */ + private void splitRecyClingItems(Collection splitedItemVos, RecyclingRecord newRecyclingRecord, RecyclingRecord oldRecyclingRecord) { + List oldItems = oldRecyclingRecord.getItems(); + List newItems = new ArrayList(); + for (RecyclingItem recyclingItem : oldItems) { + for (TousseItemVo tousseItemVo : splitedItemVos) { + if(recyclingItem.getTousseDefinitionId().longValue() == tousseItemVo.getTousseDefinitionID().longValue()){ + Integer amount = recyclingItem.getAmount(); + Integer voAmount = tousseItemVo.getAmount(); + if(amount.intValue() == voAmount.intValue()){ + recyclingItem.setRecyclingRecord(newRecyclingRecord); + newItems.add(recyclingItem); + }else{ + recyclingItem.setAmount(amount - voAmount); + RecyclingItem newItem = new RecyclingItem(); + try { + if(CollectionUtils.isNotEmpty(recyclingItem.getErrorDamageDetails())){ + throw new SystemException(recyclingItem.getTousseName() + "登记了丢失报损,只能全部拆分!"); + } + BeanUtils.copyProperties(newItem, recyclingItem); + newItem.setRecyclingRecord(newRecyclingRecord); + newItem.setAmount(voAmount); + newItem.setId(null); + newItem.setErrorDamageDetails(null); + objectDao.saveOrUpdate(newItem); + newItems.add(newItem); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + newRecyclingRecord.setItems(newItems); + } + + /** + * 新单增加回收记录 + * @param newClassifyBaskets + * @param newPlan + */ + private RecyclingRecord addRecyclingRecord(List newClassifiedItem, RecyclingApplication newPlan, RecyclingApplication oldPlan, RecyclingRecord oldRecyclingRecord) { + if(CollectionUtils.isEmpty(newClassifiedItem)){ + return null; + } + Date now = new Date(); + //更新申请单 + newPlan.setRecyclingTime(now); + newPlan.setRecyclingStatus(RecyclingApplication.RECYCLINGSTATUS_RECYCLED); + List items = newPlan.getApplicationItems(); + for (TousseItem tousseItem : items) { + tousseItem.setRecyclingAmount(tousseItem.getAmount()); + } + objectDao.saveOrUpdate(newPlan); + //创建回收记录 + RecyclingRecord record = new RecyclingRecord(); + record.setRecyclingTime(now); + record.setDepart(newPlan.getDepart()); + record.setDepartCode(newPlan.getDepartCoding()); + record.setOperator(AcegiHelper.getLoginUserFullName()); + record.setOrgUnitCoding(oldRecyclingRecord.getOrgUnitCoding()); + record.setRecyclingUser(AcegiHelper.getLoginUserFullName()); + record.setRecyclingApplication(newPlan); + record.setRecyclingApplicationType(oldRecyclingRecord.getRecyclingApplicationType()); + record.setRemark("申请单拆分后产生的回收记录"); + List basketList = new ArrayList(); + objectDao.saveOrUpdate(record); + Map splitAmountMap = new HashMap(); + for(ClassifiedItem classfiedItem : newClassifiedItem){ + classfiedItem.setInvoicePlanID(newPlan.getId()); + classfiedItem.setRecyclingRecordId(record.getId()); + ClassifyBasket cb = classfiedItem.getClassifyBasket(); + if(!basketList.contains(cb)){ + basketList.add(cb); + } + Integer amount = splitAmountMap.get(cb); + if(amount == null){ + amount = 0; + } + splitAmountMap.put(cb, ++amount); + } + record.setClassifyBaskets(basketList); + objectDao.saveOrUpdate(record); + + //如果旧回收记录某个篮筐的物品全部被拆分,要取消旧回收记录和篮筐的关联 + for (ClassifyBasket classifyBasket : basketList) { + Set tempItems = classifyBasket.getClassfiedItems(); + boolean removeBasket = true; + for (ClassifiedItem classifiedItem : tempItems) { + if(classifiedItem.getRecyclingRecordId().longValue() == oldRecyclingRecord.getId().longValue()){ + removeBasket = false; + break; + } + } + if(removeBasket){ + oldRecyclingRecord.getClassifyBaskets().remove(classifyBasket); + } + } + + return record; + } + + /** + * 判断篮筐是否包含某个物品,包含则更新篮筐物品数量,并把被移除的物品放入新篮筐中返回; + * 否则,返回null + * @param classfiedItems + * @param newItemVos + * @return + */ + private List splitClassifiedItem(List classfiedItems, Collection newItemVos) { + Map amountMap = new HashMap(); + for(TousseItemVo vo : newItemVos){ + Integer amount = amountMap.get(vo.getTousseDefinitionId()); + if(amount == null){ + amount = 0; + } + amountMap.put(vo.getTousseDefinitionId(), ++amount); + } + List returnClassifiedItems = new ArrayList(); + for (ClassifiedItem classifiedItem : classfiedItems) { + Long tousseDefinitionID = classifiedItem.getTousseDefinitionID(); + if(amountMap.get(tousseDefinitionID).intValue() == 0){ + break; + } + for(TousseItemVo vo : newItemVos){ + if(tousseDefinitionID.longValue() == vo.getTousseDefinitionId().longValue()){ + + Integer amount = vo.getAmount(); + Integer oldAmount = classifiedItem.getAmount(); + + if(amount.intValue() == oldAmount.intValue()){ + classifiedItem.setInvoicePlanID(null); + classifiedItem.setRecyclingRecordId(null); + returnClassifiedItems.add(classifiedItem); + }else{ + ClassifiedItem newClassifiedItem = new ClassifiedItem(); + try { + BeanUtils.copyProperties(newClassifiedItem, classifiedItem); + newClassifiedItem.setInvoicePlanID(null); + newClassifiedItem.setId(null); + newClassifiedItem.setRecyclingRecordId(null); + objectDao.saveOrUpdate(newClassifiedItem); + } catch (Exception e) { + e.printStackTrace(); + } + classifiedItem.setAmount(oldAmount - amount); + newClassifiedItem.setAmount(amount); + returnClassifiedItems.add(newClassifiedItem); + } + amountMap.put(tousseDefinitionID, amountMap.get(tousseDefinitionID) - amount); + break; + } + } + } + return returnClassifiedItems; + } + private Collection newTousseItemVos(JSONArray itemJsonArray,boolean setIdNull) { Collection vos = new ArrayList(); if(itemJsonArray.size() > 0){ Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/action/RecyclingApplicationAction.java =================================================================== diff -u -r30096 -r30153 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/action/RecyclingApplicationAction.java (.../RecyclingApplicationAction.java) (revision 30096) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/action/RecyclingApplicationAction.java (.../RecyclingApplicationAction.java) (revision 30153) @@ -1322,7 +1322,12 @@ obj.put("tousseName", item.getTousseName()); obj.put("type", item.getTousseType()); obj.put("amount", item.getAmount()); - obj.put("maxSplitAmount", item.getAmount()); + obj.put("recyclingAmount", item.getRecyclingAmount()); + if(item.getAmount().intValue() == 0){ + obj.put("maxSplitAmount", item.getRecyclingAmount()); + }else{ + obj.put("maxSplitAmount", item.getAmount()); + } dataArray.add(obj); } }