Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/toussedefinition/TousseDefinition.java
===================================================================
diff -u -r14440 -r14485
--- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/toussedefinition/TousseDefinition.java (.../TousseDefinition.java) (revision 14440)
+++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/toussedefinition/TousseDefinition.java (.../TousseDefinition.java) (revision 14485)
@@ -814,6 +814,14 @@
return false;
}
/**
+ * 判断是否是外来器械拆分小包
+ * @return
+ */
+ @Transient
+ public boolean isSplit(){
+ return StringTools.equals(tousseType, PACKAGE_TYPE_SPLIT);
+ }
+ /**
* 判断是否是整包清洗
* @return
*/
Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/goodsstock/service/GoodsStockManagerImpl.java
===================================================================
diff -u -r14452 -r14485
--- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/goodsstock/service/GoodsStockManagerImpl.java (.../GoodsStockManagerImpl.java) (revision 14452)
+++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/goodsstock/service/GoodsStockManagerImpl.java (.../GoodsStockManagerImpl.java) (revision 14485)
@@ -59,22 +59,24 @@
return map;
}
/**
- * 获取仓库下的物品名称的库存集合。此方法可能会多返回一些记录,但这是些记录并不是你想要的。
+ * 获取仓库下的物品名称的库存集合,目前只有外来器械拆分小包才会调用这个方法,所以在此方法里面限制物品类型为器械包,不处理材料的数据。
+ * 此方法可能会多返回一些记录,但这是些记录并不是你想要的。
*
如要获取仓库1下的张三和仓库2下的李四,应该只会有两条记录返回。但是此方法的实现,可能还会返回仓库1下的李四和仓库2下的张三
+ * @param amountBigZero 是否只获取数量大于0的记录。对于发货,应该只要查数量大于0的库存记录,但是入库可能需要查库存等于0的记录
* @param wareHouseIds
* @param goodsNames
- * @param amountBigZero 是否只获取数量大于0的记录。对于发货,应该只要查数量大于0的库存记录,但是入库可能需要查库存等于0的记录
* @return
*/
@SuppressWarnings("unchecked")
- private List getGoodsStock(Collection wareHouseIds,Collection goodsNames,boolean amountBigZero){
+ private List getGoodsStock(boolean amountBigZero,Collection wareHouseIds,Collection goodsNames){
String namePredicate = SqlUtils.getStringFieldInCollectionsPredicate("name", goodsNames);
String idPredicate = SqlUtils.getNonStringFieldInCollectionsPredicate("wareHouseId", wareHouseIds);
String amountPredicate = " 1=1 ";
if(amountBigZero){
amountPredicate = " amount > 0 ";
}
- String sql = " where 1=1 and " + idPredicate + " and " + namePredicate + " and " + amountPredicate;
+ String sql = " where 1=1 and " + idPredicate + " and " + namePredicate + " and " + amountPredicate
+ + " and goodsType='" + GoodsStock.TYPE_TOUSSE + "'";
List list = objectDao.getBySql_ForUpdate2(GoodsStock.class.getSimpleName(), sql);
return list;
}
@@ -87,13 +89,10 @@
* @return
*/
@SuppressWarnings("unchecked")
- private List getGoodsStock(Collection wareHouseIds,Collection goodsDefId,boolean toussedefIdOrMaterialDefId,boolean amountBigZero){
+ private List getGoodsStock(Collection wareHouseIds,Collection goodsDefId,boolean toussedefIdOrMaterialDefId){
String wareHouseIdPredicate = SqlUtils.getNonStringFieldInCollectionsPredicate("wareHouseId", wareHouseIds);
String goodsDefIdPredicate = "";
String amountPredicate = " 1=1 ";
- if(amountBigZero){
- amountPredicate = " amount > 0 ";
- }
if(toussedefIdOrMaterialDefId){
goodsDefIdPredicate = SqlUtils.getNonStringFieldInCollectionsPredicate("tousseDefinitionId", goodsDefId);
}else{
@@ -127,16 +126,30 @@
private void doInStock(List goodsStockList) {
String sql = null;
GoodsStock goodsStock = null;
+ List goodsStockInDB = new ArrayList();
for(GoodsStock goodsStockTemp : goodsStockList){
if(goodsStockTemp.getAmount() == null || goodsStockTemp.getAmount() == 0){
throw new RuntimeException("入/退库单"+goodsStockTemp.getName()+"的数量不能为空或0");
}
//如果为器械包
if(DatabaseUtil.isPoIdValid(goodsStockTemp.getTousseDefinitionId())){
- sql = " where 1=1 and wareHouseId = " + goodsStockTemp.getWareHouseId() + " and tousseDefinitionId = " + goodsStockTemp.getTousseDefinitionId();
- //判断库存数量是否大于退/出库数量
- goodsStock = (GoodsStock)objectDao.getBySql(GoodsStock.class.getSimpleName(), sql);
+ //先从list中找
+ goodsStock = CollectionUtils.find(goodsStockInDB, new Predicate(){
+ @Override
+ public boolean evaluate(GoodsStock gs) {
+ if(gs.getWareHouseId().equals(goodsStockTemp.getWareHouseId())
+ && gs.getTousseDefinitionId().equals(goodsStockTemp.getTousseDefinitionId())){
+ return true;
+ }
+ return false;
+ }
+ });
if(goodsStock == null){
+ sql = " where 1=1 and wareHouseId = " + goodsStockTemp.getWareHouseId() + " and tousseDefinitionId = " + goodsStockTemp.getTousseDefinitionId();
+ //判断库存数量是否大于退/出库数量
+ goodsStock = (GoodsStock)objectDao.getBySql(GoodsStock.class.getSimpleName(), sql);
+ }
+ if(goodsStock == null){
goodsStock = new GoodsStock();
goodsStock.setWareHouseId(goodsStockTemp.getWareHouseId());
goodsStock.setWareHouseName(goodsStockTemp.getWareHouseName());
@@ -148,9 +161,11 @@
goodsStock.setOrgUnitName(goodsStockTemp.getOrgUnitName());
goodsStock.setAmount(goodsStockTemp.getAmount());
objectDao.saveOrUpdate(goodsStock);
+ goodsStockInDB.add(goodsStock);
} else {
goodsStock.setAmount(goodsStock.getAmount() + goodsStockTemp.getAmount());
- objectDao.saveOrUpdate(goodsStock);
+ addIfNotFind(goodsStockInDB, goodsStock);
+ //objectDao.saveOrUpdate(goodsStock);
}
}else if(DatabaseUtil.isPoIdValid(goodsStockTemp.getMaterialDefinitionId())){
goodsStock = goodsStockTemp;
@@ -160,6 +175,10 @@
throw new RuntimeException("入/退库单器械包id与材料id不能同时为空");
}
}
+ //一次写入数据库
+ for(GoodsStock gs : goodsStockInDB){
+ objectDao.saveOrUpdate(gs);
+ }
}
/**
@@ -173,8 +192,8 @@
Map idTousseDefinitionMap = getIDTousseDefinitionMap(goodsStockList);
Set wareHouseIds = new HashSet();
- Set goodsNames = new HashSet();
Set tousseDefIds = new HashSet();
+ Set goodsNames = new HashSet();
Set materialDefIds = new HashSet();
for(GoodsStock gs : goodsStockList){
wareHouseIds.add(gs.getWareHouseId());
@@ -186,55 +205,45 @@
materialDefIds.add(gs.getMaterialDefinitionId());
}
}
- List goodsStockListInDb = getGoodsStock(wareHouseIds, goodsNames,true);
- List toussedefGoodsStockListInDb = getGoodsStock(wareHouseIds, tousseDefIds, true,true);
- List materialDefGoodsStockListInDb = getGoodsStock(wareHouseIds,materialDefIds,false,true);
+ List tousseNameStockListInDb = getGoodsStock(true,wareHouseIds, goodsNames);
+ List toussedefGoodsStockListInDb = getGoodsStock(wareHouseIds, tousseDefIds, true);
+ List materialDefGoodsStockListInDb = getGoodsStock(wareHouseIds,materialDefIds,false);
+ List toUpdateGoodsStock = new ArrayList(); //需要更新库存数量的库存记录
for(GoodsStock goodsStockTemp : goodsStockList){
if(goodsStockTemp.getAmount() == null || goodsStockTemp.getAmount() == 0){
throw new RuntimeException("入/退库单"+goodsStockTemp.getName()+"的数量不能为空或0");
}
if(DatabaseUtil.isPoIdValid(goodsStockTemp.getTousseDefinitionId())){
TousseDefinition td = idTousseDefinitionMap.get(goodsStockTemp.getTousseDefinitionId());
- //如果包定义为消毒物品、外来器械包、自定义器械包、外部代理灭菌、外来器械拆分小包等,则按器械包名称查询库存并进行扣减
if(td != null){
- if(TousseDefinition.PACKAGE_TYPE_DISINFECTION.equals(td.getTousseType())
- || TousseDefinition.PACKAGE_TYPE_FOREIGN.equals(td.getTousseType())
- || TousseDefinition.PACKAGE_TYPE_CUSTOM.equals(td.getTousseType())
- || TousseDefinition.PACKAGE_TYPE_FOREIGNPROXY.equals(td.getTousseType())
- || TousseDefinition.PACKAGE_TYPE_SPLIT.equals(td.getTousseType())){
- //先查询库存是否足够
- List list = goodsStockListInDb.stream().filter(
- gs->gs.getWareHouseId().equals(goodsStockTemp.getWareHouseId())
- && StringTools.equals(gs.getName(), goodsStockTemp.getName())
+ if(td.isSplit()){
+ //如果包定义为外来器械拆分小包等,则按器械包名称查询库存并进行扣减
+ List list = tousseNameStockListInDb.stream().filter(
+ gs->StringTools.equals(gs.getName(), goodsStockTemp.getName())
+ && gs.getWareHouseId().equals(goodsStockTemp.getWareHouseId())
&& gs.getAmount() > 0).collect(Collectors.toList());
- int amount = 0;
- if(CollectionUtils.isNotEmpty(list)){
- for(GoodsStock gs : list){
- amount = MathTools.add(amount, gs.getAmount()).intValue();
- }
- }
- if(amount < goodsStockTemp.getAmount()){
+ int totalAmount = calculateTotalAmount(list);
+ int needAmount = goodsStockTemp.getAmount();
+ if(totalAmount < needAmount){
throw new RuntimeException(goodsStockTemp.getName() + "的库存数量小于出库或退库数量,不能出库或退库");
- } else {
- int needOutAmount = goodsStockTemp.getAmount();
- for(GoodsStock stock : list){
- //如果能够扣完,则跳出
- if(stock.getAmount() >= needOutAmount){
- stock.setAmount(stock.getAmount() - needOutAmount);
- objectDao.saveOrUpdate(stock);
- break;
- }
- //否则当前库存扣完,直至扣至需要扣完的为止
- needOutAmount -= stock.getAmount();
- stock.setAmount(0);
- objectDao.saveOrUpdate(stock);
+ }
+
+ for(GoodsStock gs : list){
+ if(gs.getAmount() >= needAmount){
+ gs.setAmount(MathTools.sub(gs.getAmount(), needAmount).intValue());
+ addIfNotFind(toUpdateGoodsStock,gs);
+ break;
+ }else{
+ needAmount = MathTools.sub(needAmount, gs.getAmount()).intValue();
+ gs.setAmount(0);
+ addIfNotFind(toUpdateGoodsStock,gs);
}
}
+
}else{
- //如果为器械包、敷料包时则按包定义id查询并扣减库存
+ //按包定义祖先id查询并扣减库存
GoodsStock goodsStock = CollectionUtils.find(toussedefGoodsStockListInDb,new Predicate(){
-
@Override
public boolean evaluate(GoodsStock goodsStock) {
return goodsStockTemp.getWareHouseId().equals(goodsStock.getWareHouseId())
@@ -247,24 +256,19 @@
throw new RuntimeException(goodsStockTemp.getName() + "的库存数量小于出库或退库数量,不能出库或退库");
} else {
goodsStock.setAmount(goodsStock.getAmount() - goodsStockTemp.getAmount());
- objectDao.saveOrUpdate(goodsStock);
+ addIfNotFind(toUpdateGoodsStock,goodsStock);
}
}
}else{
throw new RuntimeException("未找到"+goodsStockTemp.getName()+"的器械包定义");
}
- }else if(goodsStockTemp.getMaterialDefinitionId() != null && goodsStockTemp.getMaterialDefinitionId() != 0){
+ }else if(DatabaseUtil.isPoIdValid(goodsStockTemp.getMaterialDefinitionId())){
//先判断该材料所有库存总和是否大于需扣减的数量
List list = materialDefGoodsStockListInDb.stream().filter(
gs->gs.getWareHouseId().equals(goodsStockTemp.getWareHouseId())
&& gs.getMaterialDefinitionId().equals(goodsStockTemp.getMaterialDefinitionId())
&& gs.getAmount() > 0).collect(Collectors.toList());
- int totalAmount = 0;
- if(CollectionUtils.isNotEmpty(list)){
- for(GoodsStock gs : list){
- totalAmount = MathTools.add(totalAmount, gs.getAmount()).intValue();
- }
- }
+ int totalAmount = calculateTotalAmount(list);
int needReturnAmount = goodsStockTemp.getAmount();
if(totalAmount < needReturnAmount){
@@ -273,17 +277,23 @@
for(GoodsStock goodsStock : list){
if(goodsStock.getAmount() >= needReturnAmount){
goodsStock.setAmount(goodsStock.getAmount() - needReturnAmount);
- objectDao.saveOrUpdate(goodsStock);
+ addIfNotFind(toUpdateGoodsStock,goodsStock);
break;
}
needReturnAmount -= goodsStock.getAmount();
goodsStock.setAmount(0);
- objectDao.saveOrUpdate(goodsStock);
+ addIfNotFind(toUpdateGoodsStock,goodsStock);
}
} else {
throw new RuntimeException("入/退库单器械包id与材料id不能同时为空");
}
}
+ //最后一次更新需要更新的库存记录
+ if(CollectionUtils.isNotEmpty(toUpdateGoodsStock)){
+ for(GoodsStock gs : toUpdateGoodsStock){
+ objectDao.saveOrUpdate(gs);
+ }
+ }
}
/**
@@ -306,5 +316,47 @@
result = (List)objectDao.findBySql(GoodsStock.class.getSimpleName(), sql);
return result;
}
-
+ /**
+ * 在集合中查找指定id的库存记录,找到返回原记录,未找到,返回null
+ * @param goodsStocks 库存记录集合
+ * @param id 要查找的库存记录的id
+ * @return id所对应的库存记录.未找到则返回null
+ */
+ public GoodsStock find(Collection goodsStocks,Long id){
+ GoodsStock goodsStockFind = CollectionUtils.find(goodsStocks,new Predicate(){
+ @Override
+ public boolean evaluate(GoodsStock gs) {
+ return id.equals(gs.getId());
+ }});
+ return goodsStockFind;
+ }
+ /**
+ * 在集合中如果没有找到库存记录,则将库存记录添加到集合中。根据id进行比对查找
+ * @param goodsStocks
+ * @param goodsStock
+ */
+ private void addIfNotFind(Collection goodsStocks,GoodsStock goodsStock){
+ if(goodsStock != null){
+ GoodsStock goodsStockFind = find(goodsStocks,goodsStock.getId());
+ if(goodsStockFind == null){
+ goodsStocks.add(goodsStock);
+ }
+ }
+ }
+ /**
+ * 计算集合中库存数量总和
+ * @param goodsStocks
+ * @return
+ */
+ public int calculateTotalAmount(Collection goodsStocks){
+ int totalAmout = 0;
+ if(CollectionUtils.isNotEmpty(goodsStocks)){
+ for(GoodsStock gs : goodsStocks){
+ if(gs != null){
+ totalAmout = MathTools.add(totalAmout, gs.getAmount()).intValue();
+ }
+ }
+ }
+ return totalAmout;
+ }
}
Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/goodsstock/GoodsStock.java
===================================================================
diff -u -r14222 -r14485
--- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/goodsstock/GoodsStock.java (.../GoodsStock.java) (revision 14222)
+++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/goodsstock/GoodsStock.java (.../GoodsStock.java) (revision 14485)
@@ -54,7 +54,7 @@
private String goodsType;
/**
- * 器械包定义id,不是祖先id
+ * 器械包定义id,记录的是祖先id,包定义的ancestorID字段
*/
private Long tousseDefinitionId;
Index: ssts-web/src/test/java/test/forgon/disinfectsystem/packing/InvoicePlanManagerTests.java
===================================================================
diff -u -r13055 -r14485
--- ssts-web/src/test/java/test/forgon/disinfectsystem/packing/InvoicePlanManagerTests.java (.../InvoicePlanManagerTests.java) (revision 13055)
+++ ssts-web/src/test/java/test/forgon/disinfectsystem/packing/InvoicePlanManagerTests.java (.../InvoicePlanManagerTests.java) (revision 14485)
@@ -146,7 +146,7 @@
goodsStockManager.saveOrUpdateGoodsStock(list, GoodsStockManager.MODE_INSTOCK);
GoodsStock getStock = new GoodsStock();
getStock.setWareHouseId(wareHouse1.getId());
- getStock.setTousseDefinitionId(td.getId());
+ getStock.setTousseDefinitionId(td.getAncestorID());
List retlist = goodsStockManager.getGoodsStockList(getStock);
assertNotNull(retlist);
Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/toussedefinition/service/TousseInstanceUtils.java
===================================================================
diff -u -r14027 -r14485
--- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/toussedefinition/service/TousseInstanceUtils.java (.../TousseInstanceUtils.java) (revision 14027)
+++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/toussedefinition/service/TousseInstanceUtils.java (.../TousseInstanceUtils.java) (revision 14485)
@@ -234,7 +234,7 @@
goodsStock.setName(tousseInstance.getTousseName());
goodsStock.setOrgUnitCode(wareHouse.getOrgUnitCode());
goodsStock.setOrgUnitName(wareHouse.getOrgUnitName());
- goodsStock.setTousseDefinitionId(tousseInstance.getTousseDefinition().getId());
+ goodsStock.setTousseDefinitionId(tousseInstance.getTousseDefinition().getAncestorID());
goodsStock.setWareHouseId(wareHouse.getId());
goodsStock.setWareHouseName(wareHouse.getName());
return goodsStock;
Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java
===================================================================
diff -u -r14480 -r14485
--- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java (.../RecyclingApplicationManagerImpl.java) (revision 14480)
+++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/recyclingapplication/service/RecyclingApplicationManagerImpl.java (.../RecyclingApplicationManagerImpl.java) (revision 14485)
@@ -3701,7 +3701,7 @@
}
List stockList = new ArrayList();
GoodsStock stock = new GoodsStock();
- stock.setTousseDefinitionId(td.getId());
+ stock.setTousseDefinitionId(td.getAncestorID());
stock.setAmount(amount);
stock.setGoodsType(GoodsStock.TYPE_TOUSSE);
stock.setName(td.getName());
@@ -3847,7 +3847,7 @@
}
List stockList = new ArrayList();
GoodsStock stock = new GoodsStock();
- stock.setTousseDefinitionId(td.getId());
+ stock.setTousseDefinitionId(td.getAncestorID());
stock.setAmount(amount);
stock.setGoodsType(GoodsStock.TYPE_TOUSSE);
stock.setName(td.getName());