diff --git a/arap/src/public/nc/api/arap/resource/GatheringbillRestResource.java b/arap/src/public/nc/api/arap/resource/GatheringbillRestResource.java index ffbb5bd..2b21399 100644 --- a/arap/src/public/nc/api/arap/resource/GatheringbillRestResource.java +++ b/arap/src/public/nc/api/arap/resource/GatheringbillRestResource.java @@ -138,7 +138,7 @@ public class GatheringbillRestResource extends ArapBaseRestResource { Object tr = dao.executeQuery( "select ntaxrate from so_saleorder_b where csaleorderid = '" + csaleorderid + "'", new ColumnProcessor()); - //ntaxrate = new UFDouble(tr.toString()); + // ntaxrate = new UFDouble(tr.toString()); // 税码 Object ctaxcodeid = hybo.findColValue("so_saleorder_b", "ctaxcodeid", "csaleorderid = '" + csaleorderid + "' "); @@ -271,6 +271,9 @@ public class GatheringbillRestResource extends ArapBaseRestResource { HYSuperDMO dmo = new HYSuperDMO(); SaleOrderHVO[] hvo = (SaleOrderHVO[]) dmo.queryByWhereClause(SaleOrderHVO.class, "vbillcode='" + def2 + "' and dr=0"); + if (hvo == null || hvo.length == 0) { + throw new BusinessException("该销售订单在ERP中被删除,订单号:" + def2); + } SaleOrderBVO[] bvos = (SaleOrderBVO[]) dmo.queryByWhereClause(SaleOrderBVO.class, "csaleorderid='" + hvo[0].getPrimaryKey() + "'"); if (bvos != null) { diff --git a/ic/src/private/nc/bs/ic/m45/sign/SignBP.java b/ic/src/private/nc/bs/ic/m45/sign/SignBP.java new file mode 100644 index 0000000..a52e3dd --- /dev/null +++ b/ic/src/private/nc/bs/ic/m45/sign/SignBP.java @@ -0,0 +1,61 @@ +package nc.bs.ic.m45.sign; + +import com.yonyou.cloud.ncc.plugin.entity.OperationInfo; +import nc.bs.ic.general.sign.ISignBP; +import nc.bs.ic.general.sign.ISignRuleProvider; +import nc.bs.ic.general.sign.SignBPTemplate; +import nc.bs.ic.m45.sign.rule.AfterSigningSynchronizeRuleMES; +import nc.bs.ic.m45.base.BPPlugInPoint; +import nc.bs.ic.m45.insert.rule.InsertOrSignRewritePayPlanInvoiceRule; +import nc.bs.ic.m45.sign.rule.*; +import nc.bs.ic.pub.util.DebugUtils; +import nc.bs.ic.pub.util.SagasUtils; +import nc.bs.scmpub.rule.VOSagaFrozenValidateRule; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.itf.ic.m45.compensate.IPurchaseInSagasCompensate; +import nc.vo.ic.m45.entity.PurchaseInVO; +import nc.vo.ic.pub.util.VOEntityUtil; +import nc.vo.scmpub.res.billtype.ICBillType; +import nccloud.bs.ic.mobile.inbound.operation.rewrite.MobAfterPurchaseInSign; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +public class SignBP implements ISignBP, ISignRuleProvider { + public SignBP() { + } + + public PurchaseInVO[] sign(PurchaseInVO[] bills) { + DebugUtils.debug("purchasein-sign-begin"); + SignBPTemplate signBP = new SignBPTemplate(BPPlugInPoint.SignAction, this); + SagasUtils.frozenAndAddSaga(bills, ICBillType.PurchaseIn.getCode(), "1", (OperationInfo) null); + Map paramMap = new HashMap(); + paramMap.put("actionname", "sign_45"); + paramMap.put("hid", VOEntityUtil.getPksFromAggVO(bills)); + paramMap.put("vos", bills); + SagasUtils.compensate(paramMap, IPurchaseInSagasCompensate.class); + PurchaseInVO[] resultVOs = (PurchaseInVO[]) signBP.sign(bills); + DebugUtils.debug("purchasein-sign-end"); + return resultVOs; + } + + public void addAfterRule(PurchaseInVO[] vos, AroundProcesser processor) { + processor.addAfterRule(new SignRewritePayPlanConfirmDataRule()); + processor.addAfterRule(new InsertOrSignRewritePayPlanInvoiceRule("1001Z01000000000F04P")); + processor.addAfterRule(new AfterRuleForRewritePUSettle()); + processor.addAfterRule(new AfterRuleForPush5X()); + processor.addAfterRule(new AfterSignRuleForFinanceProcess()); + processor.addAfterRule(new AfterSignRuleForLiabilityProcess()); + processor.addAfterRule(new MobAfterPurchaseInSign()); + processor.addAfterRule(new SignM45AndRewriteCTPayPlan()); + processor.addAfterRule(new SignInsertFeeDetailRule()); + // 签字后推送至MES系统 + processor.addAfterRule(new AfterSigningSynchronizeRuleMES()); + } + + public void addBeforeRule(PurchaseInVO[] vos, AroundProcesser processor) { + processor.addBeforeRule(new VOSagaFrozenValidateRule(true)); + processor.addBeforeRule(new BeforeRuleForCheckPU()); + } +} diff --git a/ic/src/private/nc/bs/ic/m45/sign/rule/AfterSigningSynchronizeRuleMES.java b/ic/src/private/nc/bs/ic/m45/sign/rule/AfterSigningSynchronizeRuleMES.java new file mode 100644 index 0000000..ed0227c --- /dev/null +++ b/ic/src/private/nc/bs/ic/m45/sign/rule/AfterSigningSynchronizeRuleMES.java @@ -0,0 +1,270 @@ +package nc.bs.ic.m45.sign.rule; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.vo.bd.material.MaterialVO; +import nc.vo.bd.material.measdoc.MeasdocVO; +import nc.vo.bd.psn.PsndocVO; +import nc.vo.bd.stordoc.StordocVO; +import nc.vo.bd.supplier.SupplierVO; +import nc.vo.cmp.util.StringUtils; +import nc.vo.ic.m45.entity.PurchaseInVO; +import nc.vo.ic.m45.entity.PurchaseInBodyVO; +import nc.vo.ic.m45.entity.PurchaseInHeadVO; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDate; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; +import nc.vo.vorg.DeptVersionVO; +import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; + +/** + * 采购收货单签字后推送MES系统 + */ +public class AfterSigningSynchronizeRuleMES implements IRule { + private static final String PURCHASE_IN_URL = "/GTHINKING/AjaxService/N_CGSJJSA/102223002.ashx/CGSH_INSERT"; // 采购收货单同步接口 + private static final String logginfo = "OALOG"; + private static final Log obmlog = Log.getInstance(logginfo); + private static final BaseDAO dao = new BaseDAO(); + + @Override + public void process(PurchaseInVO[] purchaseInVOS) { + try { + if (purchaseInVOS == null || purchaseInVOS.length == 0) { + return; + } + + // 检查并筛选采购收货单 + List filteredPurchaseInVOS = checkAndFilterBills(purchaseInVOS); + if (filteredPurchaseInVOS.isEmpty()) { + return; + } + + // 初始化HTTP请求工具类 + IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class); + + // 处理每个采购收货单 + for (PurchaseInVO purchaseInVO : filteredPurchaseInVOS) { + PurchaseInHeadVO head = purchaseInVO.getHead(); + PurchaseInBodyVO[] bodys = purchaseInVO.getBodys(); + // 构建要发送的数据 + JSONObject syncData = buildSyncData(head, bodys); + // 发送数据到MES系统 + httpPostOtherSys.sendToExternalSystem(PURCHASE_IN_URL, syncData); + } + } catch (Exception e) { + obmlog.error("AfterSigningSynchronizeRuleMES-处理异常:" + e.getMessage(), e); + ExceptionUtils.wrappException(e); + } + } + + /** + * 检查并筛选需要同步的单据 + */ + private List checkAndFilterBills(PurchaseInVO[] purchaseInVOS) throws BusinessException { + List result = new ArrayList<>(); + + for (PurchaseInVO vo : purchaseInVOS) { + // 检查组织是否为电缆组织 + if (vo.getHead() != null && "0001A110000000000677".equals(vo.getHead().getPk_org())) { + result.add(vo); + } + } + + return result; + } + + /** + * 构建明细数据 + */ + private JSONArray buildDetailsData(PurchaseInBodyVO[] bodys) throws BusinessException { + JSONArray details = new JSONArray(); + if (bodys != null) { + for (PurchaseInBodyVO body : bodys) { + JSONObject detailItem = new JSONObject(); + // 收货单号(必填) + detailItem.put("orderNo", null); + // 收货单序号(必填)- 使用正确的表体字段crowno + detailItem.put("orderSn", body.getCrowno()); + // 事务类型(必填)- 使用表体字段cbodytranstypecode + detailItem.put("type", null); + // 分类(必填)- H:货款, F:费用, L:劳务 + detailItem.put("costOrder", null); + // 采购订单号 - 来源单据号vsourcebillcode + detailItem.put("poNo", body.getVsourcebillcode()); + // 采购订单序号 - 来源单据行号vsourcerowno + detailItem.put("poSn", body.getVsourcerowno()); + // 物料编码(必填) + String materialCode = transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, + MaterialVO.PK_MATERIAL, body.getCmaterialvid()); + detailItem.put("materialId", materialCode); + // 计量单位(必填)- 使用单位castunitid而不是主单位cunitid + detailItem.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, body.getCastunitid())); + // 物料批号 + detailItem.put("batchNum", null); + // 制令号 - 在PurchaseInBodyVO中没有直接对应字段,可以从vdef字段获取 + detailItem.put("productNum", null); // 假设vdef1存储制令号 + // 换算系数(必填) + String scaleFactor = body.getVchangerate(); + detailItem.put("scaleFactor", transferSpecialField(scaleFactor)); + // TODO 文档必填但是没有对应关系(必填) + UFDouble taxRate = body.getNtaxrate(); + detailItem.put("taxRate", taxRate != null ? taxRate.getDouble() : null); + // 应收数量(必填)- 使用nshouldassistnum + UFDouble recQty = body.getNshouldassistnum(); + detailItem.put("recQty", recQty != null ? recQty.getDouble() : null); + // 主应收数量(必填)- 使用nshouldnum + UFDouble mainRecQty = body.getNshouldnum(); + detailItem.put("mainRecQty", mainRecQty != null ? mainRecQty.getDouble() : null); + // 辅应收数量 - 这可能是自定义字段 + detailItem.put("assitRecQty", null); + // 原币含税价格 - + UFDouble priceIncludeTax = body.getNpickupnum(); + detailItem.put("priceIncludeTax", priceIncludeTax != null ? priceIncludeTax.getDouble() : null); + // 原币含税金额 - 使用norigtaxmny + UFDouble amountIncludeTax = body.getNorigtaxmny(); + detailItem.put("amountIncludeTax", amountIncludeTax != null ? amountIncludeTax.getDouble() : null); + // 原币无税价格 - + UFDouble priceNoTax = body.getNorigprice(); + detailItem.put("priceNoTax", priceNoTax != null ? priceNoTax.getDouble() : null); + // 原币无税金额 - 使用norigmny + UFDouble amountNoTax = body.getNqtnetprice(); + detailItem.put("amountNoTax", amountNoTax != null ? amountNoTax.getDouble() : null); + // 税额 - 使用ntax + UFDouble taxAmount = body.getNtax(); + detailItem.put("taxAmount", taxAmount != null ? taxAmount.getDouble() : null); + // 备注 - 使用vnotebody + detailItem.put("remark", body.getVnotebody()); + // 原收货单信息 + detailItem.put("oldOrderNo", null); + detailItem.put("oldOrderSn", null); + details.add(detailItem); + } + } + return details; + } + + /** + * 构建符合MES系统接口规范的请求数据 + */ + private JSONObject buildSyncData(PurchaseInHeadVO head, PurchaseInBodyVO[] bodys) throws BusinessException { + // 创建请求数据 + JSONObject requestData = new JSONObject(); + JSONObject data = new JSONObject(); + + // 设置收货单主表信息 + // 收货单号(必填) + data.put("orderNo", head.getVbillcode()); + // 收货日期 + UFDate dbilldate = head.getDbilldate(); + data.put("orderDate", dbilldate != null ? dbilldate.toString().substring(0, 10) : null); + // 收货类型 + data.put("orderType", "P"); + // 事务类型 + data.put("type", null); + // 仓库编码 + String storeId = transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.CODE, + StordocVO.PK_STORDOC, head.getCwarehouseid()); + data.put("storeId", storeId); + + // 采购部门ID(必填)- 注意:根据字段字典,采购部门字段为cdptid而不是cdeptid + String departmentId = transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE, + DeptVersionVO.PK_VID, head.getCdptvid()); + data.put("departmentId", departmentId); + // 采购员 - 采购员字段为cbizid + String purchaser = transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.CODE, + PsndocVO.PK_PSNDOC, head.getCbizid()); + data.put("purchaser", purchaser); + // 供应商编码(必填) + String supplyId = transferCodeByPk(SupplierVO.getDefaultTableName(), SupplierVO.CODE, + SupplierVO.PK_SUPPLIER, head.getCvendorid()); + data.put("supplyId", supplyId); + // 货币ID + data.put("currency", null); + // 汇率(必填) + data.put("rate", null); + // 结算方式 + data.put("settleType", null); + // 开票依据 + data.put("billBasis", null); + // 生成方式(必填)- P:按采购订单, Z:直接生成 + data.put("genType", "P"); + // 分类(必填)- N:货物, Y:费用 + data.put("costOrder", "N"); + // 是否退货(必填)- N:否, Y:是 + data.put("returned", head.getFreplenishflag()); + // 备注 + data.put("remark", head.getVnote()); + // 维护人信息 + data.put("creatorNo", null); // 创建人 + data.put("creator", head.getBillmaker()); // 制单人 + data.put("creatTime", head.getDmakedate() != null ? head.getCreationtime().toString() : null); // 创建时间 + + // 构建明细数据 + JSONArray details = buildDetailsData(bodys); + data.put("Details", details); + requestData.put("Data", data); + + obmlog.debug("AfterSigningSynchronizeRuleMES-采购收货单请求数据: " + requestData.toJSONString()); + + return requestData; + } + + /** + * 转换特殊字段 如 1/1 转换为小数 1.0 + */ + + private String transferSpecialField(String field) { + if (field == null || field.trim().isEmpty()) { + return null; + } + String[] split = field.split("/"); + if (split.length == 2) { + String numStr = split[0].trim(); + String denStr = split[1].trim(); + + if (denStr.equals("0")) { + return "0.00"; // 分母不能为零 + } + + try { + BigDecimal numerator = new BigDecimal(numStr); + BigDecimal denominator = new BigDecimal(denStr); + return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString(); + } catch (NumberFormatException e) { + return field; // 非法数字,返回原字段 + } + } + return field; + } + + /** + * 根据主键查询编码 + */ + private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { + if (StringUtils.isEmpty(pk)) { + return null; + } + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select " + selectField); + sqlBuilder.append(" from " + tableName); + sqlBuilder.append(" where "); + sqlBuilder.append(pkField, pk); + Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); + if (o == null) { + throw new BusinessException("未查询到编码信息,sql【" + sqlBuilder + "】"); + } + return o.toString(); + } +} diff --git a/ic/src/private/nc/bs/ic/m4c/sign/SignBP.java b/ic/src/private/nc/bs/ic/m4c/sign/SignBP.java index 5756daa..f93fa3a 100644 --- a/ic/src/private/nc/bs/ic/m4c/sign/SignBP.java +++ b/ic/src/private/nc/bs/ic/m4c/sign/SignBP.java @@ -50,11 +50,13 @@ public class SignBP implements ISignBP, ISignRuleProvider processor.addAfterRule(new ArsubToVoucherRule()); processor.addAfterRule(new SaleOutProceedsRuleCG()); processor.addAfterRule(new MobAfterSignMessageRule()); + // 销售出库 多一个步骤 先提交销售交货单 与同步销售出库单的orderNo一致 + processor.addAfterRule(new SalesDeliveryOrderRuleMES()); // 销售出库 签字后 同步到MES金思维系统 processor.addAfterRule(new AfterSigningSynchronizeRuleMES()); // 盘点(审批后传MES) - // 销售出库 签字后 同步到锐制 + // 销售出库签字后 同步到锐制 processor.addAfterRule(new AfterSigningSynchronizeRuleRZ()); } diff --git a/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleMES.java b/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleMES.java index 93bad7a..b38d1d0 100644 --- a/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleMES.java +++ b/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleMES.java @@ -8,6 +8,7 @@ import nc.bs.framework.common.NCLocator; import nc.bs.logging.Log; import nc.impl.pubapp.pattern.rule.IRule; import nc.jdbc.framework.processor.ColumnProcessor; +import nc.vo.bd.currtype.CurrtypeVO; import nc.vo.bd.cust.CustomerVO; import nc.vo.bd.material.MaterialVO; import nc.vo.bd.material.measdoc.MeasdocVO; @@ -20,9 +21,13 @@ import nc.vo.ic.m4c.entity.SaleOutVO; import nc.vo.org.DeptVO; import nc.vo.pub.BusinessException; import nc.vo.pub.lang.UFDate; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; import nc.vo.pubapp.pattern.pub.SqlBuilder; import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; +import net.sf.mpxj.primavera.schema.CurrencyType; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.SimpleDateFormat; @@ -31,10 +36,9 @@ import java.text.SimpleDateFormat; */ public class AfterSigningSynchronizeRuleMES implements IRule { private static final String SALE_OUT_URL = "/GTHINKING/AjaxService/N_MISPRO/SaleOrderOutbound.ashx/SaveData"; // 销售出库登记接口 - private static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static final String logginfo = "OALOG"; private static final Log obmlog = Log.getInstance(logginfo); - private static BaseDAO dao = new BaseDAO(); + private static final BaseDAO dao = new BaseDAO(); public AfterSigningSynchronizeRuleMES() { } @@ -55,14 +59,12 @@ public class AfterSigningSynchronizeRuleMES implements IRule { JSONObject syncData = buildSyncData(hvo, bvos); if (syncData != null) { // 发送数据到金思维系统(使用HttpPostOtherSysImpl处理网络请求) - String mesResponse = httpPostOtherSys.callMes(SALE_OUT_URL, syncData); - obmlog.debug("AfterSigningSynchronizeRule-金思维系统响应: " + mesResponse); - // 解析响应,处理结果 - processResponse(hvo.getVbillcode(), mesResponse); + httpPostOtherSys.sendToExternalSystem(SALE_OUT_URL, syncData); } } } catch (Exception e) { obmlog.error("AfterSigningSynchronizeRule-处理异常:" + e.getMessage(), e); + ExceptionUtils.wrappException(e); } } @@ -77,128 +79,118 @@ public class AfterSigningSynchronizeRuleMES implements IRule { return null; } JSONObject requestData = new JSONObject(); - requestData.put("operation_type", "I"); - JSONObject info = new JSONObject(); - // 主表数据 - 根据字典字段映射 - info.put("orderNo", hvo.getVbillcode()); // 提货单ID - 单据号(vbillcode) + JSONObject dataObj = new JSONObject(); + // 主表数据 - 需要手输入 + dataObj.put("orderNo", hvo.getVbillcode()); // 收货单号 - 单据号(vbillcode) // 日期格式转换 UFDate dbilldate = hvo.getDbilldate(); - info.put("orderDate", dbilldate.toString()); // 提单日期 - 单据日期(dbilldate) - info.put("planDate", dbilldate.toString()); // 计划日期 - 使用同样的单据日期 - info.put("actureDate", dbilldate.toString()); - info.put("genType", null); - info.put("type", "XSCK"); + dataObj.put("orderDate", dbilldate.toString().substring(0, 10)); // 收货日期 - 单据日期(dbilldate),格式:yyyy-MM-dd + dataObj.put("planDate", dbilldate.toString().substring(0, 10)); // 计划日期 - 单据日期(dbilldate),格式:yyyy-MM-dd + dataObj.put("actureDate", dbilldate.toString().substring(0, 10)); // 实际日期 - 单据日期(dbilldate),格式:yyyy-MM-dd + dataObj.put("orderType", null); // 收货类型 - 无对应字段 + dataObj.put("type", "XSCK"); // 事务类型 - 销售出库 // 部门ID - 部门(cdptvid) - info.put("departmentId", transferCodeByPk(DeptVO.getDefaultTableName(), DeptVO.CODE, DeptVO.PK_DEPT, hvo.getCdptvid())); - // 仓库ID - 仓库(cwarehouseid) - info.put("storeId", transferCodeByPk(RackVO.getDefaultTableName(), RackVO.CODE, RackVO.PK_RACK, hvo.getCwarehouseid())); - // TODO - info.put("exRate", null); - info.put("sType", "N"); // 发出默认值 - info.put("billing", "Y"); // 出具发票默认值 - info.put("billingBasis", "S"); // 开票依据默认值 - info.put("effDate", null); - info.put("consignStoreId", null); // 寄售仓库ID - info.put("consignType", null); // 寄售事务类型 - info.put("operatorNo", null); // 经办人工号 - 制单人(billmaker) - info.put("operatorName", null); // 经办人 - // 保管员 - 库管员(cwhsmanagerid) - info.put("storeKeeper", transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.CODE, PsndocVO.PK_PSNDOC, hvo.getCwhsmanagerid())); - // 保管员ID - 库管员(cwhsmanagerid) - info.put("cwhsmanagerid", transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.CODE, PsndocVO.PK_PSNDOC, hvo.getCwhsmanagerid())); - // 客户ID - 订单客户(ccustomerid) - info.put("customId", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, hvo.getCcustomerid())); - info.put("mark", "Y"); // 生成标志默认值 - info.put("remark", hvo.getVnote()); // 备注 - 备注(vnote) - // 构建details明细数组 + dataObj.put("departmentId", transferCodeByPk(DeptVO.getDefaultTableName(), + DeptVO.CODE, DeptVO.PK_DEPT, hvo.getCdptvid())); // 采购部门ID + // 仓库编码 - 仓库(cwarehouseid) + dataObj.put("storeId", transferCodeByPk(RackVO.getDefaultTableName(), + RackVO.CODE, RackVO.PK_RACK, hvo.getCwarehouseid())); // 仓库编码 + + + // 采购员 - 业务员(cbizpersonid) + dataObj.put("purchaser", transferCodeByPk(PsndocVO.getDefaultTableName(), + PsndocVO.CODE, PsndocVO.PK_PSNDOC, hvo.getCbizid())); + + // 客户ID - 订单客户(ccustomerid),这里因为是采购所以用供应商映射 + dataObj.put("supplyId", transferCodeByPk(CustomerVO.getDefaultTableName(), + CustomerVO.CODE, CustomerVO.PK_CUSTOMER, hvo.getCcustomerid())); + // 发出 + dataObj.put("sType", "N"); + //出具发票 + dataObj.put("billing", "Y"); + //开票依据 + dataObj.put("billingBasis", "S"); + //有效日期 + dataObj.put("effDate", null); + //寄售仓库ID + dataObj.put("consignStoreId", null); + //寄售事务类型 + dataObj.put("consignType", null); + //经办人工号 + dataObj.put("operatorNo", null); + //经办人 + dataObj.put("operatorName", null); + //保管员 + dataObj.put("storeKeeper", null); + //客户ID + dataObj.put("customId", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, hvo.getCcustomerid())); + //生成标志 + dataObj.put("mark", "Y"); + //备注 + dataObj.put("remark", hvo.getVnote()); + + + // 构建Details明细数组 JSONArray details = new JSONArray(); if (bvos != null) { for (SaleOutBodyVO bvo : bvos) { - JSONObject detail = new JSONObject(); - detail.put("orderNo", hvo.getVbillcode()); // 提货单ID - 单据号(vbillcode) - detail.put("sequenceNum", bvo.getCrowno()); - // 来源单据信息 - 根据字典正确映射 - detail.put("saleOrderNo", null); // SOID - 来源单据号(vsourcebillcode) - detail.put("saleSequenceNum", null); // SO序号 - 来源单据行号(vsourcerowno) - detail.put("allocationNum", null); // 分配号 - // 物料ID - 物料(cmaterialoid) - detail.put("materialId", transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, bvo.getCmaterialoid())); - // 计量单位 - 主单位(cunitid) - detail.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, bvo.getCunitid())); - detail.put("productNum", null); - // 库位 - 货位(clocationid) - detail.put("storageId", transferCodeByPk(RackVO.getDefaultTableName(), RackVO.CODE, RackVO.PK_RACK, bvo.getClocationid())); - // 物料批号 - 批次号(vbatchcode) - detail.put("batchNum", bvo.getVbatchcode()); - detail.put("scaleFactor", bvo.getVchangerate()); - // 应发数量和实发数量 - detail.put("issuedQty", bvo.getNshouldassistnum()); // 应发数量(nshouldassistnum) - detail.put("mIssuedQty", bvo.getNshouldnum()); // 主应发数量(nshouldnum) - detail.put("actQry", bvo.getNassistnum()); // 实发数量(nassistnum) - detail.put("mActQry", bvo.getNnum()); // 主实发数量(nnum) - detail.put("assistActQry", null); // 辅助实发数量(nassistnum) - // 客户信息 - // 客户ID - 客户(casscustid) - detail.put("customId", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, bvo.getCasscustid())); - // 供应商信息 - // 供应商ID - 供应商(cvendorid) - detail.put("supplierId", transferCodeByPk(SupplierVO.getDefaultTableName(), SupplierVO.CODE, SupplierVO.PK_SUPPLIER, bvo.getCvendorid())); - detail.put("color", null); - // 生产日期 - detail.put("manufactureDate", null); // 生产日期(dproducedate) - detail.put("properties", null); - detail.put("remark", bvo.getVnotebody()); // 备注 - 行备注(vnotebody) + // 汇率 + dataObj.put("exRate", bvo.getNchangestdrate()); + JSONObject detail = new JSONObject(); + detail.put("orderNo", hvo.getVbillcode()); // 提货单ID - 单据号(vbillcode) - 必填 + detail.put("sequenceNum", bvo.getCrowno()); // 提货单序号 - 行号(crowno) - 必填 + detail.put("type", "XSCK"); // 事务类型 - 默认XSCK + + // 来源单据信息 + detail.put("saleOrderNo", bvo.getVsourcebillcode()); // SOID - 来源单据号(vsourcebillcode) + detail.put("saleSequenceNum", bvo.getVsourcerowno()); // SO序号 - 来源单据行号(vsourcerowno) + detail.put("allocationNum", null); // 分配号 + + // 物料信息 - 必填 + detail.put("materialId", transferCodeByPk(MaterialVO.getDefaultTableName(), + MaterialVO.CODE, MaterialVO.PK_MATERIAL, bvo.getCmaterialoid())); // 物料ID - 必填 + + detail.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), + MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, bvo.getCunitid())); // 计量单位 - 必填 + + detail.put("productNum", null); // 制令号 + + // 库位 - 必填 + detail.put("storageId", transferCodeByPk(RackVO.getDefaultTableName(), + RackVO.CODE, RackVO.PK_RACK, bvo.getClocationid())); // 库位 - 必填 + + detail.put("batchNum", bvo.getVbatchcode()); // 物料批号 - 必填 + detail.put("scaleFactor", transferSpecialField(bvo.getVchangerate())); // 换算系数 - 必填 + + // 数量信息 - 必填 + detail.put("issuedQty", bvo.getNshouldassistnum()); // 应发数量 - 必填 + detail.put("mIssuedQty", bvo.getNshouldnum()); // 主应发数量 - 必填 + detail.put("actQry", bvo.getNassistnum()); // 实发数量 - 必填 + detail.put("mActQry", bvo.getNnum()); // 主实发数量 - 必填 + detail.put("assistActQry", bvo.getNassistnum()); // 辅助实发数量 - 必填 + + // 客户和供应商信息 + detail.put("customId", transferCodeByPk(CustomerVO.getDefaultTableName(), + CustomerVO.CODE, CustomerVO.PK_CUSTOMER, bvo.getCasscustid())); // 客户ID + + detail.put("supplierId", transferCodeByPk(SupplierVO.getDefaultTableName(), + SupplierVO.CODE, SupplierVO.PK_SUPPLIER, bvo.getCvendorid())); // 供应商ID + + detail.put("manufactureDate", bvo.getDproducedate()); // 生产日期 + detail.put("color", null); // 颜色 + detail.put("properties", null); + detail.put("remark", bvo.getVnotebody()); // 备注 - 行备注(vnotebody) details.add(detail); } } - info.put("details", details); - - // 将info对象添加到请求数据中 - requestData.put("info", info); - + requestData.put("operation_type", "I"); + requestData.put("info", dataObj); + dataObj.put("details", details); return requestData; } - /** - * 安全获取字符串值,防止空指针异常 - */ - private String getStringValue(Object value) { - return value == null ? "" : value.toString(); - } - - /** - * 处理金思维系统响应 - */ - private void processResponse(String vbillcode, String response) { - if (StringUtils.isEmpty(response)) { - obmlog.error("AfterSigningSynchronizeRule-响应为空,单据号: " + vbillcode); - return; - } - - try { - JSONObject respObj = JSONObject.parseObject(response); - JSONObject result = respObj.getJSONObject("result"); - if (result != null) { - boolean success = result.getBooleanValue("success"); - String message = result.getString("message"); - String errorMessage = result.getString("errorMessage"); - String orderNo = result.getString("orderNo"); - - if (success) { - obmlog.info("AfterSigningSynchronizeRule-同步成功,单据号: " + vbillcode + ", 返回单号: " + orderNo + ", 消息: " + message); - } else { - obmlog.error("AfterSigningSynchronizeRule-同步失败,单据号: " + vbillcode + ", 错误: " + errorMessage); - throw new BusinessException("同步到金思维系统失败: " + errorMessage); - } - } - } catch (Exception e) { - obmlog.error("AfterSigningSynchronizeRule-处理响应异常: " + e.getMessage(), e); - } - } - - private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { if (nc.vo.cmp.util.StringUtils.isEmpty(pk)) { return null; @@ -214,4 +206,28 @@ public class AfterSigningSynchronizeRuleMES implements IRule { } return o.toString(); } + + private String transferSpecialField(String field) { + if (field == null || field.trim().isEmpty()) { + return null; + } + String[] split = field.split("/"); + if (split.length == 2) { + String numStr = split[0].trim(); + String denStr = split[1].trim(); + + if (denStr.equals("0")) { + return "0.00"; // 分母不能为零 + } + + try { + BigDecimal numerator = new BigDecimal(numStr); + BigDecimal denominator = new BigDecimal(denStr); + return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString(); + } catch (NumberFormatException e) { + return field; // 非法数字,返回原字段 + } + } + return field; + } } diff --git a/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleRZ.java b/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleRZ.java index 52aad8a..60937a5 100644 --- a/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleRZ.java +++ b/ic/src/private/nc/bs/ic/m4c/sign/rule/AfterSigningSynchronizeRuleRZ.java @@ -50,6 +50,7 @@ public class AfterSigningSynchronizeRuleRZ implements IRule { } pushToRZMOM(newSaleOutVOS.toArray(new SaleOutVO[0])); }catch (Exception e){ + log.error("同步销售出库到锐制系统失败: " + e.getMessage(), e); ExceptionUtils.wrappException(e); } } diff --git a/ic/src/private/nc/bs/ic/m4c/sign/rule/SalesDeliveryOrderRuleMES.java b/ic/src/private/nc/bs/ic/m4c/sign/rule/SalesDeliveryOrderRuleMES.java new file mode 100644 index 0000000..eef5f1c --- /dev/null +++ b/ic/src/private/nc/bs/ic/m4c/sign/rule/SalesDeliveryOrderRuleMES.java @@ -0,0 +1,260 @@ +package nc.bs.ic.m4c.sign.rule; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.vo.bd.currtype.CurrtypeVO; +import nc.vo.bd.cust.CustomerVO; +import nc.vo.bd.material.MaterialVO; +import nc.vo.bd.material.measdoc.MeasdocVO; +import nc.vo.bd.psn.PsndocVO; +import nc.vo.bd.rack.RackVO; +import nc.vo.bd.supplier.SupplierVO; +import nc.vo.ic.m4c.entity.SaleOutBodyVO; +import nc.vo.ic.m4c.entity.SaleOutHeadVO; +import nc.vo.ic.m4c.entity.SaleOutVO; +import nc.vo.org.DeptVO; +import nc.vo.pub.BusinessException; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; +import nc.vo.vorg.DeptVersionVO; +import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; + +import java.math.BigDecimal; +import java.math.RoundingMode; + + +/** + * 销售交货单(BIP无) 推送至MES + */ +public class SalesDeliveryOrderRuleMES implements IRule { + private static final BaseDAO dao = new BaseDAO(); + // MES系统API接口地址 + private static final String MES_API_URL = "/GTHINKING/AjaxService/N_MISPRO/SalesDeliveryOrder.ashx/SaveData"; + // 删除销售交货单接口地址 + private static final String MES_DELETE_API_URL = "/GTHINKING/AjaxService/N_XSSJJSA/102397002.ashx/SOTH_DELETE"; + private static final Log obmlog = Log.getInstance("OALOG"); + + @Override + public void process(SaleOutVO[] saleOutVOS) { + try { + if (saleOutVOS == null || saleOutVOS.length == 0) { + return; + } + + // 初始化HTTP请求工具类 + IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class); + + // 处理每个销售交货单 + for (SaleOutVO saleOutVO : saleOutVOS) { + SaleOutHeadVO hvo = (SaleOutHeadVO) saleOutVO.getParentVO(); + SaleOutBodyVO[] bvos = (SaleOutBodyVO[]) saleOutVO.getChildrenVO(); + + // 构建要发送的数据 + JSONObject syncData = buildSyncData(hvo, bvos); + if (syncData != null) { + // 每次新增销售交货单之前 先删除 然后再新增 + String orderNo = hvo.getVbillcode(); + boolean flag = deleteSalesDeliveryOrder(orderNo); + if (flag) { + // 发送数据到MES系统 + obmlog.debug("SalesDeliveryOrderRuleMES-准备发送销售交货单数据: " + hvo.getVbillcode()); + httpPostOtherSys.sendToExternalSystem(MES_API_URL, syncData); + } + } + } + } catch (Exception e) { + obmlog.error("SalesDeliveryOrderRuleMES-处理异常:" + e.getMessage(), e); + ExceptionUtils.wrappException(e); + } + } + + /** + * 构建符合MES系统接口规范的请求数据 + */ + private JSONObject buildSyncData(SaleOutHeadVO hvo, SaleOutBodyVO[] bvos) throws BusinessException { + obmlog.debug("SalesDeliveryOrderRuleMES-开始处理销售交货单: " + hvo.getVbillcode()); + + // 检查组织是否符合条件 + if (!hvo.getPk_org().equals("0001A110000000000677")) { + obmlog.debug("SalesDeliveryOrderRuleMES-跳过处理销售交货单,因为此单据组织非电缆: " + hvo.getVbillcode()); + return null; + } + + JSONObject requestData = new JSONObject(); + JSONObject info = new JSONObject(); + // 主表数据 - 所有字段处理 + // 必填字段 + info.put("orderNo", hvo.getVbillcode()); // 必填:交货单号 + info.put("orderDate", hvo.getDbilldate() == null ? null : hvo.getDbilldate().toString().substring(0, 10)); + info.put("deliveryDate", hvo.getDbilldate() == null ? null : hvo.getDbilldate().toString().substring(0, 10)); + // 客户ID - 订单客户(ccustomerid) + info.put("customId", transferCodeByPk(CustomerVO.getDefaultTableName(), + CustomerVO.CODE, CustomerVO.PK_CUSTOMER, hvo.getCcustomerid())); // 必填:客户编码 + // 开票单位编码 + info.put("invoicingUnit", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, hvo.getCcustomervid())); + // 销售部门编码 + info.put("departmentId", transferCodeByPk(DeptVersionVO.getDefaultTableName(), + DeptVersionVO.CODE, DeptVersionVO.PK_VID, hvo.getCdptvid())); // 必填:销售部门编码 + // 销售员 + info.put("seller", transferCodeByPk(PsndocVO.getDefaultTableName(), + PsndocVO.NAME, PsndocVO.PK_PSNDOC, hvo.getCbizid())); + info.put("invoicingBasis", "S"); // 必填:开票依据 + info.put("settlementType", "S"); // 必填:结算方式 + // 仓库编码 + info.put("warehouseId", transferCodeByPk(RackVO.getDefaultTableName(), + RackVO.CODE, RackVO.PK_RACK, hvo.getCwarehouseid())); // 必填:仓库编码 + info.put("type", "XSJH"); // 必填:事务类型,销售交货 + // 必填:生成方式 + info.put("genType", "S"); + // 必填:是否退货 + info.put("returned", "N"); + // 非必填字段 + info.put("transportMode", null); // 运输方式 + info.put("deliveryAddress", null); // 收货地点 + info.put("contacts", null); // 联系人 + info.put("contactNum", null); // 联系电话 + info.put("originalNo", null); // 原交货单号 + info.put("remark", hvo.getVnote()); // 备注 + info.put("creatorNo", null); // 维护人工号 + info.put("creator", null); // 维护人 + info.put("creatTime", null); // 维护时间 + + // 构建明细数组 + JSONArray details = new JSONArray(); + if (bvos != null) { + for (SaleOutBodyVO bvo : bvos) { + JSONObject detail = new JSONObject(); + // 表头字段需要表体字段 + // 必填:汇率 + info.put("exchangeRate", bvo.getNchangestdrate()); + // 必填:货币编码 + info.put("currency", transferCodeByPk(CurrtypeVO.getDefaultTableName(), + CurrtypeVO.CODE, CurrtypeVO.PK_CURRTYPE, bvo.getCorigcurrencyid())); + // 必填字段 + detail.put("orderNo", hvo.getVbillcode()); // 必填:交货单号 + detail.put("orderSn", bvo.getCrowno()); // 必填:交货单序号 + // 生成方式为按订单时必填 + detail.put("soOrderNo", bvo.getVsourcebillcode()); // 销售订单号 + detail.put("soSequenceNum", bvo.getVsourcerowno()); // 销售订单序号 + // 物料编码 + detail.put("materialId", transferCodeByPk(MaterialVO.getDefaultTableName(), + MaterialVO.CODE, MaterialVO.PK_MATERIAL, bvo.getCmaterialoid())); // 必填:物料编码 + // 计量单位 + detail.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), + MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, bvo.getCunitid())); // 必填:计量单位 + detail.put("scaleFactor", transferSpecialField(bvo.getVchangerate())); // 必填:换算系数 + detail.put("taxRate", bvo.getNtaxrate()); // 必填:税率 + detail.put("recQty", bvo.getNshouldassistnum()); // 必填:应收数量 + detail.put("mainRecQty", bvo.getNnum()); // 必填:主应收数量 + + // 非必填字段 + detail.put("batchNum", null); // 物料批号 + detail.put("productNum", null); // 制令号 + detail.put("assitRecQty", null); // 辅应收数量 + detail.put("priceIncludeTax", null); // 原币含税价格 + detail.put("amountIncludeTax", null); // 原币含税金额 + detail.put("taxAmount", null); // 税额 + detail.put("remark", null); // 备注 + details.add(detail); + } + } + info.put("Details", details); + // 将info对象添加到请求数据中 + requestData.put("Data", info); + return requestData; + } + + /** + * 根据主键获取对应的编码 + */ + private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { + if (pk == null || pk.trim().isEmpty()) { + return null; + } + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select " + selectField); + sqlBuilder.append(" from " + tableName); + sqlBuilder.append(" where "); + sqlBuilder.append(pkField, pk); + Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); + if (o == null) { + throw new BusinessException("未查询到编码信息,sql【" + sqlBuilder + "】"); + } + return o.toString(); + } + + /** + * 删除第三方系统中的销售交货单 + * + * @param orderNo 要删除的销售交货单号 + * @return 删除操作是否成功 + * @throws BusinessException 业务异常 + */ + public boolean deleteSalesDeliveryOrder(String orderNo) throws BusinessException { + try { + if (orderNo == null || orderNo.trim().isEmpty()) { + throw new BusinessException("销售交货单号不能为空"); + } + + obmlog.debug("SalesDeliveryOrderRuleMES-准备删除第三方系统销售交货单: " + orderNo); + + // 构建请求数据 + JSONObject requestData = new JSONObject(); + JSONObject dataObj = new JSONObject(); + dataObj.put("orderNo", orderNo); + requestData.put("Data", dataObj); + + // 初始化HTTP请求工具类 + IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class); + + // 发送删除请求 + String response = httpPostOtherSys.callMes(MES_DELETE_API_URL, requestData); + obmlog.debug("SalesDeliveryOrderRuleMES-删除请求返回结果: " + response); + + // 解析返回结果 + JSONObject jsonResponse = JSONObject.parseObject(response); + boolean isSuccess = jsonResponse.getBooleanValue("Success"); + String errorMessage = jsonResponse.getString("ErrorMessage"); + + if (!isSuccess) { + obmlog.error("SalesDeliveryOrderRuleMES-删除销售交货单失败: " + orderNo + ", 错误信息: " + errorMessage); + throw new BusinessException("删除销售交货单失败: " + (errorMessage != null ? errorMessage : "未知错误")); + } + + obmlog.debug("SalesDeliveryOrderRuleMES-成功删除销售交货单: " + orderNo); + return true; + } catch (Exception e) { + obmlog.error("SalesDeliveryOrderRuleMES-删除销售交货单异常:" + e.getMessage(), e); + throw new BusinessException("删除销售交货单时发生异常: " + e.getMessage(), e); + } + } + + private String transferSpecialField(String field) { + if (field == null || field.trim().isEmpty()) { + return null; + } + String[] split = field.split("/"); + if (split.length == 2) { + String numStr = split[0].trim(); + String denStr = split[1].trim(); + + if (denStr.equals("0")) { + return "0.00"; // 分母不能为零 + } + + try { + BigDecimal numerator = new BigDecimal(numStr); + BigDecimal denominator = new BigDecimal(denStr); + return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString(); + } catch (NumberFormatException e) { + return field; // 非法数字,返回原字段 + } + } + return field; + } +} diff --git a/ic/src/private/nc/bs/ic/m4r/approve/rule/AfterApprovingSynchronizeRuleMES.java b/ic/src/private/nc/bs/ic/m4r/approve/rule/AfterApprovingSynchronizeRuleMES.java index e420d26..8f40382 100644 --- a/ic/src/private/nc/bs/ic/m4r/approve/rule/AfterApprovingSynchronizeRuleMES.java +++ b/ic/src/private/nc/bs/ic/m4r/approve/rule/AfterApprovingSynchronizeRuleMES.java @@ -3,7 +3,6 @@ package nc.bs.ic.m4r.approve.rule; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.yonyou.cloud.utils.StringUtils; import nc.bs.dao.BaseDAO; import nc.bs.framework.common.NCLocator; import nc.bs.logging.Log; @@ -21,17 +20,17 @@ import nc.vo.org.DeptVO; import nc.vo.pub.BusinessException; import nc.vo.pub.lang.UFDate; import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; import nc.vo.pubapp.pattern.pub.SqlBuilder; +import nc.vo.vorg.DeptVersionVO; import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; -import java.text.SimpleDateFormat; - /** * 盘点(审批后传MES) */ public class AfterApprovingSynchronizeRuleMES implements IRule { - private static final String INV_COUNT_URL = "/GTHINKING/AjaxService/U20231172_N_XSSJJSA/102397009.ashx/KCPD_INSERT"; // 盘点单同步接口 + private static final String INV_COUNT_URL = "/GTHINKING/AjaxService/N_KCSJJS/101527005.ashx/KCPD_INSERT"; // 盘点单同步接口 private static final String logginfo = "OALOG"; private static final Log obmlog = Log.getInstance(logginfo); private static final BaseDAO dao = new BaseDAO(); @@ -58,15 +57,13 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { if (syncData != null) { // 发送数据到金思维系统(使用HttpPostOtherSysImpl处理网络请求) - String mesResponse = httpPostOtherSys.callMes(INV_COUNT_URL, syncData); - obmlog.debug("AfterApprovingSynchronizeRule-金思维系统响应: " + mesResponse); + httpPostOtherSys.sendToExternalSystem(INV_COUNT_URL, syncData); - // 解析响应,处理结果 - processResponse(hvo.getVbillcode(), mesResponse); } } } catch (Exception e) { obmlog.error("AfterApprovingSynchronizeRule-处理异常:" + e.getMessage(), e); + ExceptionUtils.wrappException(e); } } @@ -82,6 +79,7 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { } // 按照新规范构建请求数据 + JSONObject requestBody = new JSONObject(); JSONObject requestData = new JSONObject(); // 盘点主信息 盘点单号 为空时自动生成 @@ -92,7 +90,7 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { requestData.put("CKID", warehouseCode); // 盘点部门编码 - String deptCode = transferCodeByPk(DeptVO.getDefaultTableName(), DeptVO.CODE, DeptVO.PK_DEPT, hvo.getCdptvid()); + String deptCode = transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE, DeptVersionVO.PK_VID, hvo.getCdptvid()); requestData.put("BMID", deptCode); // 盘点人 requestData.put("PDR", getStringValue(hvo.getCountoperator())); @@ -115,11 +113,12 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { // 获取序号并转换为浮点数 String crownStr = bvo.getCrowno(); try { - detail.put("XH", Double.parseDouble(crownStr)); // 序号 - 必填 + // 序号 + detail.put("XH", Double.parseDouble(crownStr)); } catch (NumberFormatException e) { - detail.put("XH", null); // 默认序号 + detail.put("XH", null); } - // 物料编码 - 必填 + // 物料编码 detail.put("WLID", transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, bvo.getCmaterialvid())); // 货位 detail.put("KW", transferCodeByPk(RackVO.getDefaultTableName(), RackVO.CODE, RackVO.PK_RACK, bvo.getClocationid())); @@ -160,8 +159,9 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { } } requestData.put("DETAILS", details); + requestBody.put("KCPD", requestData); - return requestData; + return requestBody; } /** @@ -171,35 +171,6 @@ public class AfterApprovingSynchronizeRuleMES implements IRule { return value == null ? "" : value.toString(); } - /** - * 处理金思维系统响应 - */ - private void processResponse(String vbillcode, String response) { - if (StringUtils.isEmpty(response)) { - obmlog.error("AfterApprovingSynchronizeRule-响应为空,单据号: " + vbillcode); - return; - } - - try { - JSONObject respObj = JSONObject.parseObject(response); - JSONObject result = respObj.getJSONObject("result"); - if (result != null) { - boolean success = result.getBooleanValue("success"); - String message = result.getString("message"); - String errorMessage = result.getString("errorMessage"); - String orderNo = result.getString("orderNo"); - - if (success) { - obmlog.info("AfterApprovingSynchronizeRule-同步成功,单据号: " + vbillcode + ", 返回单号: " + orderNo + ", 消息: " + message); - } else { - obmlog.error("AfterApprovingSynchronizeRule-同步失败,单据号: " + vbillcode + ", 错误: " + errorMessage); - throw new BusinessException("同步到金思维系统失败: " + errorMessage); - } - } - } catch (Exception e) { - obmlog.error("AfterApprovingSynchronizeRule-处理响应异常: " + e.getMessage(), e); - } - } private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { if (nc.vo.cmp.util.StringUtils.isEmpty(pk)) { diff --git a/ic/src/private/nccloud/pubift/commen/impl/utils/HttpPostOtherSysImpl.java b/ic/src/private/nccloud/pubift/commen/impl/utils/HttpPostOtherSysImpl.java index bfdc252..23d59d0 100644 --- a/ic/src/private/nccloud/pubift/commen/impl/utils/HttpPostOtherSysImpl.java +++ b/ic/src/private/nccloud/pubift/commen/impl/utils/HttpPostOtherSysImpl.java @@ -26,12 +26,12 @@ public class HttpPostOtherSysImpl implements IHttpPostOtherSys { private static final String CLIENT_TYPE = "S"; private static final String EP_ID = ""; private static final String LOGIN_URL = "/GTHINKING/AjaxService/N_MISPRO/100208057.ashx/Login"; - private static final String LOG_INFO_NAME = "OALOG"; private static final Log obmlog = Log.getInstance(LOG_INFO_NAME); @Override public String callMes(String url, JSONObject json) { + // String leip = SysParaInitQuery.getParaString(PubEnv.getPk_group(), "LEIP"); String mesip = "http://192.168.29.32"; String baseurl = mesip + url; String tokenValue = this.getMESToken(mesip); diff --git a/ic/src/public/nccloud/pubift/commen/itf/utils/IHttpPostOtherSys.java b/ic/src/public/nccloud/pubift/commen/itf/utils/IHttpPostOtherSys.java index 0dfa373..148ed08 100644 --- a/ic/src/public/nccloud/pubift/commen/itf/utils/IHttpPostOtherSys.java +++ b/ic/src/public/nccloud/pubift/commen/itf/utils/IHttpPostOtherSys.java @@ -24,5 +24,4 @@ public interface IHttpPostOtherSys { * 发送数据到外部系统 */ public void sendToExternalSystem(String apiPaht, Map requestData) throws BusinessException; - } diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/PMOApproveBP.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/PMOApproveBP.java index 943304d..108cdeb 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/PMOApproveBP.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/PMOApproveBP.java @@ -49,7 +49,7 @@ public class PMOApproveBP { processer.addAfterRule(new PMOCreatePSCPlanRule()); ICompareRule auditSupplyRule = new PMOApproveAuditSupplyRule(); processer.addAfterRule(auditSupplyRule); - // 审批后推送到RZ系统 + // 审批后推送到RZ系统 processer.addAfterRule(new AfterApprovingSynchronizeRuleRZ()); } diff --git a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApprovingSynchronizeRuleRZ.java b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApprovingSynchronizeRuleRZ.java index 90ae7a7..6befb6f 100644 --- a/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApprovingSynchronizeRuleRZ.java +++ b/mmpac/src/private/nc/bs/mmpac/pmo/pac0002/bp/rule/AfterApprovingSynchronizeRuleRZ.java @@ -47,7 +47,7 @@ public class AfterApprovingSynchronizeRuleRZ implements IRule { // 推送到RZ系统 pushToRZMOM(filteredOrders.toArray(new PMOAggVO[0])); } catch (Exception e) { - log.error("同步生产订单到RZ系统失败: " + e.getMessage(), e); + log.error("同步生产订单到RZ系统失败: " + e.getMessage()); ExceptionUtils.wrappException(e); } } @@ -59,8 +59,9 @@ public class AfterApprovingSynchronizeRuleRZ implements IRule { List aggvoList = new ArrayList<>(); for (PMOAggVO aggvo : pmoAggVOS) { String pkOrg = aggvo.getParentVO().getPk_org(); + Integer fbillstatus = aggvo.getParentVO().getFbillstatus(); String orgCode = transferCodeByPk(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg); - if ("30401".equals(orgCode)) { + if ("30401".equals(orgCode)&&1==fbillstatus) { aggvoList.add(aggvo); } } @@ -110,17 +111,22 @@ public class AfterApprovingSynchronizeRuleRZ implements IRule { for (PMOItemVO body : bodys) { JSONObject detailItem = new JSONObject(); +// jhmx_wbid varchar(100) 第三方系统主键id 必填 上位系统后台唯一ID + detailItem.put("jhmx_wbid", head.getCpmohid()); // 第三方系统计划类别id detailItem.put("jhlb_wbid", head.getVtrantypecode()); // 第三方系统产品ID 物料ID detailItem.put("wlbm_wbid", transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, body.getCmaterialvid())); // 预计开工日期 - detailItem.put("sxrq", body.getTplanstarttime().toString()); + if(body.getTplanstarttime()!=null){ + detailItem.put("sxrq", body.getTplanstarttime().toString()); + } // 预计完工日期 - detailItem.put("wcrq", body.getTplanendtime().toString()); - detailItem.put("gdbj", body.getFitemstatus()); + if(body.getTplanendtime()!=null){ + detailItem.put("wcrq", body.getTplanendtime().toString()); + } // 计划产出数量 - detailItem.put("jhsl", body.getNmmastnum().doubleValue()); + detailItem.put("jhsl", body.getNmmastnum().getDouble()); // 入库仓库 detailItem.put("sdck", transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.CODE, StordocVO.PK_STORDOC, body.getCinwarehouseid())); detailItem.put("wlzdycs01", transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.CODE, StordocVO.PK_STORDOC, body.getCinwarehouseid())); @@ -130,11 +136,11 @@ public class AfterApprovingSynchronizeRuleRZ implements IRule { detailItem.put("ddbh", body.getVsalebillcode()); // 订单序号 detailItem.put("khddh", null); - detailItem.put("ddxh", null); + detailItem.put("ddxh", 1); // 备注说明 detailItem.put("bzsm", body.getVnote()); // 项目编号 - detailItem.put("htbz,wlzdycs06", body.getVdef1()); + detailItem.put("wlzdycs06", body.getVdef1()); details.add(detailItem); } } diff --git a/mmpac/src/public/nccloud/openapi/mmpac/wr/WrResource.java b/mmpac/src/public/nccloud/openapi/mmpac/wr/WrResource.java new file mode 100644 index 0000000..e05334f --- /dev/null +++ b/mmpac/src/public/nccloud/openapi/mmpac/wr/WrResource.java @@ -0,0 +1,574 @@ +package nccloud.openapi.mmpac.wr; + +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.bs.uif2.validation.ValidationFailure; +import nc.util.mmf.framework.base.MMArrayUtil; +import nc.util.mmf.framework.base.MMCollectionUtil; +import nc.util.mmf.framework.base.MMNumberUtil; +import nc.util.mmf.framework.base.MMValueCheck; +import nc.vo.mmpac.wr.entity.AggWrVO; +import nc.vo.mmpac.wr.entity.WrItemVO; +import nc.vo.mmpac.wr.entity.WrQualityVO; +import nc.vo.mmpac.wr.entity.WrSerialNoVO; +import nc.vo.mmpac.wr.entity.WrVO; +import nc.vo.mmpac.wr.enumeration.WrBillStatusEnum; +import nc.vo.pub.BusinessException; +import nc.vo.pub.VOStatus; +import nc.vo.pub.billtype.BilltypeVO; +import nc.vo.pub.lang.UFDate; +import nc.vo.pubapp.AppContext; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nccloud.api.mmpac.wr.IAPIWrMaintain; +import nccloud.api.rest.utils.NCCRestUtils; +import nccloud.api.rest.utils.ResultMessageUtil; +import nccloud.openapi.scmpub.pub.TransferCodeToPKTool; +import nccloud.ws.rest.resource.AbstractNCCRestResource; +import org.json.JSONString; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Path("mmpac/wr") +public class WrResource extends AbstractNCCRestResource { + + private static String HEADTABLE = "mm_wr"; + + private static String BODYTABLE = "mm_wr_product"; + + private static String QUALITYTABLE = "mm_wr_quality"; + + private static String SERIALNOTABLE = "mm_wr_serialno"; + + private static String PICKNOTABLE = "mm_wr_pick"; + + private static String GNUM_QUALITY = "ngqualitynum"; + private static String GNUM_REWORK = "ngreworknum"; + private static String GNUM_REJECT = "ngrejectnum"; + private static String GASTNUM_QUALITY = "ngqualityastnum"; + private static String GASTNUM_REWORK = "ngreworkastnum"; + private static String GASTNUM_REJECT = "ngrejectastnum"; + private static List HeadUnUpdateFiled = Arrays.asList(WrVO.PK_WR, WrVO.PK_GROUP, WrVO.CWKID, + WrVO.FBILLSTATUS, WrVO.VBILLCODE, WrVO.PK_ORG, WrVO.PK_ORG_V); + private static List BodyUnUpdateFiled = Arrays.asList(WrItemVO.PK_WR, "cbunitid", "pk_group", "pk_org", + "pk_org_v", "pk_wr_product", "bbhasfbill", "bbhaspicked", "bbinstock", "bbisempass", "cbempass_bid", + "cbempass_brow", "cbempasscode", "cbempassid", "cbfirstmobid", "cbfirstmoid", "cbsrctranstype", "cbsrcmoid", + "cbsrcmobid", "cbfirstranstype", "cbmaterialid", "cbmainmaterialid", "fbsourcetype", "nbaldempinastnum", + "nbaldempinnum", "nbcheckastnum", "nbchecknum", "nbempassastnum", "nbempassnum", "nbsldcheckastnum", + "nbsldchecknum", "nbsldinastnum", "nbsldinnum", "vbbatchid", "vbfirstcode", "vbfirstid", "vbfirstmocode", + "vbfirstmorowno", "vbfirstranstype", "vbfirstrowid", "vbfirstrowno", "vbfirsttype", "vbidentify", + "vbinbatchid", "vbmainidentify", "vbmainmorowno", "vbmobillcode", "vbmoparentbillcode", "vbmorowno", + "vbparentmorowno", "vbsalebillcode", "vbsalebillid", "vbsrccode", "vbsrcid", "vbsrcmocode", "vbsrcmorowno", + "vbsrcrowid", "vbsrcrowno", "vbmainbomcode", "vbsrctranstype", "bbhasbckfled", "bbhaspicked", "bbsetmark"); + + @POST + @Path("saveAndApprove") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString saveAndApprove(List> paramList) { + if (MMValueCheck.isEmpty(paramList)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + List voList = new ArrayList(); + try { + for (Map paramMap : paramList) { + if (!paramMap.containsKey(HEADTABLE) || !paramMap.containsKey(BODYTABLE)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + Map headInfo = (Map) paramMap.get(HEADTABLE); + List> itemInfos = new ArrayList>(); + if (paramMap.get(BODYTABLE) instanceof List) { + itemInfos = (List>) paramMap.get(BODYTABLE); + } else { + Map bodyInfo = (Map) paramMap.get(BODYTABLE); + itemInfos.add(bodyInfo); + } + AggWrVO vo = new AggWrVO(); + WrVO head = new WrVO(); + head.setPk_group(AppContext.getInstance().getPkGroup()); + head.setStatus(VOStatus.NEW); + for (String key : headInfo.keySet()) { + head.setAttributeValue(key, headInfo.get(key)); + } + vo.setParentVO(head); + List items = new ArrayList(); + String paramdata = NCCRestUtils.toJSONString(itemInfos).toJSONString(); + Log.getInstance("mm-mes").info("mes到生产报告参数:" + paramdata); + for (Map itemMap : itemInfos) { + WrItemVO item = new WrItemVO(); + item.setStatus(VOStatus.NEW); + boolean hasGNumFlag = false; + for (String key : itemMap.keySet()) { + if (QUALITYTABLE.equals(key)) { + List> qualityInfos = (List>) itemMap + .get(QUALITYTABLE); + List qualitys = this.getWrQualitys(qualityInfos); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } else if (SERIALNOTABLE.equals(key)) { + List> snInfos = (List>) itemMap.get(SERIALNOTABLE); + List snVOs = this.getWrSerialNos(snInfos); + item.setSerialnovos(snVOs.toArray(new WrSerialNoVO[0])); + } else if (PICKNOTABLE.equals(key)) { + continue; + } else if (this.isGNumFilds(key)) { + hasGNumFlag = true; + } else { + item.setAttributeValue(key, itemMap.get(key)); + } + } + if (hasGNumFlag) { + List qualitys = this.getWrQualitysByGnum(itemMap, item); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } + items.add(item); + } + vo.setChildren(WrItemVO.class, items.toArray(new WrItemVO[0])); + voList.add(vo); + IAPIWrMaintain server = NCLocator.getInstance().lookup(IAPIWrMaintain.class); + AggWrVO[] aggvos = server.saveAndApprove(voList.toArray(new AggWrVO[0])); + boolean successFlag = true; + StringBuilder errMsg = new StringBuilder(); + if (MMArrayUtil.isNotEmpty(aggvos)) { + for (AggWrVO aggvo : aggvos) { + List validateList = aggvo.getParentVO().getExcpMsgList(); + if (MMCollectionUtil.isNotEmpty(validateList)) { + successFlag = false; + errMsg.append(aggvo.getParentVO().getVbillcode()); + errMsg.append(":"); + for (ValidationFailure validate : validateList) { + errMsg.append(validate.getMessage()); + errMsg.append(";"); + } + } + } + } + if (successFlag) { + return ResultMessageUtil.toJSON(aggvos, "生产报告保存成功"); + } else { + ExceptionUtils.wrappBusinessException(errMsg.toString()); + } + } + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + return null; + } + + private List getWrQualitysByGnum(Map itemMap, WrItemVO item) { + List qualityVOs = new ArrayList(); + // 合格数量1 + if (itemMap.containsKey(WrResource.GNUM_QUALITY) || itemMap.containsKey(WrResource.GASTNUM_QUALITY)) { + WrQualityVO qVO = new WrQualityVO(); + qVO.setFgprocessmethod(1); + if (itemMap.containsKey(WrResource.GNUM_QUALITY)) { + qVO.setAttributeValue(WrQualityVO.NGNUM, itemMap.get(WrResource.GNUM_QUALITY)); + } + if (itemMap.containsKey(WrResource.GASTNUM_QUALITY)) { + qVO.setAttributeValue(WrQualityVO.NGASTNUM, itemMap.get(WrResource.GASTNUM_QUALITY)); + } + if (MMNumberUtil.isGtZero(qVO.getNgnum()) || MMNumberUtil.isGtZero(qVO.getNgastnum())) { + qualityVOs.add(qVO); + } + } + // 报废数量2 + if (itemMap.containsKey(WrResource.GNUM_REJECT) || itemMap.containsKey(WrResource.GASTNUM_REJECT)) { + WrQualityVO qVO = new WrQualityVO(); + qVO.setFgprocessmethod(2); + if (itemMap.containsKey(WrResource.GNUM_REJECT)) { + qVO.setAttributeValue(WrQualityVO.NGNUM, itemMap.get(WrResource.GNUM_REJECT)); + } + if (itemMap.containsKey(WrResource.GASTNUM_REJECT)) { + qVO.setAttributeValue(WrQualityVO.NGASTNUM, itemMap.get(WrResource.GASTNUM_REJECT)); + } + if (MMNumberUtil.isGtZero(qVO.getNgnum()) || MMNumberUtil.isGtZero(qVO.getNgastnum())) { + qualityVOs.add(qVO); + } + } + // 返工数量3 + if (itemMap.containsKey(WrResource.GNUM_REWORK) || itemMap.containsKey(WrResource.GASTNUM_REWORK)) { + WrQualityVO qVO = new WrQualityVO(); + qVO.setFgprocessmethod(3); + if (itemMap.containsKey(WrResource.GNUM_REWORK)) { + qVO.setAttributeValue(WrQualityVO.NGNUM, itemMap.get(WrResource.GNUM_REWORK)); + } + if (itemMap.containsKey(WrResource.GASTNUM_REWORK)) { + qVO.setAttributeValue(WrQualityVO.NGASTNUM, itemMap.get(WrResource.GASTNUM_REWORK)); + } + if (MMNumberUtil.isGtZero(qVO.getNgnum()) || MMNumberUtil.isGtZero(qVO.getNgastnum())) { + qualityVOs.add(qVO); + } + } + return qualityVOs; + } + + private boolean isGNumFilds(String key) { + if (WrResource.GNUM_QUALITY.equals(key)) { + return true; + } else if (WrResource.GASTNUM_QUALITY.equals(key)) { + return true; + } else if (WrResource.GNUM_REJECT.equals(key)) { + return true; + } else if (WrResource.GASTNUM_REJECT.equals(key)) { + return true; + } else if (WrResource.GNUM_REWORK.equals(key)) { + return true; + } else if (WrResource.GASTNUM_REWORK.equals(key)) { + return true; + } + return false; + } + + private List getWrSerialNos(List> snInfos) { + List snVOs = new ArrayList(); + for (Map snInfo : snInfos) { + WrSerialNoVO snVO = new WrSerialNoVO(); + for (String key : snInfo.keySet()) { + snVO.setAttributeValue(key, snInfo.get(key)); + } + snVOs.add(snVO); + } + return snVOs; + } + + private List getWrQualitys(List> qualityInfos) { + List qualityVOs = new ArrayList(); + for (Map qualityInfo : qualityInfos) { + WrQualityVO qualityVO = new WrQualityVO(); + for (String key : qualityInfo.keySet()) { + qualityVO.setAttributeValue(key, qualityInfo.get(key)); + } + qualityVOs.add(qualityVO); + } + return qualityVOs; + } + + @Override + public String getModule() { + // TODO Auto-generated method stub + return null; + } + + @POST + @Path("deleteByMesIDs") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString deleteByMesIDs(String[] mesIDs) { + if (MMValueCheck.isEmpty(mesIDs)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常", "1"); + } + try { + IAPIWrMaintain server = NCLocator.getInstance().lookup(IAPIWrMaintain.class); + server.deleteWrByMesID(mesIDs); + return ResultMessageUtil.toJSON(null, "生产报告删除成功"); + + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + } + + @POST + @Path("newsave") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString newsave(Map paramsMap) { + List> paramList = (List>) paramsMap.get("data"); + if (MMValueCheck.isEmpty(paramList)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + List voList = new ArrayList(); + BaseDAO baseDAO = new BaseDAO(); + try { + for (Map paramMap : paramList) { + if (!paramMap.containsKey(HEADTABLE) || !paramMap.containsKey(BODYTABLE)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + Map headInfo = (Map) paramMap.get(HEADTABLE); + List> itemInfos = new ArrayList>(); + if (paramMap.get(BODYTABLE) instanceof List) { + itemInfos = (List>) paramMap.get(BODYTABLE); + } else { + Map bodyInfo = (Map) paramMap.get(BODYTABLE); + itemInfos.add(bodyInfo); + } + AggWrVO vo = new AggWrVO(); + WrVO head = new WrVO(); + head.setPk_group(AppContext.getInstance().getPkGroup()); + for (String key : headInfo.keySet()) { + if (MMValueCheck.isEmpty(headInfo.get(key))) { + continue; + } + head.setAttributeValue(key, headInfo.get(key)); + } + vo.setParentVO(head); + List items = new ArrayList(); + String paramdata = NCCRestUtils.toJSONString(itemInfos).toJSONString(); + Log.getInstance("mm-mes").info("mes到生产报告参数:" + paramdata); + for (Map itemMap : itemInfos) { + WrItemVO item = new WrItemVO(); + boolean hasGNumFlag = false; + for (String key : itemMap.keySet()) { + + if (QUALITYTABLE.equals(key)) { + List> qualityInfos = (List>) itemMap + .get(QUALITYTABLE); + List qualitys = this.getWrQualitys(qualityInfos); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } else if (SERIALNOTABLE.equals(key)) { + List> snInfos = (List>) itemMap.get(SERIALNOTABLE); + List snVOs = this.getWrSerialNos(snInfos); + item.setSerialnovos(snVOs.toArray(new WrSerialNoVO[0])); + } else if (PICKNOTABLE.equals(key)) { + continue; + } else if (this.isGNumFilds(key)) { + hasGNumFlag = true; + } else { + if (MMValueCheck.isEmpty(itemMap.get(key))) { + continue; + } + item.setAttributeValue(key, itemMap.get(key)); + } + } + if (hasGNumFlag) { + List qualitys = this.getWrQualitysByGnum(itemMap, item); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } + items.add(item); + } + vo.setChildren(WrItemVO.class, items.toArray(new WrItemVO[0])); + voList.add(vo); + IAPIWrMaintain server = NCLocator.getInstance().lookup(IAPIWrMaintain.class); + List aggWrVOS = TransferCodeToPKTool.transferAggVO(voList); + //翻译报告类型 + for (AggWrVO aggWrVO : aggWrVOS) { + List collection = (List) baseDAO.retrieveByClause(BilltypeVO.class, " pk_billtypecode='" + aggWrVO.getParentVO().getVtrantypecode() + "'"); + if(collection==null||collection.size()==0){ + throw new BusinessException("翻译报告类型失败,检查报告类型编码【"+aggWrVO.getParentVO().getVtrantypecode()+"】"); + } + aggWrVO.getParentVO().setVtrantypeid(collection.get(0).getPk_billtypeid()); + aggWrVO.getParentVO().setDbilldate(new UFDate()); + } + AggWrVO[] aggvos = server.newsave(voList.toArray(new AggWrVO[0])); + boolean successFlag = true; + StringBuilder errMsg = new StringBuilder(); + if (MMArrayUtil.isNotEmpty(aggvos)) { + for (AggWrVO aggvo : aggvos) { + List validateList = aggvo.getParentVO().getExcpMsgList(); + if (MMCollectionUtil.isNotEmpty(validateList)) { + successFlag = false; + errMsg.append(aggvo.getParentVO().getVbillcode()); + errMsg.append(":"); + for (ValidationFailure validate : validateList) { + errMsg.append(validate.getMessage()); + errMsg.append(";"); + } + } + } + } + if (successFlag) { + return ResultMessageUtil.toJSON(aggvos, "生产报告保存成功"); + } else { + ExceptionUtils.wrappBusinessException(errMsg.toString()); + } + } + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + return null; + } + + @POST + @Path("update") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString update(Map paramsMap) throws BusinessException { + List> paramList = (List>) paramsMap.get("data"); + if (MMValueCheck.isEmpty(paramList)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + List voList = new ArrayList(); + IAPIWrMaintain server = NCLocator.getInstance().lookup(IAPIWrMaintain.class); + + List aggIds = new ArrayList<>(); + for (Map paramMap : paramList) { + if (!paramMap.containsKey(HEADTABLE) || !paramMap.containsKey(BODYTABLE)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含表头信息和表体信息", "1"); + } + Map headInfo = (Map) paramMap.get(HEADTABLE); + if (MMValueCheck.isNotEmpty(headInfo.get("pk_wr"))) { + aggIds.add(headInfo.get("pk_wr").toString()); + } + } + if (MMValueCheck.isEmpty(aggIds)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含生产报告表头主键", "1"); + } + AggWrVO[] aggWrVOSByIds = server.findAggWrVOSByIds(aggIds.toArray(new String[0])); + Map voMap = new HashMap<>(); + for (AggWrVO aggWrVO : aggWrVOSByIds) { + voMap.put(aggWrVO.getParentVO().getPk_wr(), aggWrVO); + } + + try { + // 根据传递阐参数修改生产报告数据 + for (Map paramMap : paramList) { + + Map headInfo = (Map) paramMap.get(HEADTABLE); + List> itemInfos = new ArrayList>(); + if (paramMap.get(BODYTABLE) instanceof List) { + itemInfos = (List>) paramMap.get(BODYTABLE); + } else { + Map bodyInfo = (Map) paramMap.get(BODYTABLE); + itemInfos.add(bodyInfo); + } + AggWrVO vo = voMap.get(headInfo.get("pk_wr").toString()); + if (MMValueCheck.isEmpty(vo)) { + return ResultMessageUtil + .exceptionToJSON("单据号:" + headInfo.get("vbillcode") + "生产报告在数据库中不存在或者已经被删除!", "1"); + } + WrVO head = vo.getParentVO(); + if (!(WrBillStatusEnum.I_FREEDOM.intValue() == head.getFbillstatus())) { + return ResultMessageUtil.exceptionToJSON("非自由态的生产报告不允许修改!", "1"); + } + + // 处理表头数据 + head.setStatus(VOStatus.UPDATED); + for (String key : headInfo.keySet()) { + if (MMValueCheck.isEmpty(headInfo.get(key))) { + continue; + } + if (HeadUnUpdateFiled.contains(key) + && !head.getAttributeValue(key).toString().equals(headInfo.get(key))) { + return ResultMessageUtil.exceptionToJSON("表头属性:" + key + "不允许修改", "1"); + } + head.setAttributeValue(key, headInfo.get(key)); + } + vo.setParentVO(head); + + // 处理表体数据和孙表数据 + Map wrItemVOMap = new HashMap<>(); + if (MMValueCheck.isNotEmpty(vo.getChildrenVO())) { + for (WrItemVO wrItemVO : vo.getChildrenVO()) { + wrItemVOMap.put(wrItemVO.getPk_wr_product(), wrItemVO); + } + } + List items = new ArrayList(); + String paramdata = NCCRestUtils.toJSONString(itemInfos).toJSONString(); + Log.getInstance("mm-mes").info("mes到生产报告参数:" + paramdata); + for (Map itemMap : itemInfos) { + WrItemVO item = wrItemVOMap.get(itemMap.get("pk_wr_product")); + if (MMValueCheck.isEmpty(item)) { + continue; + } + item.setStatus(VOStatus.UPDATED); + boolean hasGNumFlag = false; + for (String key : itemMap.keySet()) { + + if (QUALITYTABLE.equals(key)) { + List> qualityInfos = (List>) itemMap + .get(QUALITYTABLE); + List qualitys = this.getWrQualitys(qualityInfos); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } else if (SERIALNOTABLE.equals(key)) { + List> snInfos = (List>) itemMap.get(SERIALNOTABLE); + List snVOs = this.getWrSerialNos(snInfos); + item.setSerialnovos(snVOs.toArray(new WrSerialNoVO[0])); + } else if (PICKNOTABLE.equals(key)) { + continue; + } else if (this.isGNumFilds(key)) { + hasGNumFlag = true; + } else { + if (MMValueCheck.isEmpty(itemMap.get(key))) { + continue; + } + if (BodyUnUpdateFiled.contains(key) && MMValueCheck.isNotEmpty(item.getAttributeValue(key)) + && !item.getAttributeValue(key).toString().equals(itemMap.get(key).toString())) { + return ResultMessageUtil.exceptionToJSON("表体属性:" + key + "不允许修改", "1"); + } + item.setAttributeValue(key, itemMap.get(key)); + } + } + if (hasGNumFlag) { + List qualitys = this.getWrQualitysByGnum(itemMap, item); + item.setQualityvos(qualitys.toArray(new WrQualityVO[0])); + } + items.add(item); + } + vo.setChildren(WrItemVO.class, items.toArray(new WrItemVO[0])); + voList.add(vo); + } + + AggWrVO[] aggvos = server.update(voList.toArray(new AggWrVO[0])); + boolean successFlag = true; + StringBuilder errMsg = new StringBuilder(); + if (MMArrayUtil.isNotEmpty(aggvos)) { + for (AggWrVO aggvo : aggvos) { + List validateList = aggvo.getParentVO().getExcpMsgList(); + if (MMCollectionUtil.isNotEmpty(validateList)) { + successFlag = false; + errMsg.append(aggvo.getParentVO().getVbillcode()); + errMsg.append(":"); + for (ValidationFailure validate : validateList) { + errMsg.append(validate.getMessage()); + errMsg.append(";"); + } + } + } + } + if (successFlag) { + return ResultMessageUtil.toJSON(aggvos, "生产报告修改成功"); + } else { + ExceptionUtils.wrappBusinessException(errMsg.toString()); + } + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + return null; + } + + @POST + @Path("delete") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString delete(Map paramMap) throws BusinessException { + if (MMValueCheck.isEmpty(paramMap)) { + return ResultMessageUtil.exceptionToJSON("传入数据异常", "1"); + } + Set aggwrIds = new HashSet<>(); + Map idTsMap = new HashMap<>(); + if (!paramMap.containsKey("aggWrPk")) { + return ResultMessageUtil.exceptionToJSON("传入数据异常,参数要包含生产报告主键", "10000"); + } + aggwrIds.addAll((Collection) paramMap.get("aggWrPk")); + + try { + IAPIWrMaintain server = NCLocator.getInstance().lookup(IAPIWrMaintain.class); + AggWrVO[] aggWrVOSByIds = server.findAggWrVOSByIds(aggwrIds.toArray(new String[0])); + + List deleteVos = new ArrayList<>(); + for (AggWrVO aggWrVOSById : aggWrVOSByIds) { + if (!(WrBillStatusEnum.I_FREEDOM.intValue() == aggWrVOSById.getParentVO().getFbillstatus())) { + continue; + } + deleteVos.add(aggWrVOSById); + } + if (MMValueCheck.isEmpty(deleteVos)) { + return ResultMessageUtil.exceptionToJSON("生产报告状态为审批通过,不允许删除!", "1"); + } + server.delete(deleteVos.toArray(new AggWrVO[0])); + return ResultMessageUtil.toJSON(new String[0], "生产报告删除成功"); + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + } + +} diff --git a/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleMES.java b/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleMES.java new file mode 100644 index 0000000..af41f7e --- /dev/null +++ b/so/src/private/nc/bs/so/m30/rule/approve/AfterApprovingSynchronizeRuleMES.java @@ -0,0 +1,271 @@ +package nc.bs.so.m30.rule.approve; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.bs.dao.BaseDAO; +import nc.bs.framework.common.NCLocator; +import nc.bs.logging.Log; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.vo.bd.balatype.BalaTypeVO; +import nc.vo.bd.currtype.CurrtypeVO; +import nc.vo.bd.cust.CustomerVO; +import nc.vo.bd.material.MaterialVO; +import nc.vo.bd.material.measdoc.MeasdocVO; +import nc.vo.bd.psn.PsndocVO; +import nc.vo.cmp.util.StringUtils; +import nc.vo.org.DeptVO; +import nc.vo.pub.BusinessException; +import nc.vo.pub.billtype.BilltypeVO; +import nc.vo.pub.lang.UFDate; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.pub.SqlBuilder; +import nc.vo.so.m30.entity.SaleOrderVO; +import nc.vo.so.m30.entity.SaleOrderHVO; +import nc.vo.so.m30.entity.SaleOrderBVO; +import nc.vo.vorg.DeptVersionVO; +import nccloud.bs.sc.scadjust.beforeedit.rule.head.Psndoc; +import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; + +/** + * 销售订单审批后推送MES金思维系统 + */ +public class AfterApprovingSynchronizeRuleMES implements IRule { + private static final String SALE_ORDER_URL = "/GTHINKING/AjaxService/N_XSSJJSA/102397000.ashx/XSDD_INSERT"; // 销售订单同步接口 + private static final String logginfo = "OALOG"; + private static final Log obmlog = Log.getInstance(logginfo); + private static final BaseDAO dao = new BaseDAO(); + + public AfterApprovingSynchronizeRuleMES() { + } + + @Override + public void process(SaleOrderVO[] saleOrderVOs) { + try { + if (saleOrderVOs == null || saleOrderVOs.length == 0) { + return; + } + // 初始化HTTP请求工具类 + IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class); + // 处理每个销售订单 + for (SaleOrderVO saleOrderVO : saleOrderVOs) { + SaleOrderHVO head = saleOrderVO.getParentVO(); + SaleOrderBVO[] bodys = saleOrderVO.getChildrenVO(); + + // 构建要发送的数据 + JSONObject syncData = buildSyncData(head, bodys); + + if (syncData != null) { + // 发送数据到金思维系统 + httpPostOtherSys.sendToExternalSystem(SALE_ORDER_URL, syncData); + } + } + } catch (Exception e) { + obmlog.error("AfterApprovingSynchronizeRuleMES-处理异常:" + e.getMessage(), e); + ExceptionUtils.wrappException(e); + } + } + + /** + * 构建符合金思维系统接口规范的请求数据 + */ + private JSONObject buildSyncData(SaleOrderHVO head, SaleOrderBVO[] bodys) throws BusinessException { + obmlog.debug("AfterApprovingSynchronizeRuleMES-开始处理销售订单: " + head.getVbillcode()); + // 检查组织、单据类型等限制条件 + if (!checkOrderValidForSync(head)) { + obmlog.debug("AfterApprovingSynchronizeRule-跳过处理销售订单,因为此单据组织非电缆: " + head.getVbillcode()); + return null; + } + + // 创建请求数据 + JSONObject requestData = new JSONObject(); + JSONObject data = new JSONObject(); + // 销售订单号 这里超长了 改为手动输入 + data.put("orderNo", head.getVbillcode()); + // 客户订单号 + data.put("customOrderNo", null); + // 订单日期(必填,格式为YYYY-MM-DD) + UFDate dbilldate = head.getDbilldate(); + data.put("orderDate", dbilldate != null ? dbilldate.toString().substring(0, 10) : null); + // 订单类别(非必填) + data.put("orderType", transferCodeByPk(BilltypeVO.TABLENAME, BilltypeVO.PK_BILLTYPECODE, BilltypeVO.PK_BILLTYPE_ID, head.getCtrantypeid())); + // 生成方式 + data.put("generation", "Z"); + // 客户编码(必填,最大长度8) + String customerCode = transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, + CustomerVO.PK_CUSTOMER, head.getCcustomerid()); + data.put("customId", customerCode); + data.put("seller", transferCodeByPk(PsndocVO.getDefaultTableName(), PsndocVO.NAME, PsndocVO.PK_PSNDOC, head.getCemployeeid())); + // 销售部门编码(必填,最大长度8) + String deptCode = transferCodeByPk(DeptVersionVO.getDefaultTableName(), DeptVersionVO.CODE, + DeptVersionVO.PK_VID, head.getCdeptvid()); + data.put("departmentId", deptCode); + // 联系人(非必填) + data.put("contacts", null); + // 联系电话(非必填) + data.put("contactNum", null); + // "X"或"S" 这里只翻译了code 还需要判断 + data.put("settlementType", transferCodeByPk(BalaTypeVO.getDefaultTableName(), BalaTypeVO.CODE, BalaTypeVO.PK_BALATYPE, head.getCbalancetypeid())); + // 货币(必填,最大长度3) + String currencyCode = transferCodeByPk(CurrtypeVO.getDefaultTableName(), CurrtypeVO.CODE, CurrtypeVO.PK_CURRTYPE, head.getCorigcurrencyid()); + data.put("currency", currencyCode); + // 其他非必填字段一律设为null + data.put("priceListId", null); + data.put("invoicingUnit", transferCodeByPk(CustomerVO.getDefaultTableName(), CustomerVO.CODE, CustomerVO.PK_CUSTOMER, head.getCinvoicecustid())); + data.put("contractNo", null); + data.put("projectNo", null); + data.put("salesAreaId", null); + data.put("deliveryAreaId", null); + data.put("discount", null); + data.put("paymentType", null); + data.put("warranty", null); + data.put("retentionAmount", null); + data.put("prepayment", null); + data.put("payment", null); + data.put("salesChannels", null); + data.put("transportMode", null); + data.put("transportProxy", null); + data.put("packing", null); + data.put("deliveryAddress", null); + data.put("labelDemand", null); + data.put("skillsDemand", null); + data.put("contractType", null); + data.put("deliveryRemarks", null); + data.put("remarks", head.getVnote()); + + // 构建明细数据 - 只填必填字段 + JSONArray details = new JSONArray(); + if (bodys != null) { + for (SaleOrderBVO body : bodys) { + JSONObject detailItem = new JSONObject(); + + // 以下字段需要表体的字段 + // 需求日期 表体dreceivedate + UFDate dreceivedate = body.getDreceivedate(); + data.put("demandDate", dreceivedate != null ? dreceivedate.toString().substring(0, 10) : null); + // 计划发货日期 表体dsenddate + UFDate dsenddate = body.getDsenddate(); + data.put("deliveryDate", dsenddate != null ? dsenddate.toString().substring(0, 10) : null); + // 汇率 表体nexchangerate + data.put("exchangeRate", body.getVchangerate() != null ? transferSpecialField(body.getVchangerate()) : null); + + + // 以下表体所需字段 + // 序号 + detailItem.put("sequenceNum", body.getCrowno()); + // 合同序号 + detailItem.put("contractNum", null); + // 物料编码 + String materialCode = transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, + MaterialVO.PK_MATERIAL, body.getCmaterialvid()); + detailItem.put("materialId", materialCode); + // 计量单位 + detailItem.put("unit", transferCodeByPk(MeasdocVO.getDefaultTableName(), MeasdocVO.CODE, MeasdocVO.PK_MEASDOC, body.getCunitid())); + // 换算系数 + detailItem.put("scaleFactor", body.getVchangerate() != null ? transferSpecialField(body.getVchangerate()) : null); + // 增值税率 + UFDouble taxRate = body.getNtaxrate(); + detailItem.put("vatRate", taxRate != null ? taxRate.toString() : null); + // 需求数量 + UFDouble num = body.getNastnum(); + detailItem.put("quantity", num != null ? num.getDouble() : null); + // 主需求数量 + UFDouble mainNum = body.getNnum(); + detailItem.put("mainQuantity", mainNum != null ? mainNum.getDouble() : null); + // 含税价格 + UFDouble taxPrice = body.getNqtorigtaxprice(); + detailItem.put("price", taxPrice != null ? taxPrice.getDouble() : null); + // 含税金额 + UFDouble taxAmount = body.getNorigtaxmny(); + detailItem.put("amount", taxAmount != null ? taxAmount.getDouble() : null); + // 无税单价 + UFDouble noTaxPrice = body.getNqtorigprice(); + detailItem.put("noTaxPrice", noTaxPrice != null ? noTaxPrice.getDouble() : null); + // 无税金额 + UFDouble noTaxAmount = body.getNorigmny(); + detailItem.put("noTaxAmount", noTaxAmount != null ? noTaxAmount.getDouble() : null); + UFDate dreceivedate1 = body.getDreceivedate(); + detailItem.put("demandDate", dreceivedate1 != null ? dreceivedate1.toString().substring(0, 10) : null); + UFDate dsenddate1 = body.getDsenddate(); + detailItem.put("deliveryDate", dsenddate1 != null ? dsenddate1.toString().substring(0, 10) : null); + // 其他非必填字段设为null + detailItem.put("productNum", null); + detailItem.put("factoryId", null); + detailItem.put("customMtId", null); + detailItem.put("customNo", null); + detailItem.put("customSN", null); + detailItem.put("remarks", null); + + details.add(detailItem); + } + } + + data.put("DETAILS", details); + requestData.put("Data", data); + + return requestData; + } + + /** + * 检查订单是否符合同步条件 + */ + private boolean checkOrderValidForSync(SaleOrderHVO head) { + if (!head.getPk_org().equals("0001A110000000000677")) { + obmlog.debug("AfterApprovingSynchronizeRule-跳过处理销售出库单,因为此单据组织非电缆: " + head.getVbillcode()); + return true; + } + return false; + } + + /** + * 转换特殊字段 如 1/1 转换为小数 1.0 + */ + + private String transferSpecialField(String field) { + if (field == null || field.trim().isEmpty()) { + return null; + } + String[] split = field.split("/"); + if (split.length == 2) { + String numStr = split[0].trim(); + String denStr = split[1].trim(); + + if (denStr.equals("0")) { + return "0.00"; // 分母不能为零 + } + + try { + BigDecimal numerator = new BigDecimal(numStr); + BigDecimal denominator = new BigDecimal(denStr); + return numerator.divide(denominator, 2, RoundingMode.HALF_UP).toString(); + } catch (NumberFormatException e) { + return field; // 非法数字,返回原字段 + } + } + return field; + } + + /** + * 根据主键查询编码 + */ + private String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { + if (pk == null || pk.trim().isEmpty()) { + return null; + } + SqlBuilder sqlBuilder = new SqlBuilder(); + sqlBuilder.append(" select " + selectField); + sqlBuilder.append(" from " + tableName); + sqlBuilder.append(" where "); + sqlBuilder.append(pkField, pk); + Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor()); + if (o == null) { + throw new BusinessException("未查询到编码信息,sql【" + sqlBuilder + "】"); + } + return o.toString(); + } +} diff --git a/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java b/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java new file mode 100644 index 0000000..e99572b --- /dev/null +++ b/so/src/private/nc/impl/so/m30/action/main/ApproveSaleOrderAction.java @@ -0,0 +1,223 @@ +package nc.impl.so.m30.action.main; + +import nc.bs.framework.common.NCLocator; +import nc.bs.pub.action.N_30_APPROVE; +import nc.bs.scmpub.rule.VOSagaFrozenValidateRule; +import nc.bs.so.m30.maintain.rule.delete.RewritePromotePriceDeleteRule; +import nc.bs.so.m30.plugin.Action30PlugInPoint; +import nc.bs.so.m30.rule.approve.*; +import nc.bs.so.m30.rule.atp.SaleOrderVOATPAfterRule; +import nc.bs.so.m30.rule.atp.SaleOrderVOATPBeforeRule; +import nc.bs.so.m30.rule.credit.RenovateARByHidsBeginRule; +import nc.bs.so.m30.rule.credit.RenovateARByHidsEndRule; +import nc.bs.so.m30.rule.m35.ArsubOffsetAfterApproveRule; +import nc.bs.so.m30.rule.me.SaleOrderVOApproveAfterRule; +import nc.impl.pubapp.pattern.data.bill.BillQuery; +import nc.impl.pubapp.pattern.data.vo.VOUpdate; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.itf.scmpub.reference.uap.group.SysInitGroupQuery; +import nc.vo.credit.engrossmaintain.pub.action.M30EngrossAction; +import nc.vo.ml.NCLangRes4VoTransl; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFBoolean; +import nc.vo.pubapp.AppContext; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.log.TimeLog; +import nc.vo.scmpub.msg.rule.UpdateMsgStatusRule; +import nc.vo.scmpub.res.billtype.SOBillType; +import nc.vo.scmpub.util.AppInfoContext; +import nc.vo.so.m30.entity.SaleOrderBVO; +import nc.vo.so.m30.entity.SaleOrderHVO; +import nc.vo.so.m30.entity.SaleOrderVO; +import nc.vo.so.pub.enumeration.BillStatus; +import nc.vo.so.pub.rule.SOPfStatusChgRule; +import nccloud.bs.so.mobile.saleorder.operation.rule.MobAfterApproveMessageRule; +import nccloud.commons.lang.ArrayUtils; +import nccloud.nc.vo.pub.pf.BusFlowInfoVO; +import nccloud.pubitf.riart.businesstype.IPFBusinessTypeService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ApproveSaleOrderAction { + public ApproveSaleOrderAction() { + } + + public Object approve(SaleOrderVO[] bills, N_30_APPROVE script) { + Object ret = null; + + try { + AroundProcesser processer = new AroundProcesser(Action30PlugInPoint.ApproveAction); + TimeLog.logStart(); + this.setAppInfoContext(); + this.addBeforeRule(processer); + processer.before(bills); + TimeLog.info(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0162")); + ret = script.procActionFlow(script.getPfParameterVO()); + SaleOrderVO[] newbills = script.getVos(); + this.updateNewBillStatus(newbills); + TimeLog.logStart(); + Integer newbillstatus = newbills[0].getParentVO().getFstatusflag(); + String ctranstype = newbills[0].getParentVO().getVtrantypecode(); + this.addAfterRule(processer, newbillstatus, ctranstype); + processer.after(newbills); + TimeLog.info(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0163")); + String[] pk_so_sales = new String[0]; + + for (SaleOrderVO svo : newbills) { + pk_so_sales = (String[]) ArrayUtils.add(pk_so_sales, svo.getParentVO().getCsaleorderid()); + } + + newbills = (SaleOrderVO[]) (new BillQuery(SaleOrderVO.class)).query(pk_so_sales); + if (null == ret) { + ret = newbills; + } + } catch (Exception ex) { + ExceptionUtils.wrappException(ex); + } + + return ret; + } + + private void updateNewBillStatus(SaleOrderVO[] newbills) { + new HashMap(); + List pk_org = new ArrayList(); + + for (SaleOrderVO vo : newbills) { + for (SaleOrderBVO bvo : vo.getChildrenVO()) { + String csettleorgid = bvo.getCsettleorgid(); + if (!pk_org.contains(csettleorgid)) { + pk_org.add(csettleorgid); + } + } + } + + Map isEnable = SysInitGroupQuery.isRMEnabled(pk_org); + + for (SaleOrderVO vo : newbills) { + List newbvo = new ArrayList(); + + for (SaleOrderBVO bvo : vo.getChildrenVO()) { + String csettleorgid = bvo.getCsettleorgid(); + if (!isEnable.isEmpty() && !(Boolean) isEnable.get(csettleorgid)) { + bvo.setRmcontractbflag(UFBoolean.TRUE); + } else { + newbvo.add(bvo); + } + } + } + + SOPfStatusChgRule statuschgrule = new SOPfStatusChgRule(); + SaleOrderHVO[] updateheads = new SaleOrderHVO[newbills.length]; + List listbody = new ArrayList(); + int i = 0; + + for (SaleOrderVO ordervo : newbills) { + statuschgrule.changePfToBillStatus(ordervo); + updateheads[i++] = ordervo.getParentVO(); + + for (SaleOrderBVO bvo : ordervo.getChildrenVO()) { + listbody.add(bvo); + } + } + + String[] headupname = new String[]{"fstatusflag"}; + VOUpdate headupsrv = new VOUpdate(); + headupsrv.update(updateheads, headupname); + String[] bodyupname = new String[]{"frowstatus", "rmcontractbflag"}; + VOUpdate bodyupsrv = new VOUpdate(); + SaleOrderBVO[] updatebodys = (SaleOrderBVO[]) listbody.toArray(new SaleOrderBVO[listbody.size()]); + bodyupsrv.update(updatebodys, bodyupname); + } + + private void addAfterRule(AroundProcesser processer, Integer newbillstatus, String ctranstype) { + IRule rule = null; + if (SysInitGroupQuery.isCREDITEnabled()) { + IRule var6 = new RenovateARByHidsEndRule(M30EngrossAction.M30Approve); + processer.addAfterRule(var6); + } + + boolean icEnable = SysInitGroupQuery.isICEnabled(); + if (icEnable) { + IRule var7 = new SaleOrderVOATPAfterRule(); + processer.addAfterRule(var7); + } + + IRule var8 = new ArsubOffsetAfterApproveRule(); + processer.addAfterRule(var8); + if (BillStatus.AUDIT.equalsValue(newbillstatus)) { + IRule var9 = new ApproveStateRule(); + processer.addAfterRule(var9); + if (this.isExistDelivery(ctranstype)) { + processer.addAfterRule(new SendMsgToDeliveryRule()); + } + } + + if (BillStatus.NOPASS.equalsValue(newbillstatus) && SysInitGroupQuery.isPRICEEnabled()) { + IRule var10 = new RewritePromotePriceDeleteRule(); + processer.addAfterRule(var10); + } + + IRule var11 = new SaleOrderVOApproveAfterRule(); + processer.addAfterRule(var11); + processer.addAfterRule(new MobAfterApproveMessageRule()); + processer.addAfterRule(new SaleOrderCreateRmBeforeRule()); + // 在审批后推送到MES系统 + processer.addAfterRule(new AfterApprovingSynchronizeRuleMES()); + } + + private boolean isExistDelivery(String ctranstype) { + IPFBusinessTypeService pfservice = (IPFBusinessTypeService) NCLocator.getInstance().lookup(IPFBusinessTypeService.class); + BusFlowInfoVO[] refbillinfos = null; + String groupId = AppContext.getInstance().getPkGroup(); + String userId = AppContext.getInstance().getPkUser(); + + try { + refbillinfos = pfservice.getDownstreamInfo(SOBillType.Order.getCode(), ctranstype, groupId, userId, true); + String delieverycode = SOBillType.Delivery.getCode(); + + for (BusFlowInfoVO info : refbillinfos) { + if (delieverycode.equals(info.getBilltype())) { + return true; + } + } + + return false; + } catch (BusinessException e) { + ExceptionUtils.wrappException(e); + return false; + } + } + + private void addBeforeRule(AroundProcesser processer) { + IRule rule = new VOSagaFrozenValidateRule(); + processer.addBeforeRule(rule); + IRule var4 = new CheckApprovableRule(); + processer.addBeforeRule(var4); + if (SysInitGroupQuery.isCREDITEnabled()) { + IRule var5 = new RenovateARByHidsBeginRule(M30EngrossAction.M30Approve); + processer.addBeforeRule(var5); + } + + boolean icEnable = SysInitGroupQuery.isICEnabled(); + if (icEnable) { + IRule var6 = new SaleOrderVOATPBeforeRule(); + processer.addBeforeRule(var6); + } + + IRule var7 = new BusiLog(); + processer.addBeforeRule(var7); + processer.addBeforeRule(new UpdateMsgStatusRule("csaleorderid")); + } + + private void setAppInfoContext() { + String buttonCode = AppInfoContext.getBtnCode(); + if ("".equals(buttonCode) || null == buttonCode) { + AppInfoContext.setBtnCode("appoveCenter"); + } + + } +} diff --git a/uapbd/doc/閿愬埗鍩虹鏁版嵁瑙嗗浘.md b/uapbd/doc/閿愬埗鍩虹鏁版嵁瑙嗗浘.md new file mode 100644 index 0000000..91c97f0 --- /dev/null +++ b/uapbd/doc/閿愬埗鍩虹鏁版嵁瑙嗗浘.md @@ -0,0 +1,155 @@ +## 物料编码 +~~~sql +CREATE OR REPLACE FORCE EDITIONABLE VIEW "TKNCC"."V_UAPBD_QUERYSYNC_MATERIAL" ("PK_MATERIAL", "CODE", "NAME", "MATERIALSPEC", "PK_MEASDOC", "CHKFREEFLAG", "ENABLESTATE", "PK_STORDOC", "MATERSTATE", "PK_ORG", "ORG_CODE", "TS") AS + SELECT DISTINCT + m.PK_MATERIAL, + m.CODE, + m.NAME, + m.MATERIALSPEC, + m.PK_MEASDOC, + mk.chkfreeflag, + m.ENABLESTATE, + mk.pk_stordoc, + md.materstate, + m.PK_ORG, + oo.code AS org_code, + GREATEST(m.TS, mk.TS, md.TS, oo.TS) AS TS +FROM + bd_material m + LEFT JOIN bd_materialstock mk ON m.PK_MATERIAL = mk.pk_material + LEFT JOIN bd_materialprod md ON m.PK_MATERIAL = md.pk_material + LEFT JOIN org_orgs oo ON m.pk_org = oo.pk_org +WHERE + m.dr = 0; +~~~ + +## 物料分类 +~~~sql +CREATE VIEW V_UAPBD_QUERYSYNC_MATERIALCLASS AS +SELECT + m.code, + m.name, + m.pk_marbasclass , + p.name AS parent_name, + p.code AS parent_code, + oo.CODE AS org_code, + p.pk_marbasclass pk_parent, + GREATEST(p.TS, m.TS) AS TS +FROM + bd_marbasclass m + LEFT JOIN bd_marbasclass p ON m.pk_parent = p.pk_marbasclass + LEFT JOIN ORG_ORGS oo ON m.PK_ORG = oo.PK_ORG +WHERE + m.dr = 0 +~~~ + +## 人员 +~~~sql +CREATE VIEW V_UAPBD_QUERYSYNC_PSNDOC AS +SELECT + p.pk_psndoc, + p.CODE, + p.NAME, + dept.code AS dept_code, + dept.name AS dept_name, + p.ENABLESTATE, + org.code as org_code, + p.TS AS TS +FROM + bd_psndoc p + LEFT JOIN bd_psnjob j ON p.pk_psndoc = j.pk_psndoc + AND j.ismainjob = 'Y' + AND j.dr = 0 + LEFT JOIN org_orgs org ON p.pk_org = org.pk_org + LEFT JOIN org_dept dept ON j.pk_dept = dept.pk_dept +WHERE + p.dr = 0; +~~~ + +## 客户 +~~~sql +CREATE VIEW V_UAPBD_QUERYSYNC_CUSTOMER AS +SELECT + c.pk_customer, + c.name, + c.code, + c.enablestate, + c.shortname, + oo.code AS org_code, + oo.name AS org_name, + og.code AS group_code, + og.name AS group_name, + GREATEST(c.ts, oo.TS, og.TS) AS TS +FROM + bd_customer c + LEFT JOIN org_orgs oo ON c.pk_org = oo.pk_org + LEFT JOIN org_group og ON c.pk_group = og.pk_group +WHERE + c.dr = 0; +~~~ + +## 供应商 +~~~sql +CREATE VIEW V_UAPBD_QUERYSYNC_SUPPLIER AS +SELECT + s.CODE, + s.PK_SUPPLIER, + s.NAME, + s.ENABLESTATE, + s.shortname, + oo.code AS org_code, + oo.name AS org_name, + og.code AS group_code, + og.name AS group_name, + s.ts AS TS +FROM + bd_supplier s + LEFT JOIN org_orgs oo ON s.pk_org = oo.pk_org + LEFT JOIN org_group og ON s.pk_group = og.pk_group +WHERE + s.dr = 0; +~~~ + +## 部门 +~~~sql + CREATE VIEW V_UAPBD_QUERYSYNC_DEPT AS +SELECT + d.CODE, + d.NAME, + d.ENABLESTATE, + + d.PK_DEPT, + oo.code AS org_code, + oo.name AS org_name, + og.code AS group_code, + og.name AS group_name, + d.ts AS TS +FROM + org_dept d + LEFT JOIN org_orgs oo ON d.pk_org = oo.pk_org + LEFT JOIN org_group og ON d.pk_group = og.pk_group +WHERE + d.dr = 0; +~~~ + +## 仓库 +~~~sql + CREATE VIEW V_UAPBD_QUERYSYNC_STORDOC AS +SELECT + sd.CODE, + sd.name, + sd.ENABLESTATE, + sd.PK_STORDOC, + so.code AS org_code, + so.name AS org_name, + og.code AS group_code, + og.name AS group_name, + sd.ts AS TS + +FROM + bd_stordoc sd + LEFT JOIN org_stockorg so ON sd.pk_org = so.pk_stockorg + LEFT JOIN org_group og ON sd.pk_group = og.pk_group +WHERE + sd.dr = 0; +~~~ \ No newline at end of file diff --git a/uapbd/src/public/nc/bs/uapbd/util/ThirdPartyPostRequestUtil.java b/uapbd/src/public/nc/bs/uapbd/util/ThirdPartyPostRequestUtil.java index 0828fe3..8ce69f7 100644 --- a/uapbd/src/public/nc/bs/uapbd/util/ThirdPartyPostRequestUtil.java +++ b/uapbd/src/public/nc/bs/uapbd/util/ThirdPartyPostRequestUtil.java @@ -17,8 +17,8 @@ import java.net.URL; */ public class ThirdPartyPostRequestUtil { - private static final int DEFAULT_CONNECT_TIMEOUT = 10000; - private static final int DEFAULT_READ_TIMEOUT = 10000; + private static final int DEFAULT_CONNECT_TIMEOUT = 20000; + private static final int DEFAULT_READ_TIMEOUT = 20000; /** * 向第三方系统发送 POST 请求,并根据 HTTP 状态码返回数据