Przeglądaj źródła

1、合同产品取消配送功能开发,测试:a、添加取消数量和序列号的校验;b、序列号选择规则修改;c、取消数量大于拣货数量提醒,序列号不存在提醒;
2、合同产品配送后更新成本:先进先出、后进先出、平均;
3、产品入库计算库存平均单元成本(UNIT_COST_AVG);

zhangyao 4 miesięcy temu
rodzic
commit
2323178bd0

BIN
com.awspaas.user.apps.donenow_ctt/lib/com.awspaas.user.apps.donenow_ctt.jar


+ 46 - 22
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/controller/contractCostController.java

@@ -69,8 +69,7 @@ public class contractCostController {
         newBO.setBindId(processInstance.getId());
         int quantity = contractCostQuantity - contractProductPickQuantity;//待拣货数量
 
-        if (quantity <= 0)
-            return ResponseObject.newErrResponse("无需拣货");
+        if (quantity <= 0) return ResponseObject.newErrResponse("无需拣货");
 
         if (quantity > warehouseProductQuantity) {
             newBO.set("PICK_QUANTITY", warehouseProductQuantity);
@@ -198,23 +197,25 @@ public class contractCostController {
         //库存数量
         RowMap stockMap = DBSql.getMap("SELECT * FROM BO_EU_DNIVT_WAREHOUSE_PRODUCT WHERE ID=?", new Object[]{warehouseProductId});
         //库存产品
-        List<RowMap> lotList = DBSql.getMaps("SELECT b.* FROM bo_eu_dnivt_warehouse_product a JOIN BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT b ON a.BINDID=b.BINDID WHERE b.QUANTITY>0 AND a.ID=? ORDER BY b.IN_DATE", new Object[]{warehouseProductId});
+
+        String OUT_RULE = DBSql.getString("SELECT OUT_RULE FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{stockMap.getString("PRODUCT_ID")});
+        //1031 FIFO先进先出  1032 LIFO后进先出
+        List<RowMap> lotList = DBSql.getMaps("SELECT b.* FROM bo_eu_dnivt_warehouse_product a JOIN BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT b ON a.BINDID=b.BINDID WHERE b.QUANTITY>0 AND a.ID=? ORDER BY b.CREATEDATE " + (OUT_RULE.equals("1032") ? "DESC" : "ASC"), new Object[]{warehouseProductId});
+
         //已被拣货数量
         List<RowMap> pickList = DBSql.getMaps("SELECT a.* from BO_EU_DNCTT_CONTRACT_COST_PRODUCT a JOIN BO_EU_DNCTT_CONTRACT_COST b ON a.CONTRACT_COST_ID=b.ID WHERE a.WAREHOUSE_ID=? AND b.PRODUCT_ID=?", new Object[]{stockMap.getString("WAREHOUSE_ID"), stockMap.getString("PRODUCT_ID")});
 
         List<String> selectedSns = new ArrayList<>();//默认选择
         for (RowMap lotMap : lotList) {
             String lotSNs = lotMap.getString("SN");
-            if (StringUtils.isBlank(lotSNs))
-                continue;
+            if (StringUtils.isBlank(lotSNs)) continue;
 
             List<String> lotsns = new ArrayList<>();//本批次允许拣货数量
             for (String SN : lotSNs.split(",")) {
                 boolean isPicked = false;
                 for (RowMap pickMap : pickList) {
                     String pickSNs = pickMap.getString("SN");
-                    if (StringUtils.isBlank(pickSNs))
-                        continue;
+                    if (StringUtils.isBlank(pickSNs)) continue;
                     for (String pickSN : pickSNs.split(",")) {
                         if (SN.equals(pickSN)) {
                             //已被拣货
@@ -242,8 +243,7 @@ public class contractCostController {
                 quantity -= lotsns.size();
                 selectedSns.addAll(lotsns);
             }
-            if (quantity <= 0)
-                break;
+            if (quantity <= 0) break;
         }
 
         if (quantity > 0) {
@@ -263,10 +263,9 @@ public class contractCostController {
     public ResponseObject reAssociatePurchaseOrder(UserContext uc, String contractCostId) {
         BO orderProductBO = SDK.getBOAPI().query("BO_EU_DNIVT_ORDER_PRODUCT").addQuery("CONTRACT_COST_ID=", contractCostId).detail();//采购单
 
-        if (orderProductBO == null)
-            return ResponseObject.newErrResponse("未找到采购单");
+        if (orderProductBO == null) return ResponseObject.newErrResponse("未找到采购单");
 
-        if (DBSql.getString("SELECT STATUS_ID FROM BO_EU_DNIVT_ORDER WHERE ID=?", new Object[]{orderProductBO.getString("ORDER_ID")}).equals("2148") == false) {
+        if (DBSql.getString("SELECT STATUS_ID FROM BO_EU_DNIVT_ORDER WHERE ID=?", new Object[]{orderProductBO.getString("ORDER_ID")}).equals("2150") == false) {
             return ResponseObject.newErrResponse("采购单未接收,请在全部产品接收后操作");
         }
 
@@ -285,19 +284,15 @@ public class contractCostController {
                 {
                     if (StringUtils.isNotBlank(SN))
                         movePro += "产品序列号:" + SN + ",数量:" + QUANTITY + "已被移动到仓库" + NAME + ",";
-                    else
-                        movePro += "数量:" + QUANTITY + "已被移动到仓库" + NAME + ",";
+                    else movePro += "数量:" + QUANTITY + "已被移动到仓库" + NAME + ",";
 
                 } else {
-                    if (StringUtils.isNotBlank(SN))
-                        sns = sns + "," + SN;
+                    if (StringUtils.isNotBlank(SN)) sns = sns + "," + SN;
                     orderQuantity = orderQuantity + QUANTITY;
                 }
             }
-            if (StringUtils.isNotBlank(sns))
-                sns = sns + ",";
-            if (orderQuantity <= 0)
-                return ResponseObject.newErrResponse("采购单产品已全部关联,请勿重复操作!");
+            if (StringUtils.isNotBlank(sns)) sns = sns + ",";
+            if (orderQuantity <= 0) return ResponseObject.newErrResponse("采购单产品已全部关联,请勿重复操作!");
 
         } else {
             return ResponseObject.newErrResponse("采购单产品已全部关联,请勿重复操作!");
@@ -320,8 +315,7 @@ public class contractCostController {
         if (orderQuantity <= 0) {
             return ResponseObject.newErrResponse("采购单产品已全部关联,本次操作无效!");
         }
-        if (StringUtils.isNotBlank(sns))
-            sns = sns.substring(1, sns.length() - 1);
+        if (StringUtils.isNotBlank(sns)) sns = sns.substring(1, sns.length() - 1);
 
         //创建新的采购单产品
         BO newCostProductBO = costProductList.get(0);
@@ -340,4 +334,34 @@ public class contractCostController {
         return ResponseObject.newOkResponse();
     }
 
+    /**
+     * 产品配送
+     * @param uc
+     * @param bindid
+     * @return
+     */
+    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.costProductShip")
+    public ResponseObject costProductShip(UserContext uc, String bindid) {
+        BO costProductBO = SDK.getBOAPI().getByProcess("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", bindid);
+
+        if (costProductBO.getString("IS_SHIP").equals("2"))
+            return ResponseObject.newErrResponse("该产品已配送,请勿重复操作!");
+
+        //只有状态是“待配送”和“已拣货”才能进行配送
+        if (!costProductBO.getString("STATUS_ID").equals("2157") && !costProductBO.getString("STATUS_ID").equals("2158"))
+            return ResponseObject.newErrResponse("该产品状态不是待配送或已拣货,请勿操作!");
+
+        costProductBO.set("IS_SHIP", "1");//待配送
+        costProductBO.set("OLD_QUANTITY", costProductBO.get("QUANTITY"));
+        costProductBO.set("SHIPPING_TYPE_ID", null);
+        costProductBO.set("SHIPPING_SN", costProductBO.get("SN"));
+
+        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductBO);
+
+        String url = "./w?appId=com.awspaas.user.apps.donenow_ctt&msaAppId=com.awspaas.user.apps.donenow_ctt&sid=" + uc.getSessionId() + "&cmd=CLIENT_DW_FORM_OPENPAGE&bindid=" + bindid;
+        ResponseObject responseObject = ResponseObject.newOkResponse();
+        responseObject.setData(url);
+        return responseObject;
+    }
+
 }

+ 51 - 0
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/event/costProductFormBeforeSave.java

@@ -0,0 +1,51 @@
+package com.awspaas.user.apps.donenow_ctt.event;
+
+import com.actionsoft.bpms.bo.engine.BO;
+import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext;
+import com.actionsoft.bpms.bpmn.engine.listener.InterruptListener;
+import com.actionsoft.bpms.bpmn.engine.listener.ListenerConst;
+import com.actionsoft.exception.BPMNError;
+import org.apache.commons.lang3.StringUtils;
+
+public class costProductFormBeforeSave extends InterruptListener {
+    public String getDescription() {
+        return "合同产品配送前,校验库存";
+    }
+
+    /**
+     * 监听器执行方法
+     * @param param
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public boolean execute(ProcessExecutionContext param) throws Exception {
+
+        //记录ID
+        String boId = param.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_BOID);
+        //表单ID
+        String formId = param.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_FORMID);
+        //BO表名 ,当表单中有主子表多个表时,该事件会执行多次,开发人员需要判断当前执行换取到的表名,进一步进行业务处理
+        String boName = param.getParameterOfString(ListenerConst.FORM_EVENT_PARAM_BONAME);
+        BO formData = (BO) param.getParameter(ListenerConst.FORM_EVENT_PARAM_FORMDATA);
+
+
+        int QUANTITY = Integer.parseInt(formData.getString("QUANTITY"));//配送数量
+        if (QUANTITY <= 0)
+            throw new BPMNError("quantity", "配送数量必须大于等于0");
+        String sn = formData.getString("SN");//序列号
+        String shipSn = formData.getString("SHIPPING_SN");
+
+        if (StringUtils.isNotBlank(sn) && StringUtils.isBlank(shipSn))
+            throw new BPMNError("sn", "请选择序列号");
+
+        if (StringUtils.isNotBlank(shipSn)) {
+            if (shipSn.split(",").length != QUANTITY)
+                throw new BPMNError("shipSn", "请选择正确的序列号");
+        }
+
+        //记录表单修改
+        dn.recordFormChanges.execute(param);
+        return true;
+    }
+}

+ 70 - 23
com.awspaas.user.apps.donenow_ctt/src/com/awspaas/user/apps/donenow_ctt/event/costProductShipFormAfterSave.java

@@ -37,33 +37,40 @@ public class costProductShipFormAfterSave extends ExecuteListener {
                 conn = DBSql.open();
                 conn.setAutoCommit(false);
 
-                int shipQuantity = ObjToInt(productBO.get("QUANTITY"));
-                // String SERIAL_NUMBERS = productBO.getString("SN");
+                int shipQuantity = ObjToInt(productBO.get("QUANTITY"));//配送数量
                 int notShipQuantity = ObjToInt(productBO.get("OLD_QUANTITY")) - shipQuantity;//剩余数量;
 
                 String SN = productBO.getString("SN");//原产品序列号
-                String notShipSN = "," + SN + ",";
                 String SHIPPING_SN = productBO.getString("SHIPPING_SN");//配送产品序列号
-                for (String spsn : SHIPPING_SN.split(",")) {
-                    notShipSN = notShipSN.replaceAll("," + spsn + ",", ",");
+                if (StringUtils.isNotBlank(SN) && StringUtils.isBlank(SHIPPING_SN)) {
+                    throw new BPMNError("请选择要配送的产品");
+                }
+                String notShipSN = "";
+                if (StringUtils.isNotBlank(SN) && StringUtils.isNotBlank(SHIPPING_SN)) {
+                    notShipSN = "," + SN + ",";
+                    for (String spsn : SHIPPING_SN.split(",")) {
+                        notShipSN = notShipSN.replaceAll("," + spsn + ",", ",");
+                    }
+                    if (StringUtils.isNotBlank(notShipSN) && notShipSN.length() > 1 && !notShipSN.equals(",,"))
+                        notShipSN = notShipSN.substring(1, notShipSN.length() - 1);//未配送的产品序列号
+                    else
+                        notShipSN = "";
                 }
-                notShipSN = notShipSN.substring(1, notShipSN.length() - 1);//未配送的产品序列号
-
 
+                String oldStatusId = productBO.getString("STATUS_ID");//原状态
                 //全部配送
                 if (ObjToInt(productBO.get("OLD_QUANTITY")) == shipQuantity) {
                     productBO.set("IS_SHIP", "2");
                     productBO.set("STATUS_ID", 2159);
-                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", productBO, conn);
+                    //SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", productBO, conn);
                 } else {
                     //部分配送
                     productBO.set("SN", SHIPPING_SN);
                     productBO.set("IS_SHIP", "2");
                     productBO.set("QUANTITY", shipQuantity);
-                    productBO.set("OLD_QUANTITY", productBO.get("QUANTITY"));
+                    productBO.set("OLD_QUANTITY", shipQuantity);
                     productBO.set("STATUS_ID", 2159);//已配送
-
-                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", productBO, conn);
+                    //SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", productBO, conn);
 
                     //未配送的生成一个新的物流单
                     BO toCostProductBO = new BO();
@@ -73,10 +80,12 @@ public class costProductShipFormAfterSave extends ExecuteListener {
                     toCostProductBO.set("WAREHOUSE_ID", productBO.get("WAREHOUSE_ID"));
                     toCostProductBO.set("CONTRACT_COST_ID", productBO.get("CONTRACT_COST_ID"));
                     toCostProductBO.set("QUANTITY", notShipQuantity);
-                    toCostProductBO.set("STATUS_ID", 2157);//已拣货
-                    toCostProductBO.set("OLD_QUANTITY", toCostProductBO.get("QUANTITY"));//配送数量
-                    productBO.set("SN", notShipSN);//未配送的产品序列号
-                    SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", toCostProductBO, processExecutionContext.getUserContext(), conn);
+                    toCostProductBO.set("ORDER_ID", productBO.getString("ORDER_ID"));
+                    toCostProductBO.set("STATUS_ID", oldStatusId);
+                    toCostProductBO.set("OLD_QUANTITY", notShipQuantity);//配送数量
+                    toCostProductBO.set("SN", notShipSN);//未配送的产品序列号
+                    toCostProductBO.set("SHIPPING_SN", notShipSN);
+                    SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", toCostProductBO, processInstance, processExecutionContext.getUserContext(), conn);
                 }
 
                 BO costBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST", productBO.getString("CONTRACT_COST_ID"));//获取合同产品
@@ -105,11 +114,24 @@ public class costProductShipFormAfterSave extends ExecuteListener {
                 fromWarehouseProductBO.set("QUANTITY", ObjToInt(fromWarehouseProductBO.get("QUANTITY")) - ObjToInt(shipQuantity));
                 SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT", fromWarehouseProductBO, conn);
 
+                List<BO> lots = null;
+                //出库方式
+                String OUT_RULE = DBSql.getString(conn, "SELECT OUT_RULE FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{fromWarehouseProductBO.getString("PRODUCT_ID")});
+
+                if (OUT_RULE.equals("1032"))//LIFO后进先出
+                {
+                    lots = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", fromWarehouseProductBO.getBindId()).addQuery("QUANTITY>0", null).orderByCreated().desc().list();
+                } else {
+                    //FIFO先进先出
+                    lots = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", fromWarehouseProductBO.getBindId()).addQuery("QUANTITY>0", null).orderByCreated().asc().list();
+                }
+
                 //减少批次
-                List<BO> lots = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", fromWarehouseProductBO.getBindId()).addQuery("QUANTITY>0", null).orderByCreated().list();
+                double totalCost = 0;//总成本
                 int cnt = 0;
-                String[] shipSerials = SHIPPING_SN.split(",");
+                String[] shipSerials = SHIPPING_SN.split(",");//配送的批次
                 for (BO lot : lots) {
+                    //序列号产品
                     if (StringUtils.isNotBlank(SHIPPING_SN)) {
                         boolean isIn = false;
                         String lotSN = lot.getString("SN");
@@ -136,7 +158,8 @@ public class costProductShipFormAfterSave extends ExecuteListener {
                                 lot.set("SN", "");
                                 lot.set("QUANTITY", 0);
                             }
-
+                            totalCost += toSN.size() * Double.parseDouble(lot.getString("UNIT_COST"));
+                            lot.set("SHIPPED_SN", StringUtils.join(toSN, ","));
                             //更新批次上序列号
                             SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);
 
@@ -146,19 +169,30 @@ public class costProductShipFormAfterSave extends ExecuteListener {
                     } else {
                         //无序列号处理
                         int QUANTITY = Integer.parseInt(lot.get("QUANTITY").toString());
+                        int toQu = QUANTITY;
                         if (QUANTITY > shipQuantity) {
                             lot.set("QUANTITY", QUANTITY - shipQuantity);
-                            shipQuantity=0;
+                            toQu = shipQuantity;
+                            shipQuantity = 0;
+
                         } else {
                             lot.set("QUANTITY", 0);
+                            toQu = QUANTITY;
                             shipQuantity = shipQuantity - QUANTITY;
                         }
+
+                        totalCost += toQu * Double.parseDouble(lot.getString("UNIT_COST"));
+
                         SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);
-                        if (shipQuantity<=0)
+                        if (shipQuantity <= 0)
                             break;
                     }
                 }
 
+                productBO.set("UNIT_COST", totalCost / Integer.parseInt(productBO.getString("QUANTITY")));//计算平均成本
+
+                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", productBO, conn);
+
                 //生成运费成本
                 // 输入运费的物料计费代码,就会生成新的成本ctt_contract_cost
                 if (StringUtils.isNotBlank(productBO.getString("COST_CODE_ID"))) {
@@ -194,20 +228,33 @@ public class costProductShipFormAfterSave extends ExecuteListener {
 
 
                 //配送成功后,更新产品成本:产品来源于采购---从采购单获取,成本取自采购单;库存拣货,成本取自库存产品
+                if (DBSql.getInt(conn, "select count(ID) from BO_EU_DNCTT_CONTRACT_COST_PRODUCT where CONTRACT_COST_ID=? AND STATUS_ID<2159  AND CLOSED=0", new Object[]{costBO.getId()}) == 0) {
+                    //已全部配送完成
 
+                    costBO.set("STATUS_ID", 1237);//已配送
+                    double UNIT_COST = 0;
+                    if (OUT_RULE.equals("1030")) {
+                        //库存平均单元成本
+                        UNIT_COST = DBSql.getDouble(conn, "SELECT UNIT_COST_AVG FROM BO_EU_DNIVT_PRODUCT WHERE ID='" + fromWarehouseProductBO.getString("PRODUCT_ID") + "'", "UNIT_COST_AVG");
+
+                    } else {
+                        UNIT_COST = DBSql.getDouble(conn, "SELECT SUM(UNIT_COST*QUANTITY)/SUM(QUANTITY) AS UNIT_COST FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID='" + costBO.getId() + "' AND CLOSED=0", "UNIT_COST");
+                    }
 
+                    costBO.set("UNIT_COST", UNIT_COST);
+                    costBO.set("EXTENDED_COST", UNIT_COST * Integer.parseInt(costBO.getString("QUANTITY")));
+                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST", costBO, conn);
 
+                }
                 conn.commit();
             } catch (Exception e) {
                 conn.rollback();
+                e.printStackTrace();
                 throw new BPMNError("550", "库存转移失败");
             } finally {
                 DBSql.close(conn);
             }
-
         }
-
-
     }
 
 

BIN
com.awspaas.user.apps.donenow_ivt/lib/com.awspaas.user.apps.donenow_ivt.jar


+ 42 - 18
com.awspaas.user.apps.donenow_ivt/src/com/awspaas/user/apps/donenow_ivt/controller/ivtOrderController.java

@@ -256,8 +256,7 @@ public class ivtOrderController {
         if (StringUtils.isBlank(costPdtIds))
             return ResponseObject.newErrResponse("无数据");
 
-        List<RowMap> pdtList = DBSql.getMaps("select ID,STATUS_ID,CONTRACT_COST_ID,QUANTITY,WAREHOUSE_ID from bo_eu_dnctt_contract_cost_product where FIND_IN_SET(ID,?)", new Object[]{costPdtIds});
-
+        List<RowMap> pdtList = DBSql.getMaps("select ID,STATUS_ID,CONTRACT_COST_ID,QUANTITY,WAREHOUSE_ID,SN from bo_eu_dnctt_contract_cost_product where FIND_IN_SET(ID,?)", new Object[]{costPdtIds});
 
         if (pdtList.isEmpty())
             return ResponseObject.newErrResponse("无数据");
@@ -270,9 +269,9 @@ public class ivtOrderController {
                 BO pdtBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", pdtMap.getString("ID"));
 
                 String PRODUCT_ID = DBSql.getString("select PRODUCT_ID from BO_EU_DNCTT_CONTRACT_COST where ID=?", new Object[]{pdtBO.getString("CONTRACT_COST_ID")});
-
                 pdtBO.set("STATUS_ID", "2158");//待配送
                 pdtBO.set("SHIPPING_TIME", null);
+                pdtBO.set("IS_SHIP", 0);
                 SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", pdtBO, conn);
 
                 //修改成本状态
@@ -295,30 +294,55 @@ public class ivtOrderController {
                     tsf.set("TO_ACCOUNT_ID", DBSql.getString("select account_id from bo_eu_dnctt_contract where id=?", new Object[]{costBO.getString("CONTRACT_ID")}));
                 }
                 tsf.set("TO_CONTRACT_ID", costBO.getString("CONTRACT_ID"));
+
+                tsf.set("SN", pdtMap.getString("SN"));
                 SDK.getBOAPI().create("BO_EU_DNIVT_TRANSFER", tsf, processInstance, uc, conn);
 
                 // 删除库存数修改
                 BO lctPdtBO = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT").addQuery("PRODUCT_ID=", PRODUCT_ID).addQuery("WAREHOUSE_ID=", pdtBO.getString("WAREHOUSE_ID")).detail();
 
                 if (lctPdtBO != null) {
+
+                    //序列号更新
+                    String sns = pdtMap.getString("SN");
+                    if (sns != null && !sns.isEmpty()) {
+                        //如何回到对应的批次上
+
+                        for (String sn : sns.split(",")) {
+                            BO lctPdtLotBO = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", lctPdtBO.getBindId()).addQuery("FIND_IN_SET(" + sn + ",SHIPPED_SN)", null).detail();
+                            lctPdtLotBO.set("QUANTITY", Integer.parseInt(lctPdtLotBO.getString("QUANTITY")) + 1);
+
+                            String lostSN = lctPdtLotBO.getString("SN");
+                            if (StringUtils.isNotBlank(lostSN))
+                                lctPdtLotBO.set("SN", lostSN + "," + sn);
+                            else
+                                lctPdtLotBO.set("SN", sn);
+
+                            String lostShippedSN = lctPdtLotBO.getString("SHIPPED_SN");//移除sn
+
+                            String[] lostShippedSNs = lostShippedSN.split(",");
+                            List<String> lostShippedSNsList = new ArrayList<String>();
+                            for (String lostShippedSNsItem : lostShippedSNs) {
+                                if (!lostShippedSNsItem.equals(sn))
+                                    lostShippedSNsList.add(lostShippedSNsItem);
+                            }
+                            lostShippedSN = StringUtils.join(lostShippedSNsList.toArray(), ",");
+                            lctPdtLotBO.set("SHIPPED_SN", lostShippedSN);
+                            SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lctPdtLotBO, conn);
+                        }
+
+                        String wpsn = lctPdtBO.getString("SN");
+                        if (StringUtils.isNotBlank(wpsn)) {
+                            lctPdtBO.set("SN", wpsn + "," + sns);
+                        } else {
+                            lctPdtBO.set("SN", sns);
+                        }
+                    }
+
                     lctPdtBO.set("QUANTITY", lctPdtBO.get("QUANTITY", Integer.class) + pdtBO.get("QUANTITY", Integer.class));
                     SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT", lctPdtBO, conn);
                 }
-                //序列号更新
-                List<String> sns = DBSql.getList("select sn from bo_eu_dnctt_contract_cost_product_sn where contract_cost_product_id=?", String.class, new Object[]{pdtMap.getString("ID")});
-                if (sns != null && !sns.isEmpty()) {
-                    for (String sn : sns) {
-                        BO lctPdtSn = new BO();
-                        lctPdtSn.set("SN", sn);
-                        lctPdtSn.set("WAREHOUSE_PRODUCT_ID", lctPdtBO.getId());
-                        SDK.getBOAPI().create("BO_EU_DNIVT_WAREHOUSE_PRODUCT_SN", lctPdtSn, lctPdtBO.getBindId(), uc.getUID(), conn);
-
-                        BO tsfSn = new BO();
-                        tsfSn.set("SN", sn);
-                        tsfSn.set("TRANSFER_ID", tsf.getId());
-                        SDK.getBOAPI().create("BO_EU_DNIVT_TRANSFER_SN", tsfSn, tsf.getBindId(), uc.getUID(), conn);
-                    }
-                }
+
             }
             conn.commit();
         } catch (SQLException e) {

+ 25 - 2
com.awspaas.user.apps.donenow_ivt/src/com/awspaas/user/apps/donenow_ivt/event/DoWorkThread.java

@@ -47,6 +47,10 @@ public class DoWorkThread extends Thread {
                 String BEN_RECEIVE = BigDecimalUtil.isNull(bo.getString("BEN_RECEIVE"));
                 int intBenReceive = Integer.valueOf(BEN_RECEIVE).intValue();//本次接收数量
 
+                //本次接收数量为0,则跳过
+                if (intBenReceive == 0)
+                    continue;
+
                 RowMap rowMap = DBSql.getMap("select ORDER_PRODUCT_ID,sum(QUANTITY_RECEIVED) QUANTITY_RECEIVED from BO_EU_DNIVT_RECEIVE WHERE  ORDER_PRODUCT_ID=? group by ORDER_PRODUCT_ID", new Object[]{bo.getString("ORDER_PRODUCT_ID")});
                 BO receiveBo = new BO();
                 receiveBo.set("ORDER_PRODUCT_ID", bo.get("ORDER_PRODUCT_ID"));
@@ -64,8 +68,12 @@ public class DoWorkThread extends Thread {
 
                 //更新产品的库存
                 String wareHouseProductBINDID = null;
+                int oldQuantity = 0;//全部库存数量
                 BO wareHouseProduct = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_WAREHOUSE_PRODUCT).addQuery("WAREHOUSE_ID=", bo.getString("WAREHOUSE_ID")).addQuery("PRODUCT_ID=", bo.getString("PRODUCT_ID")).detail();
                 if (wareHouseProduct != null && wareHouseProduct.isNew() == false) {
+
+                    oldQuantity = Integer.valueOf(wareHouseProduct.getString("QUANTITY")).intValue();
+
                     String add = BigDecimalUtil.add(wareHouseProduct.getString("QUANTITY"), bo.getString("BEN_RECEIVE"));
                     wareHouseProduct.set("QUANTITY", add);
                     SDK.getBOAPI().update(IVTConstant.BO_EU_DNIVT_WAREHOUSE_PRODUCT, wareHouseProduct);
@@ -97,6 +105,7 @@ public class DoWorkThread extends Thread {
                     warehouseProductLotBo.set("ORDER_PRODUCT_ID", bo.getString("ORDER_PRODUCT_ID"));
                     warehouseProductLotBo.set("IN_DATE", new Date());
                     SDK.getBOAPI().createDataBO(IVTConstant.BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT, warehouseProductLotBo, uc);
+
                 } else {
                     if (StringUtils.isNotBlank(bo.getString("SN"))) {
                         if (intBenReceive > 0)
@@ -117,6 +126,15 @@ public class DoWorkThread extends Thread {
                     SDK.getBOAPI().update(IVTConstant.BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT, warehouseProductLotBo);
                 }
 
+
+                //更新 产品信息
+                //BO_EU_DNIVT_PRODUCT 上面的 库存平均单元成本 UNIT_COST_AVG
+                BO productBo = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_PRODUCT).addQuery("ID=", warehouseProductLotBo.getString("PRODUCT_ID")).detail();
+                double UNIT_COST_AVG = Double.parseDouble(productBo.getString("UNIT_COST_AVG"));
+                UNIT_COST_AVG = (oldQuantity * UNIT_COST_AVG + intBenReceive * Double.parseDouble(bo.getString("UNIT_COST"))) / (oldQuantity + intBenReceive);
+                productBo.set("UNIT_COST_AVG", UNIT_COST_AVG);
+                SDK.getBOAPI().update(IVTConstant.BO_EU_DNIVT_PRODUCT, productBo);
+
                 //2、库存转移记录 BO_EU_DNIVT_TRANSFER
                 ProcessInstance warehouseTransferInstance = SDK.getProcessAPI().createBOProcessInstance("obj_e15a8fedeaeb43dc85aa258a7e1cffcf", uc.getUID(), "采购接收-" + warehouseProductLotBo.get("LOT"));
                 BO warehouseTransferBo = new BO();
@@ -225,10 +243,14 @@ public class DoWorkThread extends Thread {
             String orderBindId = DBSql.getString("SELECT BINDID FROM " + IVTConstant.BO_EU_DNIVT_ORDER_PRODUCT + " WHERE ID='" + list.get(0).getString("ORDER_PRODUCT_ID") + "'");
             List<BO> orderProductList = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_ORDER_PRODUCT).bindId(orderBindId).list();
             int count = 0;
+            boolean exitsReceive = false;//存在接收
             for (BO bo : orderProductList) {
                 RowMap map = DBSql.getMap("select ORDER_PRODUCT_ID,sum(QUANTITY_RECEIVED) QUANTITY_RECEIVED from BO_EU_DNIVT_RECEIVE WHERE  ORDER_PRODUCT_ID=? group by ORDER_PRODUCT_ID", new Object[]{bo.getString("ID")});
                 //采购项总共接收数量
-                int QUANTITY_RECEIVED = map.getInt("QUANTITY_RECEIVED");
+                int QUANTITY_RECEIVED = map == null ? 0 : map.getInt("QUANTITY_RECEIVED");
+                if (QUANTITY_RECEIVED > 0) {
+                    exitsReceive = true;
+                }
                 //采购项数量
                 int QUANTITY = Integer.valueOf(BigDecimalUtil.isNull(bo.getString("QUANTITY"))).intValue();
                 if (QUANTITY_RECEIVED == QUANTITY) {
@@ -261,7 +283,8 @@ public class DoWorkThread extends Thread {
                     }
                 }
 
-            } else if (count > 0) {
+            } else if (count > 0 || exitsReceive) {
+                //部分接收
                 DBSql.update("UPDATE " + IVTConstant.BO_EU_DNIVT_ORDER + " SET STATUS_ID=" + IVTConstant.STATUS_2149 + " WHERE BINDID='" + orderBindId + "'");
             } else {
                 DBSql.update("UPDATE " + IVTConstant.BO_EU_DNIVT_ORDER + " SET STATUS_ID=" + IVTConstant.STATUS_2148 + " WHERE BINDID='" + orderBindId + "'");

+ 22 - 4
com.awspaas.user.apps.donenow_ivt/src/com/awspaas/user/apps/donenow_ivt/event/reserveFormBeforeSave.java

@@ -41,18 +41,36 @@ public class reserveFormBeforeSave extends InterruptListener {
 
                 String BEN_RECEIVE = BigDecimalUtil.isNull(bo.getString("BEN_RECEIVE"));
                 int intBenReceive = Integer.valueOf(BEN_RECEIVE).intValue();
-
                 String sns = bo.getString("SN");
+                if (intBenReceive == 0) {
+                    if (StringUtils.isNotBlank(sns))
+                        throw new BPMNError("receiveErrorCode0", "本次接收数量为空,不需要输入序列号!");
+                    continue;
+                }
+
+                RowMap map = DBSql.getMap("select sum(QUANTITY_RECEIVED) QUANTITY_RECEIVED from BO_EU_DNIVT_RECEIVE WHERE  ORDER_PRODUCT_ID=?", new Object[]{bo.getString("ORDER_PRODUCT_ID")});
+
+                int QUANTITY_RECEIVED = map == null ? 0 : map.getInt("QUANTITY_RECEIVED");
+                if (intBenReceive + QUANTITY_RECEIVED < 0) {
+                    throw new BPMNError("receiveErrorCode4", "取消接收的数量不能大于已接收的数量!");
+                }
+
+                if (intBenReceive + QUANTITY_RECEIVED > Integer.parseInt(bo.getString("QUANTITY"))) {
+                    throw new BPMNError("receiveErrorCode5", "接收数量不能大于采购数量!");
+                }
+
+                //序列号产品批次号不能重复
                 if (StringUtils.isNotBlank(sns)) {
                     for (String sn : sns.split(",")) {
                         List<RowMap> exitsLots = DBSql.getMaps("select * from BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT WHERE FIND_IN_SET(?,SN)", new Object[]{sn});
                         if (exitsLots.size() > 0 && intBenReceive > 0) {
                             //已存在,不能再新增
-                            throw new BPMNError("505", sn + "已存在此序列号,不能再新增!");
+                            throw new BPMNError("receiveErrorCode1", sn + "已存在此序列号,不能再新增!");
                         }
 
                         if (intBenReceive < 0) {
-                            if (exitsLots.size() <= 0) throw new BPMNError("505", sn + "不存在此序列号,不能再删除!");
+                            if (exitsLots.size() <= 0)
+                                throw new BPMNError("receiveErrorCode2", sn + "不存在此序列号,不能再删除!");
                             else if (exitsLots.size() > 0) {
                                 boolean sameOrderProduct = false;
                                 for (RowMap rowMap : exitsLots) {
@@ -61,7 +79,7 @@ public class reserveFormBeforeSave extends InterruptListener {
                                     }
                                 }
                                 if (!sameOrderProduct) {
-                                    throw new BPMNError("505", sn + "不是此采购单接收的,不能在此采购单上取消!");
+                                    throw new BPMNError("receiveErrorCode3", sn + "不是此采购单接收的,不能在此采购单上取消!");
                                 }
                             }
                         }