From b39472c4fb2cbb0dca67cb39264654843932d9e7 Mon Sep 17 00:00:00 2001 From: mzr Date: Thu, 14 Aug 2025 18:34:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=90=88=E5=90=8C=E9=94=80?= =?UTF-8?q?=E5=94=AE=E8=AE=A2=E5=8D=95=E7=9A=84=E6=95=B0=E9=87=8F=E4=BF=A1?= =?UTF-8?q?=E6=81=AF-=E7=B4=AF=E8=AE=A1=E5=AE=89=E6=8E=92=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E8=AE=A2=E5=8D=95=E4=B8=BB=E6=95=B0=E9=87=8F+?= =?UTF-8?q?=E7=B4=AF=E8=AE=A1=E7=A1=AE=E8=AE=A4=E5=BA=94=E6=94=B6=E9=87=91?= =?UTF-8?q?=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../so/m30/so/m33/Rewrite30For33Impl.java | 427 ++++++++++++++++++ .../so/m30arrange/Rewrite30ArrangeImpl.java | 307 +++++++++++++ .../nc/pubimpl/so/rule/SyncClmNumRule.java | 76 ++++ .../public/nc/vo/so/m30/util/HttpClmUtil.java | 211 +++++++++ .../nc/vo/so/m30/util/IgnoreSslUtil.java | 55 +++ 5 files changed, 1076 insertions(+) create mode 100644 so/src/private/nc/pubimpl/so/m30/so/m33/Rewrite30For33Impl.java create mode 100644 so/src/private/nc/pubimpl/so/m30arrange/Rewrite30ArrangeImpl.java create mode 100644 so/src/private/nc/pubimpl/so/rule/SyncClmNumRule.java create mode 100644 so/src/public/nc/vo/so/m30/util/HttpClmUtil.java create mode 100644 so/src/public/nc/vo/so/m30/util/IgnoreSslUtil.java diff --git a/so/src/private/nc/pubimpl/so/m30/so/m33/Rewrite30For33Impl.java b/so/src/private/nc/pubimpl/so/m30/so/m33/Rewrite30For33Impl.java new file mode 100644 index 0000000..9f636f1 --- /dev/null +++ b/so/src/private/nc/pubimpl/so/m30/so/m33/Rewrite30For33Impl.java @@ -0,0 +1,427 @@ +package nc.pubimpl.so.m30.so.m33; + +import com.yonyou.cloud.ncc.NCCSagas; +import nc.bs.so.m30.plugin.ServicePlugInPoint; +import nc.bs.so.m30.rule.credit.RenovateARByBidsBeginRule; +import nc.bs.so.m30.rule.credit.RenovateARByBidsEndRule; +import nc.impl.pubapp.env.BSContext; +import nc.impl.pubapp.pattern.data.view.ViewQuery; +import nc.impl.pubapp.pattern.data.view.ViewUpdate; +import nc.impl.pubapp.pattern.pub.LockOperator; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.itf.so.m30.compensate.ISaleOrderToRmSagasCompensate; +import nc.pubimpl.so.m30.so.m33.rule.RewriteInvoiceStateRule; +import nc.pubimpl.so.rule.SyncClmNumRule; +import nc.pubitf.so.m30.so.m33.IRewrite30For33; +import nc.pubitf.so.m30.so.m33.Rewrite33Para; +import nc.pubitf.so.m30.so.m33.Rewrite33RmPara; +import nc.vo.credit.engrossmaintain.pub.action.M30EngrossAction; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.bill.CombineBill; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.log.TimeLog; +import nc.vo.pubapp.pattern.pub.MathTool; +import nc.vo.scmpub.res.billtype.SOBillType; +import nc.vo.scmpub.util.SagasConst; +import nc.vo.scmpub.util.SagasUtil; +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.m30.entity.SaleOrderViewVO; +import nc.vo.so.pub.util.SOSagasConst; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 回写 + * + * @author yixl + * @version 2013-03-27 11:03:36 + * @since 6.1 + */ +public class Rewrite30For33Impl implements IRewrite30For33 { + /** + * 针对于收入确认时段进行的分摊,在收入确认单审批通过回写销售订单的累计收入确认金额定义的接口 + */ + + @Override + public void rewrite30RMForConrim(Rewrite33RmPara[] paras) throws BusinessException { + List orderBidPks = new ArrayList(); + for (Rewrite33RmPara para : paras) { + orderBidPks.add(para.getCsaleorderbid()); + } + if (orderBidPks.size() > 0) { + if (!SagasUtil.isNccnativeMerged()) { + String[] ids = orderBidPks.toArray(new String[orderBidPks.size()]); + ViewQuery bo = new ViewQuery(SaleOrderViewVO.class); + bo.setSharedHead(true); + SaleOrderViewVO[] views = bo.query(ids); + SaleOrderVO[] vos = this.viewToSaleOrderVO(views); + // 冻结销售订单 + SagasUtil.frozenAndAddSagaForHead(vos, SOBillType.Order.getCode()); + // 埋入补偿 + Map paraMap = new HashMap(); + paraMap.put(SOSagasConst.OPERATER, SagasConst.REWRITE); + paraMap.put("rewritePara", (Serializable) paras); + NCCSagas.compensate(ISaleOrderToRmSagasCompensate.class, paraMap); + } + // 对销售订单进行回写 + this.rewrite30RMFor33(paras); + } + + } + + private SaleOrderVO[] viewToSaleOrderVO(SaleOrderViewVO[] views) { + int len = views.length; + SaleOrderVO[] bills = new SaleOrderVO[len]; + for (int i = 0; i < len; i++) { + bills[i] = views[i].changeToSaleOrderVO(); + } + CombineBill cb = new CombineBill(); + cb.appendKey(SaleOrderHVO.CSALEORDERID); + return cb.combine(bills); + } + + /** + * 销售应收结算回写销售订单累计递延收入金额、累计收入确认金额 add by huoyzh 2020-09-11 + */ + @Override + public void rewrite30RMFor33(Rewrite33RmPara[] paras) throws BusinessException { + Map index = this.prepareParamsRm(paras); + // 查询销售订单表体 + SaleOrderViewVO[] views = this.queryRm(index); + // 金额累加 + this.setRmMny(views, index); + // 更新数据库 + String[] names = new String[]{SaleOrderBVO.DEFERRALMNY, SaleOrderBVO.REVCONFIRMMNY}; + ViewUpdate bo = new ViewUpdate(); + bo.update(views, SaleOrderBVO.class, names); + TimeLog.info("更新数据库"); + + } + + @Override + public void rewrite30ARFor33(Rewrite33Para[] paras) throws BusinessException { + try { + + Map index = this.prepareParams(paras); + BSContext.getInstance().setSession(Rewrite33Para.class.getName(), index); + // 查询销售订单表体 + SaleOrderViewVO[] views = this.query(index); + + AroundProcesser processer = new AroundProcesser( + ServicePlugInPoint.rewrite30ARFor33); + this.addRule(processer, M30EngrossAction.M30ArReWrite); + // 执行前规则 + processer.before(views); + + // 设置应收结算数量、金额 + this.setARNumMny(views, index); + String[] names = new String[]{SaleOrderBVO.NTOTALARNUM, SaleOrderBVO.NTOTALARMNY}; + this.rewrite(views, names); + + // 执行后规则 + processer.after(views); + // 此处释放session变量,以免浪费内存 + BSContext.getInstance().removeSession(Rewrite33Para.class.getName()); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ETFor33(Rewrite33Para[] paras) throws BusinessException { + Map index = this.prepareParams(paras); + BSContext.getInstance().setSession(Rewrite33Para.class.getName(), index); + // 查询销售订单表体 + SaleOrderViewVO[] views = this.query(index); + + AroundProcesser processer = new AroundProcesser( + ServicePlugInPoint.rewrite30ETFor33); + this.addRule(processer, M30EngrossAction.M30EstArReWrite); + // 执行前规则 + processer.before(views); + + // 设置暂估金额,数量 + this.setETNumMny(views, index); + String[] names = new String[]{SaleOrderBVO.NTOTALESTARMNY, SaleOrderBVO.NTOTALESTARNUM}; + this.rewrite(views, names); + + // 执行后规则 + processer.after(views); + // 此处释放session变量,以免浪费内存 + BSContext.getInstance().removeSession(Rewrite33Para.class.getName()); + } + + @Override + public void rewrite30IAFor33(Rewrite33Para[] paras) throws BusinessException { + Map index = this.prepareParams(paras); + BSContext.getInstance().setSession(Rewrite33Para.class.getName(), index); + // 查询销售订单表体 + SaleOrderViewVO[] views = this.query(index); + + // 设置应收结算数量 + this.setCostNum(views, index); + + String[] names = new String[]{SaleOrderBVO.NTOTALCOSTNUM}; + this.rewrite(views, names); + + // 此处释放session变量,以免浪费内存 + BSContext.getInstance().removeSession(Rewrite33Para.class.getName()); + } + + @Override + public void rewrite30OutRushFor33(Rewrite33Para[] paras) throws BusinessException { + + Map index = this.prepareParams(paras); + BSContext.getInstance().setSession(Rewrite33Para.class.getName(), index); + // 查询销售订单表体 + SaleOrderViewVO[] views = this.query(index); + + AroundProcesser processer = new AroundProcesser( + ServicePlugInPoint.rewrite30OutRushFor33); + this.addRuleForOutRush(processer, M30EngrossAction.M30RushReWrite); + // 执行前规则 + processer.before(views); + + // 设置应收结算数量 + this.setOutRushNum(views, index); + + String[] names = new String[]{SaleOrderBVO.NTOTALRUSHNUM}; + this.rewrite(views, names); + + // 执行后规则 + processer.after(views); + + // 此处释放session变量,以免浪费内存 + BSContext.getInstance().removeSession(Rewrite33Para.class.getName()); + } + + private void addRule(AroundProcesser processer, M30EngrossAction engrossAction) { + // 更新信用调用前 + processer.addBeforeRule(new RenovateARByBidsBeginRule(engrossAction)); + + // -------------------------------------- + // 更新信用调用后 + processer.addAfterRule(new RenovateARByBidsEndRule(engrossAction)); + // 同步CLM合同销售订单 + processer.addAfterRule(new SyncClmNumRule("totalaccrued")); + } + + private void addRuleForOutRush(AroundProcesser processer, M30EngrossAction engrossAction) { + // 更新信用调用前 + processer.addBeforeRule(new RenovateARByBidsBeginRule(engrossAction)); + + // -------------------------------------- + // 更新信用调用后 + processer.addAfterRule(new RenovateARByBidsEndRule(engrossAction)); + + // 出库对冲影响发票关闭状态,注意要在信用调用之后调用此方法 + processer.addAfterRule(new RewriteInvoiceStateRule()); + + } + + private String[] lockBills(Map index) { + int size = index.size(); + String[] bids = new String[size]; + bids = index.keySet().toArray(bids); + LockOperator locker = new LockOperator(); + String message = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + "04006011-0187")/* @res "销售结算回写销售订单累计结算数量,锁销售订单表体失败" */; + locker.lock(bids, message); + return bids; + } + + private String[] lockBillRms(Map index) { + int size = index.size(); + String[] bids = new String[size]; + bids = index.keySet().toArray(bids); + LockOperator locker = new LockOperator(); + String message = "销售结算回写销售订单收入确认的金额,锁销售订单表体失败"; + locker.lock(bids, message); + return bids; + } + + private Map prepareParams(Rewrite33Para[] paras) { + Map index = new HashMap(); + for (Rewrite33Para para : paras) { + index.put(para.getCsaleorderbid(), para); + } + return index; + } + + private Map prepareParamsRm(Rewrite33RmPara[] paras) { + Map index = new HashMap(); + for (Rewrite33RmPara para : paras) { + if (null == index.get(para.getCsaleorderbid())) { + index.put(para.getCsaleorderbid(), para); + } else { + Rewrite33RmPara old = index.get(para.getCsaleorderbid()); + if (old.getRmtype().equals(para.getRmtype())) { + old.setNarmny(MathTool.add(old.getNarmny(), para.getNarmny())); + } + } + + } + return index; + } + + private SaleOrderViewVO[] query(Map index) { + String[] ids = this.lockBills(index); + ViewQuery bo = new ViewQuery(SaleOrderViewVO.class); + bo.setSharedHead(true); + + SaleOrderViewVO[] views = bo.query(ids); + if (views.length != index.size()) { + String message = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + "04006011-0171")/* @res "出现并发,请重新查询销售订单" */; + ExceptionUtils.wrappBusinessException(message); + } + return views; + } + + private SaleOrderViewVO[] queryRm(Map index) { + String[] ids = this.lockBillRms(index); + ViewQuery bo = new ViewQuery(SaleOrderViewVO.class); + bo.setSharedHead(true); + + SaleOrderViewVO[] views = bo.query(ids); + if (views.length != index.size()) { + String message = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + "04006011-0171")/* @res "出现并发,请重新查询销售订单" */; + ExceptionUtils.wrappBusinessException(message); + } + return views; + } + + private void rewrite(SaleOrderViewVO[] views, String[] names) { + AroundProcesser processer = new AroundProcesser( + ServicePlugInPoint.rewrite30NumFor33); + + TimeLog.logStart(); + processer.before(views); + TimeLog.info("写数据库前执行业务规则"); /*-=notranslate=-*/ + + TimeLog.logStart(); + ViewUpdate bo = new ViewUpdate(); + SaleOrderViewVO[] retviews = bo.update(views, SaleOrderBVO.class, names); + TimeLog.info("更新数据库"); /*-=notranslate=-*/ + + TimeLog.logStart(); + processer.after(retviews); + TimeLog.info("写数据库后执行业务规则"); /*-=notranslate=-*/ + + } + + /** + * 方法功能描述:设置累计应收结算数量、金额 + *

+ * examples: + *

+ * 使用示例 + *

+ * 参数说明 + * + * @param vos + * @param index

+ * @author zhangcheng + * @time 2010-7-16 下午12:00:15 + */ + private void setARNumMny(SaleOrderViewVO[] vos, Map index) { + UFDouble ntotalarnum = null; + UFDouble ntotalarmny = null; + SaleOrderBVO body = null; + for (SaleOrderViewVO vo : vos) { + body = vo.getBody(); + Rewrite33Para para = index.get(body.getCsaleorderbid()); + ntotalarnum = body.getNtotalarnum(); + ntotalarmny = body.getNtotalarmny(); + body.setNtotalarnum(MathTool.add(ntotalarnum, para.getNarnum())); + body.setNtotalarmny(MathTool.add(ntotalarmny, para.getNarmny())); + } + } + + /** + * 方法功能描述:设置累计收入确认金额 + *

+ * examples: + *

+ * 使用示例 + *

+ * 参数说明 + * + * @param vos + * @param index

+ * @author huoyzh + * @time 2020-09-11 + */ + private void setRmMny(SaleOrderViewVO[] vos, Map index) { + UFDouble deferralmny = null;// 记录递延累计 + UFDouble revconfirmmny = null;// 记录收入确认的 + SaleOrderBVO body = null; + for (SaleOrderViewVO vo : vos) { + body = vo.getBody(); + Rewrite33RmPara para = index.get(body.getCsaleorderbid()); + // 递延累计金额 + if ("RMDC".equals(para.getRmtype())) { + deferralmny = body.getDeferralmny(); + body.setDeferralmny(MathTool.add(deferralmny, para.getNarmny())); + // 收入确认金额 + } else if ("RMCF".equals(para.getRmtype())) { + revconfirmmny = body.getRevconfirmmny(); + body.setRevconfirmmny(MathTool.add(revconfirmmny, para.getNarmny())); + } + } + } + + private void setCostNum(SaleOrderViewVO[] vos, Map index) { + UFDouble ntotaletcostnum; + SaleOrderBVO body = null; + for (SaleOrderViewVO vo : vos) { + body = vo.getBody(); + Rewrite33Para para = index.get(body.getCsaleorderbid()); + ntotaletcostnum = body.getNtotalcostnum(); + body.setNtotalcostnum(MathTool.add(ntotaletcostnum, para.getNarnum())); + // dongli2--2013.8.29 因超容差开票,发票审批报错:累计成本结算数量不能大于订单主数量! + // 先注掉 以后考虑 + // if (MathTool.greaterThan(MathTool.abs(body.getNtotalcostnum()), + // MathTool.abs(body.getNnum()))) { + // String message = + // nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + // "04006011-0475")/*@res "累计成本结算数量不能大于订单主数量!"*/; + // ExceptionUtils.wrappBusinessException(message); + // } + } + } + + private void setETNumMny(SaleOrderViewVO[] vos, Map index) { + UFDouble ntotaletarnum = null; + UFDouble ntotaletarmny = null; + SaleOrderBVO body = null; + for (SaleOrderViewVO vo : vos) { + body = vo.getBody(); + Rewrite33Para para = index.get(body.getCsaleorderbid()); + ntotaletarnum = body.getNtotalestarnum(); + ntotaletarmny = body.getNtotalestarmny(); + body.setNtotalestarnum(MathTool.add(ntotaletarnum, para.getNarnum())); + body.setNtotalestarmny(MathTool.add(ntotaletarmny, para.getNarmny())); + } + } + + private void setOutRushNum(SaleOrderViewVO[] vos, Map index) { + UFDouble ntotaloutrushnum; + SaleOrderBVO body = null; + for (SaleOrderViewVO vo : vos) { + body = vo.getBody(); + Rewrite33Para para = index.get(body.getCsaleorderbid()); + ntotaloutrushnum = body.getNtotalrushnum(); + body.setNtotalrushnum(MathTool.add(ntotaloutrushnum, para.getNarnum())); + } + } + +} diff --git a/so/src/private/nc/pubimpl/so/m30arrange/Rewrite30ArrangeImpl.java b/so/src/private/nc/pubimpl/so/m30arrange/Rewrite30ArrangeImpl.java new file mode 100644 index 0000000..4d04973 --- /dev/null +++ b/so/src/private/nc/pubimpl/so/m30arrange/Rewrite30ArrangeImpl.java @@ -0,0 +1,307 @@ +package nc.pubimpl.so.m30arrange; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import com.yonyou.cloud.ncc.NCCSagas; + +import nc.bs.so.m30.plugin.ServicePlugInPoint; +import nc.impl.pubapp.env.BSContext; +import nc.impl.pubapp.pattern.data.view.ViewQuery; +import nc.impl.pubapp.pattern.data.view.ViewUpdate; +import nc.impl.pubapp.pattern.pub.LockOperator; +import nc.impl.pubapp.pattern.rule.plugin.IPluginPoint; +import nc.impl.pubapp.pattern.rule.processer.AroundProcesser; +import nc.pubimpl.so.m30arrange.rule.RewriteCheckArrangeNumRule; +import nc.pubimpl.so.m30arrange.rule.RewriteCheckOutCloseRule; +import nc.pubimpl.so.m30arrange.rule.RewriteSetNumRule; +import nc.pubimpl.so.rule.SyncClmNumRule; +import nc.pubitf.so.m30arrange.Rewrite30ArrangePara; +import nc.pubitf.so.m30arrange.mm.m55a2.IRewrite30For55A2; +import nc.pubitf.so.m30arrange.mm.m55a2.IRewrite30ForMMSagasCompensate; +import nc.pubitf.so.m30arrange.mmpps.plo.IRewrite30For55B4; +import nc.pubitf.so.m30arrange.po.m20.IRewrite30For20; +import nc.pubitf.so.m30arrange.po.m21.IRewrite30For21; +import nc.pubitf.so.m30arrange.sc.m61.IRewrite30For61; +import nc.pubitf.so.m30arrange.to.m5a.IRewrite30For5A; +import nc.pubitf.so.m30arrange.to.m5x.IRewrite30For5X; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.exception.ExceptionUtils; +import nc.vo.pubapp.pattern.log.TimeLog; +import nc.vo.pubapp.pattern.pub.MathTool; +import nc.vo.scmpub.res.billtype.IBillType; +import nc.vo.scmpub.res.billtype.MMBillType; +import nc.vo.scmpub.res.billtype.POBillType; +import nc.vo.scmpub.res.billtype.SCBillType; +import nc.vo.scmpub.res.billtype.SOBillType; +import nc.vo.scmpub.res.billtype.TOBillType; +import nc.vo.scmpub.util.SagasUtil; +import nc.vo.so.m30.entity.SaleOrderBVO; +import nc.vo.so.m30.entity.SaleOrderHVO; +import nc.vo.so.m30.entity.SaleOrderViewVO; +import nc.vo.so.pub.util.SOSagasConst; + +/** + * 补货直运安排回写销售订单 + * + * @author yixl + * @version 2013-04-26 16:13:42 + * @since 6.1 + */ +public class Rewrite30ArrangeImpl implements IRewrite30For20, IRewrite30For21, + IRewrite30For5A, IRewrite30For5X, IRewrite30For61, IRewrite30For55A2, + IRewrite30For55B4 { + + private void addRule(AroundProcesser processer, + IBillType srctype) { + // 直运采购不需要检查 + if (!(POBillType.Order.getCode().equals(srctype.getCode()) || POBillType.PrayBill + .getCode().equals(srctype.getCode()))) { + processer.addBeforeFinalRule(new RewriteCheckOutCloseRule()); + } + processer.addBeforeRule(new RewriteCheckArrangeNumRule()); + processer.addBeforeRule(new RewriteSetNumRule()); + if (MMBillType.ProduceOrder.getCode().equals(srctype.getCode()) || MMBillType.LsProduceOrder.getCode().equals(srctype.getCode())) { + // 同步CLM合同销售订单 + processer.addAfterRule(new SyncClmNumRule("narrangemonum")); + } + } + + private IPluginPoint getServicePlugInPoint(Rewrite30ArrangePara para) { + IPluginPoint pluginPoint = null; + if (POBillType.PrayBill.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumFor20; + } else if (POBillType.Order.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumFor21; + } else if (TOBillType.TransIn.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumFor5A; + } else if (TOBillType.TransOrder.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumFor5X; + } else if (SCBillType.Order.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumFor61; + } else if (MMBillType.ProduceOrder.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30ArrangeNumForA2; + } else if (MMBillType.PlanOrder.isEqual(para.getBilltype())) { + pluginPoint = ServicePlugInPoint.rewrite30npolnumFor55B4; + } + return pluginPoint; + } + + private String[] getUpdateNames(Rewrite30ArrangePara para) { + String arrangeName = null; + if (POBillType.PrayBill.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGEPOAPPNUM; + } else if (POBillType.Order.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGEPONUM; + } else if (TOBillType.TransIn.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGETOAPPNUM; + } else if (TOBillType.TransOrder.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGETOORNUM; + } else if (SCBillType.Order.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGESCORNUM; + } else if (MMBillType.ProduceOrder.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGEMONUM; + } else if (MMBillType.LsProduceOrder.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NARRANGEMONUM; + } else if (MMBillType.PlanOrder.isEqual(para.getBilltype())) { + arrangeName = SaleOrderBVO.NTOTALPLONUM; + } + + String[] names = + new String[]{ + arrangeName, SaleOrderBVO.CARRANGEPERSONID, + SaleOrderBVO.TLASTARRANGETIME, SaleOrderBVO.BARRANGEDFLAG + }; + return names; + } + + private String[] lockBills(Map index) { + int size = index.size(); + String[] bids = new String[size]; + bids = index.keySet().toArray(bids); + LockOperator locker = new LockOperator(); + String message = + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + "04006011-0191")/*@res "补货/安排下游单据回写销售订单累计安排数量,锁销售订单表体失败"*/; + locker.lock(bids, message); + return bids; + } + + private Map prepareParams( + Rewrite30ArrangePara[] paras) { + Map index = + new HashMap(); + for (Rewrite30ArrangePara para : paras) { + String bid = para.getCsaleorderbid(); + Rewrite30ArrangePara oldpara = index.get(bid); + if (null == oldpara) { + index.put(bid, para); + } else { + UFDouble oldnum = oldpara.getNnum(); + oldpara.setNnum(MathTool.add(oldnum, para.getNnum())); + } + + } + return index; + } + + private SaleOrderViewVO[] query(Map index) { + String[] ids = this.lockBills(index); + ViewQuery bo = + new ViewQuery(SaleOrderViewVO.class); + bo.setSharedHead(true); + + SaleOrderViewVO[] views = bo.query(ids); + if (views.length != index.size()) { + String message = + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", + "04006011-0171")/*@res "出现并发,请重新查询销售订单"*/; + ExceptionUtils.wrappBusinessException(message); + } + return views; + } + + private void rewrite(Rewrite30ArrangePara[] paras, IBillType srctype) { + TimeLog.logStart(); + Map index = this.prepareParams(paras); + // 此处设置session变量,以避免程序到处传递 + BSContext.getInstance().setSession(Rewrite30ArrangePara.class.getName(), + index); + TimeLog.info("并处理参数"); /*-=notranslate=-*/ + + TimeLog.logStart(); + SaleOrderViewVO[] views = this.query(index); + TimeLog.info("查询销售订单表体"); /*-=notranslate=-*/ + + // 计划订单回写时需要冻结并埋回退逻辑 add by yangls7 for 2012 + if (!SagasUtil.isNccnativeMerged() + && (MMBillType.PlanOrder.equals(srctype) || MMBillType.ProduceOrder.equals(srctype))) { + this.frozenAndAddSaga(views, srctype); + } + + AroundProcesser processer = + new AroundProcesser( + this.getServicePlugInPoint(paras[0])); + this.addRule(processer, srctype); + + TimeLog.logStart(); + processer.before(views); + TimeLog.info("写数据库前执行业务规则"); /*-=notranslate=-*/ + + TimeLog.logStart(); + + ViewUpdate bo = new ViewUpdate(); + views = bo.update(views, SaleOrderBVO.class, this.getUpdateNames(paras[0])); + TimeLog.info("更新数据库"); /*-=notranslate=-*/ + + TimeLog.logStart(); + processer.after(views); + TimeLog.info("写数据库后执行业务规则"); /*-=notranslate=-*/ + + // 此处释放session变量,以免浪费内存 + BSContext.getInstance().removeSession(Rewrite30ArrangePara.class.getName()); + } + + @Override + public void rewrite30ArrangeNumFor20(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, POBillType.PrayBill); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ArrangeNumFor21(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, POBillType.Order); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ArrangeNumFor55A2(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, MMBillType.ProduceOrder); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ArrangeNumFor5A(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, TOBillType.TransIn); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ArrangeNumFor5X(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, TOBillType.TransOrder); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30ArrangeNumFor61(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, SCBillType.Order); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + @Override + public void rewrite30npolnumFor55B4(Rewrite30ArrangePara[] paras) + throws BusinessException { + try { + this.rewrite(paras, MMBillType.PlanOrder); + } catch (RuntimeException ex) { + ExceptionUtils.marsh(ex); + } + } + + /** + * 当生成生产订单时冻结销售订单,并埋补偿接口 + * add by yangls7 for ncc2012 + */ + private void frozenAndAddSaga(SaleOrderViewVO[] views, IBillType srctype) { + + SaleOrderHVO[] heads = new SaleOrderHVO[views.length]; + SaleOrderBVO[] bodys = new SaleOrderBVO[views.length]; + for (int i = 0; i < views.length; i++) { + heads[i] = views[i].getHead(); + SaleOrderBVO bvo = new SaleOrderBVO(); + bvo.setCsaleorderbid(views[i].getBody().getCsaleorderbid()); + bvo.setNarrangemonum(views[i].getBody().getNarrangemonum()); + bvo.setNtotalplonum(views[i].getBody().getNtotalplonum()); + bodys[i] = bvo; + } + // 冻结 + SagasUtil.frozenAndAddSaga(heads, SOBillType.Order.getCode()); + // 补偿 + Map map = new HashMap(); + if (MMBillType.PlanOrder.equals(srctype)) { + map.put(SOSagasConst.OPERATER, SOSagasConst.PLOREWRITE30); + } else { + map.put(SOSagasConst.OPERATER, SOSagasConst.PDOREWRITE30); + } + map.put(SOSagasConst.VOS, bodys); + + NCCSagas.compensate(IRewrite30ForMMSagasCompensate.class, map); + } + +} diff --git a/so/src/private/nc/pubimpl/so/rule/SyncClmNumRule.java b/so/src/private/nc/pubimpl/so/rule/SyncClmNumRule.java new file mode 100644 index 0000000..0394224 --- /dev/null +++ b/so/src/private/nc/pubimpl/so/rule/SyncClmNumRule.java @@ -0,0 +1,76 @@ +package nc.pubimpl.so.rule; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.impl.pubapp.pattern.rule.IRule; +import nc.vo.so.m30.entity.SaleOrderBVO; +import nc.vo.so.m30.entity.SaleOrderHVO; +import nc.vo.so.m30.entity.SaleOrderViewVO; +import nc.vo.so.m30.util.HttpClmUtil; +import nccloud.commons.lang.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 同步合同销售订单的数量信息 + */ +public class SyncClmNumRule implements IRule { + private String flag = ""; + + public SyncClmNumRule() { + } + + public SyncClmNumRule(String flag) { + this.flag = flag; + } + + public void process(SaleOrderViewVO[] vos) { + JSONArray array = new JSONArray(); + for (SaleOrderViewVO vo : vos) { + SaleOrderHVO head = vo.getHead(); + SaleOrderBVO body = vo.getBody(); + String vdef9 = head.getVdef9();// BIP合同销售订单id + String vbdef11 = body.getVbdef11();// BIP合同销售订单更新 子表id + if (StringUtils.isEmpty(vdef9) || StringUtils.isEmpty(vbdef11)) { + continue; + } + // 累计安排生产订单主数量 + Object narrangemonum = body.getAttributeValue("narrangemonum"); + if ("narrangemonum".equals(flag) && narrangemonum == null) { + continue; + } + // 累计确认应收金额 + Object totalaccrued = body.getAttributeValue("totalaccrued"); + if ("totalaccrued".equals(flag) && totalaccrued == null) { + continue; + } + JSONObject oneJson = new JSONObject(); + List> bodyList = new ArrayList<>(); + Map bodyMap = new HashMap<>(); + + bodyMap.put("id", vbdef11); + if (narrangemonum != null) { + bodyMap.put("narrangemonum", narrangemonum); + } + if (totalaccrued != null) { + bodyMap.put("totalAccrued", totalaccrued); + } + + bodyList.add(bodyMap); + + oneJson.put("contractOrdersList", bodyList); + + oneJson.put("id", vdef9); + array.add(oneJson); + } + if (!array.isEmpty()) { + JSONObject reqData = new JSONObject(); + reqData.put("HTXSDD", array); + HttpClmUtil httpClmUtil = new HttpClmUtil(); + httpClmUtil.reqSaleOrder(reqData); + } + } +} diff --git a/so/src/public/nc/vo/so/m30/util/HttpClmUtil.java b/so/src/public/nc/vo/so/m30/util/HttpClmUtil.java new file mode 100644 index 0000000..9eddb90 --- /dev/null +++ b/so/src/public/nc/vo/so/m30/util/HttpClmUtil.java @@ -0,0 +1,211 @@ +package nc.vo.so.m30.util; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.gson.Gson; +import com.yonyou.cloud.utils.StringUtils; +import nc.bs.dao.DAOException; +import nc.bs.logging.Logger; +import nc.bs.trade.business.HYSuperDMO; +import nc.vo.bd.defdoc.DefdocVO; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.net.ssl.HttpsURLConnection; +import java.io.*; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +/** + * 请求合同平台接口的工具类 + * + * @author mzr + * @date 2025/8/14 + */ +public class HttpClmUtil { + + private HYSuperDMO superDMO = null; + private String appKey = ""; + private String appSecret = ""; + private String baseUrl = ""; + private String tokenUrl = "/iuap-api-auth/open-auth/selfAppAuth/getAccessToken"; + private String toBipUrl = ""; + + public HYSuperDMO getSuperDMO() { + if (superDMO == null) { + superDMO = new HYSuperDMO(); + } + return superDMO; + } + + public void reqSaleOrder(JSONObject reqData) { + // 从自定义档案中获取 + try { + Map bipParamMap = checkBipParam(); + if (bipParamMap.isEmpty()) { + Logger.error("HttpClmUtil-bipParamMap is empty"); + return; + } + baseUrl = bipParamMap.get("baseUrl"); + appKey = bipParamMap.get("appKey"); + appSecret = bipParamMap.get("appSecret"); + toBipUrl = bipParamMap.get("contractSaleOrder"); + String accessToken = getAccessToken(); + if (StringUtils.isEmpty(accessToken)) { + Logger.error("HttpClmUtil-accessToken is empty"); + return; + } + Logger.error("HttpClmUtil-param = " + reqData.toJSONString()); + String url = baseUrl + toBipUrl + "?access_token=" + accessToken; + String resultString = doPost(url, reqData); + Logger.error("HttpClmUtil-res = " + resultString); + } catch (Exception e) { + Logger.error("HttpClmUtil-error:" + e.getMessage(), e); + } + } + + /** + * 获取旗舰版的token + * + * @return token + * @author mzr + * @date 2025/3/20 + */ + private String getAccessToken() throws NoSuchAlgorithmException, InvalidKeyException, IOException { + String access_token = ""; + // 获取旗舰版的token + Map params = new HashMap<>(); + // 除签名外的其他参数 + params.put("appKey", appKey); + String timestamp = String.valueOf(System.currentTimeMillis()); + params.put("timestamp", timestamp); + // 计算签名 + Map treeMap = new TreeMap<>(params); + StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry entry : treeMap.entrySet()) { + stringBuilder.append(entry.getKey()).append(entry.getValue()); + } + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); + byte[] signData = mac.doFinal(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); + String base64String = Base64.getEncoder().encodeToString(signData); + String signature = URLEncoder.encode(base64String, StandardCharsets.UTF_8); + params.put("signature", signature); + String responseString = doGet(baseUrl + tokenUrl, params); + Logger.error("HttpClmUtil-responseString = " + responseString); + Gson gson = new Gson(); + Map result = gson.fromJson(responseString, Map.class); + if (StringUtils.equals("00000", result.getOrDefault("code", "") + "")) { + Map tokenInfo = (Map) result.get("data"); + access_token = (String) tokenInfo.getOrDefault("access_token", ""); + } + Logger.error("HttpClmUtil-getAccessToken = " + access_token); + return access_token; + } + + private String doGet(String requestUrl, Map paramMap) throws IOException { + + StringBuilder param = new StringBuilder("?"); + if (paramMap != null) { + for (Map.Entry entry : paramMap.entrySet()) { + param.append(entry.getKey()); + param.append("="); + param.append(entry.getValue()); + param.append("&"); + } + param.deleteCharAt(param.length() - 1); + } + String url = requestUrl + param; + URL u = new URL(url); + try { + if ("https".equalsIgnoreCase(u.getProtocol())) {// 判定网址是否信任,不信任则调用忽略信任工具类SslUtil + IgnoreSslUtil.ignoreSsl(); + } + HttpsURLConnection connection = (HttpsURLConnection) u.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + connection.connect(); + StringBuilder response = new StringBuilder(); + int responsecode = connection.getResponseCode(); + if (responsecode == HttpsURLConnection.HTTP_OK) { + InputStream inputstream = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream)); + String line; + + while ((line = reader.readLine()) != null) { + response.append(line); + } + reader.close(); + } + connection.disconnect(); + return response.toString(); + } catch (Exception e) { + Logger.error("HttpClmUtil-doGet:" + e.getMessage(), e); + } + + + return null; + } + + private String doPost(String requestUrl, JSONObject json) throws IOException { + URL u = new URL(requestUrl); + try { + if ("https".equalsIgnoreCase(u.getProtocol())) {// 判定网址是否信任,不信任则调用忽略信任工具类SslUtil + IgnoreSslUtil.ignoreSsl(); + } + HttpsURLConnection connection = (HttpsURLConnection) u.openConnection(); + // 设置请求方法 + connection.setRequestMethod("POST"); + // 设置请求属性 + connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + // 发送POST请求必须设置如下两行 + connection.setDoOutput(true); + connection.setDoInput(true); + byte[] outputInBytes = json.toJSONString().getBytes(StandardCharsets.UTF_8); + // 写入数据到请求体 + OutputStream os = connection.getOutputStream(); + os.write(outputInBytes); + // 获取响应码 + int responseCode = connection.getResponseCode(); + // System.out.println("Response Code: " + responseCode); + // 读取响应 + String response = ""; + try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + br.readLine(); + // System.out.println("Response: " + response); + } + // 关闭连接 + connection.disconnect(); + return response; + } catch (Exception e) { + Logger.error("HttpClmUtil-doPost:" + e.getMessage(), e); + } + return null; + } + + /** + * 检查bip参数是否完整 + */ + private Map checkBipParam() { + Map map = new HashMap(); + String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='BIP-sq' and dr=0 ) and dr=0"; + try { + DefdocVO[] defdocVOs = (DefdocVO[]) getSuperDMO().queryByWhereClause(DefdocVO.class, strWhere); + if (defdocVOs != null && defdocVOs.length > 0) { + for (DefdocVO defdocVO : defdocVOs) { + map.put(defdocVO.getCode().trim(), defdocVO.getName()); + } + } + } catch (DAOException e) { + Logger.error("HttpClmUtil-checkBipParam:" + e.getMessage(), e); + } + return map; + + } + +} diff --git a/so/src/public/nc/vo/so/m30/util/IgnoreSslUtil.java b/so/src/public/nc/vo/so/m30/util/IgnoreSslUtil.java new file mode 100644 index 0000000..d5b0923 --- /dev/null +++ b/so/src/public/nc/vo/so/m30/util/IgnoreSslUtil.java @@ -0,0 +1,55 @@ +package nc.vo.so.m30.util; + +import javax.net.ssl.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +public class IgnoreSslUtil { + private static void trustAllHttpsCertificates() throws Exception { + TrustManager[] trustAllCerts = new TrustManager[1]; + TrustManager tm = new miTM(); + trustAllCerts[0] = tm; + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, null); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } + + static class miTM implements TrustManager,X509TrustManager { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public boolean isServerTrusted(X509Certificate[] certs) { + return true; + } + + public boolean isClientTrusted(X509Certificate[] certs) { + return true; + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) + throws CertificateException { + return; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) + throws CertificateException { + return; + } + } + + /** + * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用 + * @throws Exception + */ + public static void ignoreSsl() throws Exception{ + HostnameVerifier hv = new HostnameVerifier() { + public boolean verify(String urlHostName, SSLSession session) { + System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); + return true; + } + }; + trustAllHttpsCertificates(); + HttpsURLConnection.setDefaultHostnameVerifier(hv); + } +} \ No newline at end of file