|
|
@@ -14,6 +14,7 @@ import com.actionsoft.sdk.local.SDK;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.awspaas.user.apps.donenow_ivt.constant.IVTConstant;
|
|
|
import com.awspaas.user.apps.donenow_ivt.utils.BigDecimalUtil;
|
|
|
+import com.ibm.icu.math.BigDecimal;
|
|
|
import me.chanjar.weixin.common.util.StringUtils;
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
@@ -164,18 +165,60 @@ public class IVTController extends BaseController {
|
|
|
return success("");
|
|
|
}
|
|
|
|
|
|
+ @Mapping("com.awspaas.user.apps.donenow_ivt.queryExistPurchasereceive")
|
|
|
+ public String queryExistPurchasereceive(String ids, String bindId, UserContext uc) {
|
|
|
+ // 处理入参:优先用bindId查询采购项ID
|
|
|
+ String pureIds = "";
|
|
|
+ if (StringUtils.isNotBlank(bindId)) {
|
|
|
+ // 核心:通过bindId获取关联的采购项ID(和创建接口逻辑一致)
|
|
|
+ pureIds = DBSql.getString("SELECT GROUP_CONCAT(ID) from bo_eu_dnivt_order_product WHERE BINDID=?", new Object[]{bindId});
|
|
|
+ } else if (StringUtils.isNotBlank(ids)) {
|
|
|
+ pureIds = ids.trim();
|
|
|
+ if (pureIds.endsWith(",")) {
|
|
|
+ pureIds = pureIds.substring(0, pureIds.length() - 1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return "{\"code\":-1,\"msg\":\"请传入bindId或ids\"}";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(pureIds)) {
|
|
|
+ return "{\"code\":-1,\"msg\":\"无已存在的待接收接收单\"}";
|
|
|
+ }
|
|
|
|
|
|
+ String quotedIds = "'" + pureIds.replace(",", "','") + "'";
|
|
|
+ String checkSql = "SELECT DISTINCT s.BINDID FROM BO_EU_DNIVT_RECEIVE_SUB s " +
|
|
|
+ "WHERE s.ORDER_PRODUCT_ID IN (" + quotedIds + ") ";
|
|
|
+ String existBindId = DBSql.getString(checkSql, new Object[]{});
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(existBindId)) {
|
|
|
+ String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), existBindId, "", 1, "", "", "");
|
|
|
+ url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);
|
|
|
+ return "{\"code\":0,\"msg\":\"操作成功\",\"data\":\"" + url + "\"}";
|
|
|
+ } else {
|
|
|
+ return "{\"code\":-1,\"msg\":\"无已存在的待接收接收单\"}";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ *采购项接收
|
|
|
+ */
|
|
|
/**
|
|
|
*
|
|
|
*采购项接收
|
|
|
*/
|
|
|
+
|
|
|
+
|
|
|
@Mapping("com.awspaas.user.apps.donenow_ivt.purchasereceive")
|
|
|
public String purchasereceive(String ids, UserContext uc, String bindId) {
|
|
|
System.out.print("idsids:" + ids);
|
|
|
System.out.print("bindId:" + bindId);
|
|
|
|
|
|
+ // ===== 1. 订单项ID预处理 + 非空校验 =====
|
|
|
if (StringUtils.isNotBlank(ids)) {
|
|
|
- ids = ids.substring(0, ids.length() - 1);
|
|
|
+ ids = ids.trim();
|
|
|
+ if (ids.endsWith(",")) {
|
|
|
+ ids = ids.substring(0, ids.length() - 1);
|
|
|
+ }
|
|
|
} else if (StringUtils.isNotBlank(bindId)) {
|
|
|
ids = DBSql.getString("SELECT GROUP_CONCAT(ID) from bo_eu_dnivt_order_product WHERE BINDID=?", new Object[]{bindId});
|
|
|
} else {
|
|
|
@@ -184,7 +227,7 @@ public class IVTController extends BaseController {
|
|
|
ids = "'" + ids.replace(",", "','") + "'";
|
|
|
System.out.print("idsids:" + ids);
|
|
|
|
|
|
- //采购接收查询SQL
|
|
|
+ // ===== 2. 采购订单项及关联数据查询 =====
|
|
|
String sql = " select op.CONTRACT_COST_ID,a.IS_SERIALIZED,o.CREATEDATE,o.FREIGHT_COST,op.WAREHOUSE_ID,op.product_id,op.id,c.id as contract_id,p.id as project_id,t.id as task_id,op.product_id," +
|
|
|
" ifnull(c.account_id,ifnull(p.account_id,t.account_id))as account_id,b.opportunity_id," +
|
|
|
" o.vendor_account_id,if(c.name is not null,'contract',if(p.name is not null,'project'," +
|
|
|
@@ -220,90 +263,138 @@ public class IVTController extends BaseController {
|
|
|
if (maps.size() == 0) {
|
|
|
return fail("请检查采购订单是否未审批!");
|
|
|
}
|
|
|
- ProcessInstance createBOProcessInstance = SDK.getProcessAPI().createBOProcessInstance(IVTConstant.obj_3121af9039dc454aa776f9bdadf6b239, uc.getUID(), "");
|
|
|
- //校验是否是同一个采购订单
|
|
|
+
|
|
|
+ // ===== 3. 提取采购订单号 + 校验:单次只能处理同一个采购订单 =====
|
|
|
+ String purchaseOrderNo = null;
|
|
|
Set<String> set = new HashSet<String>();
|
|
|
- List<BO> list = new ArrayList<BO>();
|
|
|
for (RowMap map : maps) {
|
|
|
- if (StringUtils.isNotBlank(map.getString("PURCHASE_ORDER_NO")) && StringUtils.isNotBlank(map.getString("PURCHASE_ORDER_NO").trim())) {
|
|
|
- set.add(map.getString("PURCHASE_ORDER_NO"));
|
|
|
+ String poNo = map.getString("purchase_order_no");
|
|
|
+ if (StringUtils.isNotBlank(poNo) && StringUtils.isNotBlank(poNo.trim())) {
|
|
|
+ set.add(poNo);
|
|
|
+ purchaseOrderNo = poNo;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
if (set.size() > 1) {
|
|
|
System.out.println("setsetset:" + set);
|
|
|
-
|
|
|
return fail("一次只能接收同一个采购订单的采购项");
|
|
|
}
|
|
|
- for (RowMap orgMap : maps) {
|
|
|
|
|
|
- System.out.println("map:" + orgMap);
|
|
|
+ // ===== 4. 核心修复:防重复创建【适配主表无STATUS字段】✅✅
|
|
|
+ // 关键改动:主表仅按采购单号判断是否存在,彻底删除STATUS查询条件,杜绝报错
|
|
|
+ BO existingMainBO = null;
|
|
|
+ if (StringUtils.isNotBlank(purchaseOrderNo)) {
|
|
|
+ long count = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_RECEIVE_MAIN)
|
|
|
+ .addQuery("PURCHASE_ORDER_NO=", purchaseOrderNo)
|
|
|
+ .count();
|
|
|
+ // 只要存在同采购单号的主单,直接获取并返回,不区分状态
|
|
|
+ if (count > 0) {
|
|
|
+ existingMainBO = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_RECEIVE_MAIN)
|
|
|
+ .addQuery("PURCHASE_ORDER_NO=", purchaseOrderNo)
|
|
|
+ .detail();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- Map<String, Object> map = convertKeysToUppercase(orgMap);
|
|
|
+ // ===== 5. 存在已有单据,直接返回URL,终止创建(重复打开不报错)✅✅
|
|
|
+ if (existingMainBO != null) {
|
|
|
+ String processInstanceId = existingMainBO.getBindId();
|
|
|
+ String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), processInstanceId, "", 1, "", "", "");
|
|
|
+ url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);
|
|
|
+ return success(url);
|
|
|
+ }
|
|
|
|
|
|
- //采购数量不能为空,也不能小于0
|
|
|
- Object purchaseQuantity = map.get("QUANTITY");
|
|
|
+ // ===== 6. 初始化流程实例ID(主/子表绑定)=====
|
|
|
+ ProcessInstance createBOProcessInstance = SDK.getProcessAPI().createBOProcessInstance(IVTConstant.obj_3121af9039dc454aa776f9bdadf6b239, uc.getUID(), "");
|
|
|
|
|
|
- System.out.println("purchaseQuantity:" + purchaseQuantity);
|
|
|
- if (purchaseQuantity == null || StringUtils.isBlank(purchaseQuantity.toString()) || Double.parseDouble(purchaseQuantity.toString()) <= 0) {
|
|
|
+ // ===== 7. 构建采购接收子表数据(子表独有STATUS,初始待接收)✅✅
|
|
|
+ List<BO> list = new ArrayList<BO>();
|
|
|
+ for (RowMap orgMap : maps) {
|
|
|
+ System.out.println("map:" + orgMap);
|
|
|
+ // 原生RowMap取值,无方法歧义、零报错
|
|
|
+ String opId = orgMap.getString("id");
|
|
|
+ String productName = orgMap.getString("product_name");
|
|
|
+ String warehouseId = orgMap.getString("warehouse_id");
|
|
|
+ String accountName = orgMap.getString("account_name");
|
|
|
+ String contracName = orgMap.getString("contrac_project_task_name");
|
|
|
+ String productId = orgMap.getString("product_id");
|
|
|
+ String contractCostId = orgMap.getString("contract_cost_id");
|
|
|
+ String isSerialized = orgMap.getString("IS_SERIALIZED");
|
|
|
+ Object quantityObj = orgMap.get("quantity");
|
|
|
+ Object onHandObj = orgMap.get("on_hand");
|
|
|
+
|
|
|
+ // 过滤无效项:采购数量为空/≤0 跳过
|
|
|
+ if (quantityObj == null || StringUtils.isBlank(quantityObj.toString()) || Double.parseDouble(quantityObj.toString()) <= 0) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- String unBack = "0";
|
|
|
+ int totalQty = Integer.parseInt(quantityObj.toString());
|
|
|
BO subBo = new BO();
|
|
|
- set.add(getString(map, "PURCHASE_ORDER_NO"));
|
|
|
- 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[]{getString(map, "ID")});
|
|
|
- if (null != rowMap) {
|
|
|
- unBack = getUnBack(getString(map, "QUANTITY"), rowMap.getString("QUANTITY_RECEIVED"));
|
|
|
- if (Integer.valueOf(unBack) <= 0) {
|
|
|
- // System.out.println("采购数量小于已接收数量:" +getString(map,"QUANTITY") + "-----" + rowMap.getString("QUANTITY_RECEIVED"));
|
|
|
- // continue;
|
|
|
- }
|
|
|
- subBo.set("QUANTITY_RECEIVED", rowMap.get("QUANTITY_RECEIVED"));
|
|
|
- subBo.set("QUANTITY_BACKORDERED", unBack);
|
|
|
- } else {
|
|
|
- subBo.set("QUANTITY_RECEIVED", 0);
|
|
|
- subBo.set("QUANTITY_BACKORDERED", map.get("QUANTITY"));
|
|
|
+ int historyReceive = 0;
|
|
|
+
|
|
|
+ // 查询子表历史累计接收数(子表有数据统计能力)
|
|
|
+ RowMap rowMap = DBSql.getMap(
|
|
|
+ "select sum(QUANTITY_RECEIVED) QUANTITY_RECEIVED from BO_EU_DNIVT_RECEIVE_SUB WHERE ORDER_PRODUCT_ID=? group by ORDER_PRODUCT_ID",
|
|
|
+ new Object[]{opId}
|
|
|
+ );
|
|
|
+ if (null != rowMap && rowMap.get("QUANTITY_RECEIVED") != null) {
|
|
|
+ historyReceive = Integer.parseInt(rowMap.get("QUANTITY_RECEIVED").toString());
|
|
|
}
|
|
|
- subBo.set("PRODUCT_NAME", map.get("PRODUCT_NAME"));
|
|
|
- subBo.set("IS_SERIALIZED", map.get("IS_SERIALIZED"));
|
|
|
- subBo.set("WAREHOUSE_ID", map.get("WAREHOUSE_ID"));
|
|
|
- subBo.set("ACCOUNT_NAME", map.get("ACCOUNT_NAME"));
|
|
|
- subBo.set("CONTRAC_PROJECT_TASK_NAME", map.get("CONTRAC_PROJECT_TASK_NAME"));
|
|
|
- subBo.set("QUANTITY", map.get("QUANTITY"));
|
|
|
- subBo.set("ON_HAND", map.get("ON_HAND"));
|
|
|
- subBo.set("PRODUCT_ID", map.get("PRODUCT_ID"));
|
|
|
- subBo.set("ORDER_PRODUCT_ID", map.get("ID"));
|
|
|
- subBo.set("NOW_COUNT", 0);
|
|
|
- subBo.set("CONTRACT_COST_ID", map.get("CONTRACT_COST_ID"));
|
|
|
+
|
|
|
+ // 正确计算字段初始值
|
|
|
+ int totalReceive = historyReceive; // 累计接收数=历史数,初始0
|
|
|
+ String unBack = String.valueOf(totalQty - totalReceive); // 未收货=采购数-历史数
|
|
|
+
|
|
|
+ // ✅ 核心:子表设置STATUS,初始强制为【待接收】,手动填数后由业务端更新
|
|
|
subBo.set("STATUS", "待接收");
|
|
|
- subBo.set("WHOLE", DBSql.getInt("select count(1) AS CNT from BO_EU_DNCTT_CONTRACT_COST where ID=? AND IS_SERVICE_PRODUCT=1", new Object[]{map.get("CONTRACT_COST_ID")}));//判断是否整体接收
|
|
|
+ // ✅ 本次接收数初始0,必须手动输入保存后生效
|
|
|
+ subBo.set("NOW_COUNT", 0);
|
|
|
+
|
|
|
+ // 子表字段赋值(完整、无遗漏)
|
|
|
+ subBo.set("QUANTITY_RECEIVED", totalReceive);
|
|
|
+ subBo.set("QUANTITY_BACKORDERED", unBack);
|
|
|
+ subBo.set("PRODUCT_NAME", productName);
|
|
|
+ subBo.set("IS_SERIALIZED", isSerialized);
|
|
|
+ subBo.set("WAREHOUSE_ID", warehouseId);
|
|
|
+ subBo.set("ACCOUNT_NAME", accountName);
|
|
|
+ subBo.set("CONTRAC_PROJECT_TASK_NAME", contracName);
|
|
|
+ subBo.set("QUANTITY", totalQty);
|
|
|
+ subBo.set("ON_HAND", onHandObj);
|
|
|
+ subBo.set("PRODUCT_ID", productId);
|
|
|
+ subBo.set("ORDER_PRODUCT_ID", opId);
|
|
|
+ subBo.set("CONTRACT_COST_ID", contractCostId);
|
|
|
+
|
|
|
+ // 查询WHOLE字段值
|
|
|
+ int whole = DBSql.getInt("select count(1) AS CNT from BO_EU_DNCTT_CONTRACT_COST where ID=? AND IS_SERVICE_PRODUCT=1", new Object[]{contractCostId});
|
|
|
+ subBo.set("WHOLE", whole);
|
|
|
+
|
|
|
subBo.setBindId(createBOProcessInstance.getId());
|
|
|
list.add(subBo);
|
|
|
}
|
|
|
+
|
|
|
+ // 无有效子表数据,返回失败
|
|
|
if (list.size() == 0) {
|
|
|
return fail("采购订单项都已经接收完毕");
|
|
|
}
|
|
|
- //采购接收主表添加数据
|
|
|
+
|
|
|
+ // ===== 8. 创建采购接收主表数据(无STATUS字段,适配表结构)✅✅
|
|
|
RowMap rowMap = maps.get(0);
|
|
|
BO detail = SDK.getBOAPI().query(IVTConstant.BO_EU_DNIVT_ORDER).addQuery("PURCHASE_ORDER_NO=", rowMap.getString("purchase_order_no")).detail();
|
|
|
if (null == detail) {
|
|
|
return fail("未找到对应的订单");
|
|
|
}
|
|
|
- //主表数据
|
|
|
+
|
|
|
BO bo = new BO();
|
|
|
bo.setBindId(createBOProcessInstance.getId());
|
|
|
- bo.setId(UUIDGener.getUUID());
|
|
|
+ bo.setId(UUID.randomUUID().toString().replace("-",""));
|
|
|
bo.set("COMPANY", rowMap.getString("vendor"));
|
|
|
bo.set("PURCHASE_ORDER_NO", rowMap.getString("purchase_order_no"));
|
|
|
bo.set("SUBMIT_TIME", rowMap.get("CREATEDATE"));
|
|
|
- bo.set("VENDOR_INVOICE_NO", rowMap.get("VENDOR_INVOICE_NO"));
|
|
|
bo.set("FREIGHT_COST", rowMap.get("FREIGHT_COST"));
|
|
|
SDK.getBOAPI().create(IVTConstant.BO_EU_DNIVT_RECEIVE_MAIN, bo, createBOProcessInstance, uc);
|
|
|
|
|
|
- //子表数据
|
|
|
+ // ===== 9. 创建采购接收子表数据(携带STATUS字段)=====
|
|
|
SDK.getBOAPI().create(IVTConstant.BO_EU_DNIVT_RECEIVE_SUB, list, createBOProcessInstance, uc);
|
|
|
|
|
|
+ // ===== 10. 生成单据URL并返回 =====
|
|
|
String url = SDK.getFormAPI().getFormURL("", uc.getSessionId(), createBOProcessInstance.getId(), "", 1, "", "", "");
|
|
|
url = SDK.getPortalAPI().getPortalUrl() + "/r" + url.substring(1);
|
|
|
return success(url);
|