This commit is contained in:
		
							parent
							
								
									215c55e889
								
							
						
					
					
						commit
						09fe9de4ee
					
				|  | @ -0,0 +1,253 @@ | |||
| package nccloud.web.pu.arrival.action; | ||||
| 
 | ||||
| import nc.itf.pu.m23.qc.IArriveForQC; | ||||
| import nc.pubitf.pu.m23.pubquery.IArrivePubQuery; | ||||
| import nc.pubitf.qc.c001.pu.ReturnObjectFor23; | ||||
| import nc.vo.pu.m23.entity.ArriveHeaderVO; | ||||
| import nc.vo.pu.m23.entity.ArriveItemVO; | ||||
| import nc.vo.pu.m23.entity.ArriveVO; | ||||
| import nc.vo.pu.m23.entity.ArriveViewVO; | ||||
| import nc.vo.pu.pub.util.AggVOUtil; | ||||
| import nc.vo.pub.lang.UFDouble; | ||||
| import nc.vo.pubapp.pattern.model.entity.view.AbstractDataView; | ||||
| import nc.vo.pubapp.pattern.model.tool.BillComposite; | ||||
| import nc.vo.qc.pub.enumeration.StrictLevelEnum; | ||||
| import nccloud.commons.lang.ArrayUtils; | ||||
| import nccloud.dto.pu.puinvoice.entity.DataInfo; | ||||
| import nccloud.framework.core.exception.ExceptionUtils; | ||||
| import nccloud.framework.core.json.IJson; | ||||
| import nccloud.framework.service.ServiceLocator; | ||||
| import nccloud.framework.web.action.itf.ICommonAction; | ||||
| import nccloud.framework.web.container.IRequest; | ||||
| import nccloud.framework.web.json.JsonFactory; | ||||
| import nccloud.framework.web.processor.template.GridConvertProcessor; | ||||
| import nccloud.pubitf.pu.arrival.service.IArrivalQueryService; | ||||
| import nccloud.web.pu.arrivalqc.entity.QualityCheckInfo; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * @description 检验 | ||||
|  * @author ligangt | ||||
|  * @date 2018年8月28日 下午1:43:35 | ||||
|  * @version ncc1.0 | ||||
|  */ | ||||
| public class QualityCheckAction implements ICommonAction { | ||||
| 
 | ||||
|     @Override | ||||
|     public Object doAction(IRequest request) { | ||||
|         try { | ||||
|             // 获取前台json | ||||
|             IJson json = JsonFactory.create(); | ||||
|             QualityCheckInfo info = json.fromJson(request.read(), | ||||
|                     QualityCheckInfo.class); | ||||
| 
 | ||||
|             ArriveViewVO[] views = null; | ||||
|             if (info.isQcEnable()) { | ||||
|                 DataInfo[] idTs = info.getIdTs(); | ||||
|                 views = queryViewVOs(idTs); | ||||
|             } else { | ||||
|                 GridConvertProcessor processor = new GridConvertProcessor(); | ||||
|                 views = processor.fromGrid(info.getGrid()); | ||||
|             } | ||||
| 
 | ||||
|             if (views != null && views.length > 0) { | ||||
|                 // IPubUtilService pubService = ServiceLocator | ||||
|                 // .find(IPubUtilService.class); | ||||
|                 // if (pubService.isOrgQcEnable(info.getPk_org())) { | ||||
|                 // 非紧急放行入库数量>0,即根据质检入库 | ||||
|                 // ArriveItemVO item = views[0].getBVO(); | ||||
|                 // if | ||||
|                 // (MathTool.compareTo(MathTool.sub(item.getNaccumstorenum(), | ||||
|                 // item.getNaccumletgoinnum()), UFDouble.ZERO_DBL) > 0) { | ||||
|                 // //ExceptionUtils.wrapBusinessException("紧急放行数量大于入库数量"); | ||||
|                 // return false; | ||||
|                 // } | ||||
|                 // } | ||||
|                 ArriveVO[] vos = this.getArriveVOs(views); | ||||
|                 for (ArriveVO vo : vos) { | ||||
|                     ArriveItemVO[] bvos = vo.getBVO(); | ||||
|                     for (ArriveItemVO bvo : bvos) { | ||||
|                         UFDouble nchecknum = bvo.getNchecknum(); | ||||
|                         UFDouble nwillelignum = bvo.getNwillelignum(); | ||||
|                         if (nchecknum != null && nwillelignum != null) { | ||||
|                             if (nchecknum.compareTo(UFDouble.ZERO_DBL) < 0 | ||||
|                                     || nwillelignum.compareTo(UFDouble.ZERO_DBL) < 0) { | ||||
|                                 ExceptionUtils.wrapBusinessException( | ||||
|                                         nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID( | ||||
|                                                 "4004100_0", "04004100-0010")/* | ||||
|                                          * @res "报检数量和合格主数量不允许为负数" | ||||
|                                          */); | ||||
|                             } | ||||
|                         } | ||||
|                         UFDouble naccumchecknum = bvo.getNaccumchecknum(); | ||||
|                         if (naccumchecknum != null) { | ||||
|                             if (naccumchecknum.compareTo(bvo.getNnum()) == 0) { | ||||
|                                 UFDouble naccumstorenum = bvo.getNaccumstorenum(); | ||||
|                                 if (naccumstorenum != null | ||||
|                                         && naccumstorenum.compareTo(UFDouble.ZERO_DBL) > 0) { | ||||
| //									ExceptionUtils.wrapBusinessException( | ||||
| //											nc.vo.ml.NCLangRes4VoTransl.getNCLangRes() | ||||
| //													.getStrByID("4004100_0", "04004100-0012") | ||||
| //													/* @res "第" */ + bvo.getCrowno() | ||||
| //													+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes() | ||||
| //															.getStrByID("4004100_0", | ||||
| //																	"04004100-0307")/* @res 04004100-0062 "行已经完全入库,不能生成报检单" | ||||
| //																		NCC-362748 修改后:行已经生成过报检单且正在检验中,不允许复检!*/); | ||||
|                                     ExceptionUtils.wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4008015_0", | ||||
|                                             "04008015-0077"+"\n", null, new String[] { | ||||
|                                                     bvo.getCrowno() | ||||
|                                             })); | ||||
| 									/* @res 04004100-0062 "行已经完全入库,不能生成报检单" | ||||
| 																		NCC-362748 修改后:第{0}行已经生成过报检单且正在检验中,不允许复检!*/ | ||||
| 
 | ||||
| 
 | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 ArriveVO[] returnVos = this.check(vos, info.isCheck()); | ||||
|                 if (null == returnVos) { | ||||
|                     ExceptionUtils.wrapBusinessException( | ||||
|                             nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4004100_0", | ||||
|                                     "04004100-0011")/* @res "到货单检验失败!" */); | ||||
|                 } | ||||
|                 ServiceLocator.find(IArriveForQC.class).pushWmsByArriveVOs(vos); | ||||
|                 // 把后台返回的轻量级聚合VO转换为视图VO | ||||
|                 // new ClientBillCombinServer<ArriveVO>().combine(vos, | ||||
|                 // returnVos); | ||||
|                 // ArriveViewVO[] newViews = ArrivePublicUtil | ||||
|                 // .convertAggToViewVO(vos); | ||||
|                 // grid = processor.convert(info.getGrid().getPageid(), | ||||
|                 // newViews); | ||||
| 
 | ||||
|                 // String[] successIds = this.getSuccessBIDs(returnVos); | ||||
|                 // return successIds; | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             ExceptionUtils.wrapException(e); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     private ArriveViewVO[] queryViewVOs(DataInfo[] idTs) { | ||||
|         List<String> bids = new ArrayList<String>(); | ||||
|         Map<String, String> idTsIndex = new HashMap<String, String>(); | ||||
|         for (DataInfo item : idTs) { | ||||
|             bids.add(item.getId()); | ||||
|             idTsIndex.put(item.getId(), item.getTs()); | ||||
|         } | ||||
| 
 | ||||
|         IArrivalQueryService qryService = ServiceLocator | ||||
|                 .find(IArrivalQueryService.class); | ||||
|         ArriveViewVO[] viewvos = qryService | ||||
|                 .queryViewByBIDs(bids.toArray(new String[0])); | ||||
|         // 重设ts | ||||
|         for (ArriveViewVO viewvo : viewvos) { | ||||
|             viewvo.setAttributeValue("ts", | ||||
|                     idTsIndex.get(viewvo.getPk_arriveorder_b())); | ||||
|         } | ||||
| 
 | ||||
|         return viewvos; | ||||
|     } | ||||
| 
 | ||||
|     // private String[] getSuccessBIDs(ArriveVO[] returnVos) { | ||||
|     // List<String> bid_l = new ArrayList<String>(); | ||||
|     // for (ArriveVO arrivevo : returnVos) { | ||||
|     // ArriveItemVO[] itemvos = arrivevo.getBVO(); | ||||
|     // for (ArriveItemVO item : itemvos) { | ||||
|     // bid_l.add(item.getPk_arriveorder_b()); | ||||
|     // } | ||||
|     // } | ||||
|     // return bid_l.toArray(new String[0]); | ||||
|     // } | ||||
| 
 | ||||
|     private ArriveVO[] getArriveVOs(ArriveViewVO[] views) { | ||||
|         List<ArriveHeaderVO> headers = new ArrayList<ArriveHeaderVO>(); | ||||
|         List<ArriveItemVO> items = new ArrayList<ArriveItemVO>(); | ||||
|         for (AbstractDataView view : views) { | ||||
|             headers.add((ArriveHeaderVO) view.getVO(ArriveHeaderVO.class)); | ||||
|             items.add((ArriveItemVO) view.getVO(ArriveItemVO.class)); | ||||
|         } | ||||
| 
 | ||||
|         BillComposite<ArriveVO> bc = new BillComposite<ArriveVO>(ArriveVO.class); | ||||
|         ArriveVO tempVO = new ArriveVO(); | ||||
|         bc.append(tempVO.getMetaData().getParent(), | ||||
|                 headers.toArray(new ArriveHeaderVO[headers.size()])); | ||||
|         bc.append(tempVO.getMetaData().getVOMeta(ArriveItemVO.class), | ||||
|                 items.toArray(new ArriveItemVO[items.size()])); | ||||
|         return bc.composite(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 调用后台接口进行检验 | ||||
|      * | ||||
|      * @param vos | ||||
|      *          到货单vo | ||||
|      * @param isCheck | ||||
|      * @return 检验结果数组 | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     private ArriveVO[] check(ArriveVO[] vos, boolean isCheck) throws Exception { | ||||
|         Object[] objs = ServiceLocator.find(IArriveForQC.class).qualityCheck(vos, | ||||
|                 isCheck); | ||||
|         ArriveVO[] result = (ArriveVO[]) objs[0]; | ||||
|         ReturnObjectFor23 rof = (ReturnObjectFor23) objs[1]; | ||||
|         // 得到质检模块的提示信息 | ||||
|         if (rof != null) { | ||||
|             Map<String, Integer> strictMap = rof.getCsourcebid_strictlevel(); | ||||
|             Set<String> keySet = strictMap.keySet(); | ||||
|             IArrivePubQuery arriveQuery = ServiceLocator.find(IArrivePubQuery.class); | ||||
|             ArriveItemVO[] items = arriveQuery | ||||
|                     .queryItemVOByBids(keySet.toArray(new String[keySet.size()])); | ||||
| 
 | ||||
|             String[] bpks = AggVOUtil.getPrimaryKeys(items); | ||||
|             if (strictMap.size() > 0) { | ||||
|                 for (Map.Entry<String, Integer> entry : strictMap.entrySet()) { | ||||
|                     String itempk = entry.getKey(); | ||||
|                     int dji = entry.getValue().intValue(); | ||||
|                     if (StrictLevelEnum.FREE.getReturnType() == dji) { | ||||
|                         int i = Arrays.binarySearch(bpks, itempk); | ||||
|                         items[i].getCrowno(); | ||||
|                         ExceptionUtils.wrapBusinessException( | ||||
|                                 nc.vo.ml.NCLangRes4VoTransl.getNCLangRes() | ||||
|                                         .getStrByID("4004100_0", "04004100-0012")/* @res "第" */ | ||||
|                                         + items[i].getCrowno() | ||||
|                                         + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID( | ||||
|                                         "4004100_0", | ||||
|                                         "04004100-0013")/* | ||||
|                                  * @res "行为质检连续批的严格程度为免检,不需要生成报检单!" | ||||
|                                  */); | ||||
|                     } else if (StrictLevelEnum.PAUSE.getReturnType() == dji) { | ||||
|                         int i = Arrays.binarySearch(bpks, itempk); | ||||
|                         items[i].getCrowno(); | ||||
|                         ExceptionUtils.wrapBusinessException( | ||||
|                                 nc.vo.ml.NCLangRes4VoTransl.getNCLangRes() | ||||
|                                         .getStrByID("4004100_0", "04004100-0012")/* @res "第" */ | ||||
|                                         + items[i].getCrowno() | ||||
|                                         + nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID( | ||||
|                                         "4004100_0", | ||||
|                                         "04004100-0014")/* | ||||
|                                  * @res "行为质检连续批的严格程度为暂停, 不能生成报检单!" | ||||
|                                  */);/* | ||||
|                          * 第 { 0 } 行为质检连续批的严格程度为暂停 , | ||||
|                          * 不能生成报检单 ! | ||||
|                          */ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (!ArrayUtils.isEmpty(result)) { | ||||
|             return result; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,649 @@ | |||
| package nc.impl.pu.m23.qc; | ||||
| 
 | ||||
| import com.alibaba.fastjson.JSONArray; | ||||
| import com.alibaba.fastjson.JSONObject; | ||||
| import nc.bs.dao.BaseDAO; | ||||
| import nc.bs.framework.common.InvocationInfoProxy; | ||||
| import nc.bs.framework.common.NCLocator; | ||||
| import nc.bs.logging.Log; | ||||
| import nc.impl.pu.m23.qc.action.AntiQualityCheckAction; | ||||
| import nc.impl.pu.m23.qc.action.QualityCheckAction; | ||||
| import nc.impl.pubapp.bd.material.assistant.MarAssistantCheckUtils; | ||||
| import nc.impl.pubapp.pattern.data.vo.VOQuery; | ||||
| import nc.impl.pubapp.pattern.data.vo.VOUpdate; | ||||
| import nc.itf.arap.goldentax.SysParaInitQuery; | ||||
| import nc.itf.pu.m23.qc.IArriveForQC; | ||||
| import nc.jdbc.framework.SQLParameter; | ||||
| import nc.jdbc.framework.processor.ColumnProcessor; | ||||
| import nc.jdbc.framework.processor.ResultSetProcessor; | ||||
| import nc.pubitf.uapbd.IMaterialPubService_C; | ||||
| import nc.vo.am.common.util.StringUtils; | ||||
| import nc.vo.bd.material.MaterialVO; | ||||
| import nc.vo.bd.stordoc.StordocVO; | ||||
| import nc.vo.org.OrgQueryUtil; | ||||
| import nc.vo.org.OrgVO; | ||||
| import nc.vo.pu.m23.entity.ArriveHeaderVO; | ||||
| import nc.vo.pu.m23.entity.ArriveItemVO; | ||||
| import nc.vo.pu.m23.entity.ArriveVO; | ||||
| import nc.vo.pub.BusinessException; | ||||
| import nc.vo.pub.lang.UFDouble; | ||||
| import nc.vo.pubapp.pattern.exception.ExceptionUtils; | ||||
| import nc.vo.pubapp.pattern.pub.SqlBuilder; | ||||
| import nc.vo.qc.c001.entity.ApplyHeaderVO; | ||||
| import nc.vo.qc.c001.entity.ApplySourceItemVO; | ||||
| import nc.vo.qc.c001.entity.ApplyVO; | ||||
| import nccloud.api.uapbd.wms.utils.WmsSyncUtils; | ||||
| import nccloud.pubitf.scmpub.pub.service.ISCMPubQueryService; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| /** | ||||
|  * <p> | ||||
|  * <b>本类主要完成以下功能:</b> | ||||
|  * <ul> | ||||
|  * <li>到货单的质检 | ||||
|  * <li>到货单的反检 | ||||
|  * </ul> | ||||
|  * <p> | ||||
|  * <p> | ||||
|  * | ||||
|  * @author hanbin | ||||
|  * @version 6.0 | ||||
|  * @time 2010-9-28 下午01:26:15 | ||||
|  * @since 6.0 | ||||
|  */ | ||||
| public class ArriveForQCImpl implements IArriveForQC { | ||||
|     private static final Log log = Log.getInstance("wmslog"); | ||||
|     private final WmsSyncUtils wmsSyncUtils = new WmsSyncUtils(); | ||||
|     private static final BaseDAO dao = new BaseDAO(); | ||||
| 
 | ||||
|     @Override | ||||
|     public ArriveItemVO[] antiQualityCheck(ArriveItemVO[] bills) throws BusinessException { | ||||
|         try { | ||||
|             AntiQualityCheckAction action = new AntiQualityCheckAction(); | ||||
|             return action.antiQualityCheck(bills); | ||||
|         } catch (Exception ex) { | ||||
|             ExceptionUtils.marsh(ex); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Object[] qualityCheck(ArriveVO[] bills, boolean isCheck) | ||||
|             throws BusinessException { | ||||
|         try { | ||||
|             QualityCheckAction action = new QualityCheckAction(); | ||||
|             return action.qualityCheck(bills, isCheck); | ||||
|         } catch (Exception ex) { | ||||
|             ExceptionUtils.marsh(ex); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public ApplyVO[] pushWmsByArriveVOs(ArriveVO[] bills) throws Exception { | ||||
|         //检查到货单组织是否全是成套 | ||||
|         log.error("到货单检验推送wms--检查组织是否为WMSORG里参数开始"); | ||||
|         boolean isWmsCt = checkOrgBeyondSysParam(bills); | ||||
|         log.error("到货单检验推送wms--检查组织是否为WMSORG里参数结束"); | ||||
|         if(!isWmsCt){ | ||||
|             log.error("到货单检验推送wms--检查组织不为WMSORG里参数,结束推送"); | ||||
|             return null; | ||||
|         } | ||||
|         String wmsBJPKS = InvocationInfoProxy.getInstance().getProperty("wmsBJPKS"); | ||||
|         if (wmsBJPKS == null || wmsBJPKS.length() < 1) { | ||||
|             throw new BusinessException("发送WMS数据未查询到报检单pk或已存在下游报检单,请检查!!!"); | ||||
|         } | ||||
|         log.error("到货单检验推送wms--到货单推送生成报检单主键字符串【"+wmsBJPKS+"】"); | ||||
|         String[] pks = wmsBJPKS.split("_"); | ||||
|         if (pks == null || pks.length < 1) { | ||||
|             throw new BusinessException("解析报检单pk失败,请检查!!!"); | ||||
|         } | ||||
|         //根据表头主键查询报检单 | ||||
|         ApplyVO[] applyVOs = (ApplyVO[]) ((ISCMPubQueryService) NCLocator.getInstance().lookup(ISCMPubQueryService.class)).billquery(ApplyVO.class, pks); | ||||
|         this.pushWms(applyVOs); | ||||
|         InvocationInfoProxy.getInstance().setProperty("wmsBJPKS", null); | ||||
|         return applyVOs; | ||||
|     } | ||||
| 
 | ||||
|     private boolean checkOrgBeyondSysParam(ArriveVO[] bills) throws BusinessException { | ||||
|         String targetCode = SysParaInitQuery.getParaString("GLOBLE00000000000000", "WMSORG"); | ||||
|         if (targetCode == null || StringUtils.isEmpty(targetCode)) { | ||||
|             throw new BusinessException("未配置组织参数,请前往 [业务参数设置-全局] 配置WMSORG 参数"); | ||||
|         } | ||||
|         String[] orgItem = targetCode.split(";"); | ||||
|         if(orgItem==null || orgItem.length<1){ | ||||
|             throw new BusinessException("WMSORG全局参数解析失败,请检查"); | ||||
|         } | ||||
|         //使用Stream将orgItem转成list | ||||
|         List<String> orgList = Arrays.asList(orgItem); | ||||
|         Set<String> orgPKs=new HashSet<>(); | ||||
|         for(ArriveVO arriveVO: bills){ | ||||
|             String pkOrg = arriveVO.getHVO().getPk_org(); | ||||
|             orgPKs.add(pkOrg); | ||||
|         } | ||||
|         OrgVO[] orgVOS = OrgQueryUtil.queryOrgVOByPks(orgPKs.toArray(new String[0])); | ||||
|         if(orgVOS==null || orgVOS.length<1){ | ||||
|             throw new BusinessException("未查询到组织信息,请检查"); | ||||
|         } | ||||
|         boolean containCT=false; | ||||
|         boolean containOther=false; | ||||
|         for(OrgVO orgVO:orgVOS){ | ||||
|             if(orgList.contains(orgVO.getCode())){ | ||||
|                 containCT=true; | ||||
|             }else{ | ||||
|                 containOther=true; | ||||
|             } | ||||
|         } | ||||
|         if(containCT && containOther){ | ||||
|             throw new BusinessException("存在非【"+targetCode+"】组织数据与其一起检验,请检查"); | ||||
|         } | ||||
|         return containCT; | ||||
|     } | ||||
| 
 | ||||
|     private void pushWms(ApplyVO[] applyVOs) throws BusinessException { | ||||
|         try { | ||||
|             JSONObject wmsData = new JSONObject(); | ||||
|             // 构造表头数据 | ||||
|             JSONArray jsonArray = new JSONArray(); | ||||
|             //2025年10月17日09点19分--过滤虚拟仓 | ||||
|             List<ApplyVO> filterData = new ArrayList<>(); | ||||
|             for (ApplyVO applyVO : applyVOs) { | ||||
|                 this.checkInfo(applyVO); | ||||
|                 ApplyHeaderVO headVO = applyVO.getHVO(); | ||||
|                 String vbillcode = headVO.getVbillcode(); | ||||
|                 // 检查是否为虚拟仓 | ||||
|                 String isVirtual = wmsSyncUtils.transferFieldByPkAllowNull(StordocVO.getDefaultTableName(), | ||||
|                         "def1", StordocVO.PK_STORDOC, | ||||
|                         headVO.getPk_stordoc()); | ||||
|                 if ("Y".equals(isVirtual)) { | ||||
|                     log.error("ArriveForQCImpl -到货单检验,生成的报检单【"+vbillcode+"】 仓库[" + headVO.getPk_stordoc() + "]为虚拟仓,跳过同步"); | ||||
|                     continue; | ||||
|                 } | ||||
|                 filterData.add(applyVO); | ||||
|                 //2025年10月17日09点19分--过滤虚拟仓 | ||||
|             } | ||||
|             if(filterData.isEmpty()){ | ||||
|                 log.error("ArriveForQCImpl -到货单检验,筛选完之后无可同步报检单,结束WMS同步"); | ||||
|                 return; | ||||
|             } | ||||
|             ApplyVO[] syncApplyVOs=filterData.toArray(new ApplyVO[0]); | ||||
|             this.constructWMSData(jsonArray, syncApplyVOs); | ||||
|             if (jsonArray == null || jsonArray.isEmpty()) { | ||||
|                 throw new BusinessException("当前报检单号同步数据为空,不同步WMS"); | ||||
|             } | ||||
|             wmsData.put("header", jsonArray); | ||||
|             String method = "TK_BIP_QC_ORDER"; | ||||
|             //同步前更新上游和本单--失败回滚,成功落库 | ||||
|             log.error("回写报检单Vdef3开始--接口失败回滚,接口成功落库"); | ||||
|             // 标记同步成功 | ||||
|             List<ApplyHeaderVO> headvos = new ArrayList<>(); | ||||
|             for (ApplyVO applyVO : syncApplyVOs) { | ||||
|                 applyVO.getHVO().setVdef3("Y"); | ||||
|                 applyVO.getHVO().setStatus(1); | ||||
|                 headvos.add(applyVO.getHVO()); | ||||
|             } | ||||
|             VOUpdate<ApplyHeaderVO> applyVOUpdater = new VOUpdate<>(); | ||||
|             applyVOUpdater.update(headvos.toArray(new ApplyHeaderVO[0]), new String[]{"vdef3"}); | ||||
|             log.error("回写报检单Vdef结束--接口失败回滚,接口成功落库"); | ||||
|             // 回写上游到货单成功 | ||||
|             handleUpstreamArriveOrderSuccess(syncApplyVOs); | ||||
|             // 后规则最后一个 更新 | ||||
| 
 | ||||
|             log.error("开始同步报检单到WMS"); | ||||
| //            log.error("同步报文【" + wmsData.toJSONString() + "】"); | ||||
|             wmsSyncUtils.sendToExternalSystem(method, wmsData); | ||||
|             log.error("报检单同步WMS成功"); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             log.error("检验结束,同步WMS失败" + e.getMessage()); | ||||
|             throw new BusinessException("同步WMS失败" + e.getMessage()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void constructWMSData(JSONArray jsonArray, ApplyVO[] applyVOs) throws Exception { | ||||
|         //获取时间戳 | ||||
|         long timestamp = System.currentTimeMillis(); | ||||
|         for (ApplyVO applyVO : applyVOs) { | ||||
|             ApplyHeaderVO headVO = applyVO.getHVO(); | ||||
|             String vbillcode = headVO.getVbillcode(); | ||||
|             log.error("到货单检验推送wms--到货单推送生成报检单单号【"+vbillcode+"】"); | ||||
|             ApplySourceItemVO[] itemVOs = applyVO.getB2VO(); | ||||
| 
 | ||||
|             ApplySourceItemVO itemExampleVO = itemVOs[0]; | ||||
| 
 | ||||
|             JSONObject headData = new JSONObject(); | ||||
| //                Map<String, Object> headData = new HashMap<>(); | ||||
|             // 构建仓库ID: "CK" + 组织编码 + "001" | ||||
|             String orgCode = wmsSyncUtils.transferCodeByPk("org_stockorg", "code", "pk_stockorg", | ||||
|                     headVO.getPk_stockorg()); | ||||
|             String warehouseId = "CK" + (orgCode != null ? orgCode : "") + "001"; | ||||
|             headData.put("organizationId", "TK"); // 组织 默认TK | ||||
|             headData.put("warehouseId", warehouseId); // 仓库ID(必填) | ||||
| //            headData.put("customerId", "TKJT"); // 货主(必填,默认值) | ||||
|             //2025年9月3日10点37分--货主改为和仓库编码一致 --sdlizheng start | ||||
|             headData.put("customerId", warehouseId); | ||||
|             //2025年9月3日10点37分--货主改为和仓库编码一致 --sdlizheng end | ||||
| 
 | ||||
|             // 根据表体源头单据类型编码确定订单类型 | ||||
|             String asnType = getAsnTypeByFirstTypeCode(itemVOs); | ||||
|             if (asnType == null) { | ||||
|                 throw new BusinessException("报检单号【" + vbillcode + "】 - 未知的源头单据类型编码,不同步此报检单"); | ||||
|             } | ||||
|             headData.put("asnType", asnType); // 订单类型(必填,根据源头单据类型编码确定) | ||||
|             headData.put("QCNO", headVO.getVbillcode()); // 质检单号(必填) | ||||
| 
 | ||||
|             //2025年9月2日09点01分--表头添加到货日期--sdlizheng start | ||||
|             headData.put("BIP_TIME", headVO.getDapplydate().toString()); | ||||
|             //2025年9月2日09点01分--表头添加到货日期--sdlizheng end | ||||
|             headData.put("MSG_BATCH", String.valueOf( timestamp)); | ||||
|             headData.put("QCSTATUS", "00"); // 质检单状态(必填,默认00) | ||||
|             // 到货单号取来源单据号 | ||||
|             headData.put("SOURCEORDERNO1", itemExampleVO.getVsourcecode() != null ? itemExampleVO.getVsourcecode() : ""); // 到货单号(必填) | ||||
|             headData.put("qty_rejected", headVO.getNnum() != null ? headVO.getNnum().toString() : ""); // 报检数量(必填) | ||||
|             headData.put("supplierId", wmsSyncUtils.transferCodeByPk("bd_supplier", "code", "pk_supplier", headVO.getPk_supplier())); | ||||
|             headData.put("DEPARTMENT", | ||||
|                     wmsSyncUtils.transferCodeByPk("org_dept", "code", "pk_dept", headVO.getPk_applydept())); // 报检部门(必填) | ||||
|             headData.put("hedi02", headVO.getPk_applybill() != null ? headVO.getPk_applybill() : ""); // 报检单主键(必填) | ||||
|             headData.put("hedi03", headVO.getPk_stordoc() != null ? headVO.getPk_stordoc() : ""); // 仓库回传主键 | ||||
|             headData.put("hedi05", itemExampleVO.getCsourceid()); | ||||
|             headData.put("hedi06", itemExampleVO.getCsourcetypecode()); | ||||
|             headData.put("hedi07", wmsSyncUtils.transferFieldByPkAllowNull("sm_user", "user_name", "cuserid", headVO.getBillmaker())); | ||||
| 
 | ||||
|             headData.put("hedi08", wmsSyncUtils.transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.NAME, StordocVO.PK_STORDOC, headVO.getPk_stordoc())); | ||||
| 
 | ||||
|             //2025年9月7日16点26分--增加检验方案字段--sdlizheng start | ||||
| //            WMS报检单下发WMS新增两个字段:pk_defaultstd,pk_defaultstd_v   WMS回传质检报告时:hedi11,hedi12,分别对应pk_chkstd,pk_chkstd_v | ||||
|             headData.put("hedi11", wmsSyncUtils.transferCodeByPk("qc_checkstandard", "vchkstandardcode", "pk_checkstandard", headVO.getPk_defaultstd())); | ||||
|             headData.put("hedi12", wmsSyncUtils.transferCodeByPk("qc_checkstandard_v", "vchkstandardcode", "pk_checkstandard", headVO.getPk_defaultstd_v())); | ||||
|             //2025年9月7日16点26分--增加检验方案字段--sdlizheng end | ||||
| 
 | ||||
|             // 构造表体数据(遍历itemVOs表体VO数组) | ||||
| //                List<Map<String, Object>> bodyDataList = new ArrayList<>(); | ||||
|             JSONArray bodyDataList = new JSONArray(); | ||||
|             String old_manufacturer = null, old_cprojectid = null, old_productionDept = null, old_vbatchcode = null; | ||||
| 
 | ||||
| //            for (ApplySourceItemVO itemVO : itemVOs) { | ||||
| 
 | ||||
|             // 查询一下上游的到货单明细,然后拿到生产厂商和部门 | ||||
|             VOQuery<ArriveItemVO> voQuery = new VOQuery<>(ArriveItemVO.class); | ||||
|             ArriveItemVO[] arriveItemVO = voQuery.query(new String[]{itemVOs[0].getCsourcebid()}); | ||||
|             if (arriveItemVO != null && arriveItemVO.length > 0) { | ||||
|                 ArriveItemVO arriveItem = arriveItemVO[0]; | ||||
|                 old_vbatchcode = arriveItem.getVbatchcode(); | ||||
|                 old_manufacturer = arriveItem.getCproductorid(); | ||||
|                 old_cprojectid = arriveItem.getCprojectid(); | ||||
|                 old_productionDept = arriveItem.getVfree1(); | ||||
|             }else{ | ||||
|                throw new BusinessException("到货单检验推送wms--根据报检单来源子表id【"+itemVOs[0].getCsourcebid()+"】未查询到到货单明细,请检查"); | ||||
|             } | ||||
|             // 校验物料属性--2025年9月2日09点50分 变更--如果启用校验报错--不启用则先留存数据,清空vo数据,后续赋值数据  sdlizheng start | ||||
| //                wmsSyncUtils.checkMaterialBatchCode(itemVOs[0].getPk_material(), itemVOs[0].getVbatchcode(), orgCode); | ||||
|             this.checkMaterialInfo(itemVOs[0], headVO.getPk_stockorg(), arriveItemVO[0]); | ||||
| //                wmsSyncUtils.checkMaterialFreeAssistantProps(itemVOs[0].getPk_material(), orgCode, manufacturer, cprojectid, productionDept); | ||||
|             // 校验物料属性--2025年9月2日09点50分 变更--如果启用校验报错--不启用则先留存数据,清空vo数据,后续赋值数据  sdlizheng end | ||||
| 
 | ||||
| //            	} | ||||
| //                Map<String, Object> bodyData = new HashMap<>(); | ||||
|             JSONObject bodyData = new JSONObject(); | ||||
|             //2025年10月10日11点29分--增加到货单字段推送wms-start | ||||
| //            一、到货单表体自定义项28货位编码发送给WMS的WGKWBH字段(传编码)。 | ||||
| //            二、到货单表体自定义项29产品编码发送给WMS的CCPBH字段(传编码)。 | ||||
| //            三、到货单表体自定义项30流程生产订单号发送给WMS的LCSCDDH字段(传编码)。 | ||||
| //            四、到货单表体生产日期dproducedate字段发送给WMS的JHKGSJ字段(传日期)。 | ||||
| //            五、到货单表体备注字段vmemob字段发送给WMS的BOMBZ字段(传字符串)。 | ||||
| //            六、到货单表头的采购部门pk_dept字段发送给WMS的CGBM字段(传编码)。 | ||||
| //            七、到货单表头的采购员pk_pupsndoc字段发给WMS的CGY字段(传编码)。 | ||||
|             VOQuery<ArriveHeaderVO> headQueryVO = new VOQuery<>(ArriveHeaderVO.class); | ||||
|             ArriveHeaderVO[] arriveVOs = headQueryVO.query(new String[]{itemVOs[0].getCsourceid()}); | ||||
|             if(arriveVOs==null || arriveVOs.length==0){ | ||||
|                 throw new BusinessException("到货单检验推送wms--根据报检单来源子表id【"+itemVOs[0].getCsourceid()+"】未查询到到货单明细,请检查"); | ||||
|             } | ||||
|             String vbdef28 = arriveItemVO[0].getVbdef28(); | ||||
|             bodyData.put("WGKWBH",vbdef28); | ||||
|             String vbdef29 = arriveItemVO[0].getVbdef29(); | ||||
|             bodyData.put("CCPBH",vbdef29); | ||||
|             String vbdef30 = arriveItemVO[0].getVbdef30(); | ||||
|             bodyData.put("LCSCDDH",vbdef30); | ||||
|             String dproducedate= arriveItemVO[0].getDproducedate() != null ? arriveItemVO[0].getDproducedate().toStdString() : null; | ||||
|             bodyData.put("JHKGSJ", dproducedate); | ||||
|             bodyData.put("BOMBZ", arriveItemVO[0].getVmemob()); | ||||
|             String pkDept = arriveVOs[0].getPk_dept(); | ||||
|             headData.put("CGBM", wmsSyncUtils.transferCodeByPk("org_dept", "code", "pk_dept", pkDept)); | ||||
|             String pkPupsndoc = arriveVOs[0].getPk_pupsndoc(); | ||||
|             headData.put("CGY", wmsSyncUtils.transferCodeByPk("bd_psndoc", "code", "pk_psndoc", pkPupsndoc)); | ||||
|             //2025年10月10日11点29分--增加到货单字段推送wms-end | ||||
|             //2025年10月17日13点41分--增加数量字段推送wms-start | ||||
|             UFDouble nastnum = arriveItemVO[0].getNastnum()==null?UFDouble.ZERO_DBL:arriveItemVO[0].getNastnum(); | ||||
|             bodyData.put("DEDI09", nastnum.toString()); | ||||
|             //2025年10月21日10点54分--添加到货字段DEDI10-start | ||||
|             bodyData.put("DEDI10", nastnum.toString()); | ||||
|             //2025年10月21日10点54分--添加到货字段DEDI10-end | ||||
|             bodyData.put("DEDI05", wmsSyncUtils.transferCodeByPk("bd_measdoc", "code", "pk_measdoc", arriveItemVO[0].getCastunitid())); | ||||
|             //2025年10月17日13点41分--增加字段推送wms-start | ||||
| 
 | ||||
|             // 检验项目明细表体使用表头物料信息(因为itemVO是检验项目明细,不是物料明细) | ||||
|             bodyData.put("sku", wmsSyncUtils.transferCodeByPk("bd_material", "code", "pk_material", | ||||
|                     headVO.getPk_material())); // 产品(必填)- 使用表头物料 | ||||
|             bodyData.put("skuDescr1", wmsSyncUtils.transferFieldByPkAllowNull("bd_material", "materialshortname", "pk_material", headVO.getPk_material())); // 产品描述(必填)- 使用表头物料 | ||||
| 
 | ||||
|             //2025年10月17日13点50分--改取nnum | ||||
| //            bodyData.put("QTY_REJECTED", headVO.getNastnum() != null ? headVO.getNastnum().toString() : ""); // 报检数量(必填)- | ||||
|             bodyData.put("QTY_REJECTED", headVO.getNnum() != null ? headVO.getNnum().toString() : ""); | ||||
| 
 | ||||
|             // 使用表头数量 | ||||
|             bodyData.put("qcQty_Completed", headVO.getNnum() != null ? headVO.getNnum().doubleValue() : ""); // 质检数量(可选) | ||||
|             bodyData.put("LOTATT01", | ||||
|                     headVO.getDproducedate() != null ? headVO.getDproducedate().toString() : ""); // 生产日期(必填)- | ||||
|             bodyData.put("LOTATT04", headVO.getVbatchcode() != null ? headVO.getVbatchcode() : ""); // ERP批次号(必填)- | ||||
|             // 使用表头批次号 | ||||
|             bodyData.put("LOTATT05", wmsSyncUtils.transferCodeByPk("bd_stordoc", "code", "pk_stordoc", | ||||
|                     headVO.getPk_stordoc())); // ERP仓库(必填)- 使用表头仓库 | ||||
|             bodyData.put("LOTATT06", wmsSyncUtils.transferCodeByPk("bd_supplier", "code", "pk_supplier", | ||||
|                     headVO.getPk_supplier())); // 供应商(必填)- 使用表头供应商 | ||||
|             // 从上游抽出生产厂商字段 | ||||
|             bodyData.put("LOTATT07", wmsSyncUtils.transferFieldByPkAllowNull("bd_defdoc", "code", "pk_defdoc", arriveItemVO[0].getCproductorid())); | ||||
|             bodyData.put("LOTATT08", "DJ"); | ||||
|             // 项目号(必填)- 使用表头项目 | ||||
|             bodyData.put("LOTATT09", wmsSyncUtils.transferCodeByPk("bd_project", "project_code", "pk_project", arriveItemVO[0].getCprojectid())); | ||||
|             // 检验项目明细相关字段 | ||||
|             bodyData.put("DEDI01", itemVOs[0].getCsourcebid()); | ||||
|             bodyData.put("DEDI02", headVO.getCtrantypeid()); // 检验项目名称(可选) | ||||
|             bodyData.put("DEDI03", wmsSyncUtils.transferFieldByPkAllowNull("bd_supplier", "name", "pk_supplier", headVO.getPk_supplier())); // 供应商名称 | ||||
| //            bodyData.put("DEDI04", wmsSyncUtils.transferFieldByPkAllowNull("bd_stordoc", "name", "pk_stordoc", headVO.getPk_stordoc())); // ERP仓库名称 | ||||
|            //2025年9月28日19点24分--换报检明细主键 | ||||
|             bodyData.put("DEDI04", itemVOs[0].getPk_applybill_s()); | ||||
|             // 采购部门(可选)- 使用表头采购部门 | ||||
|             bodyData.put("PURCHASE_DEPARMENT", wmsSyncUtils.transferCodeByPk("org_dept", "code", "pk_dept", arriveItemVO[0].getVfree1())); | ||||
|             // 采购员(可选)- 使用表头采购员 | ||||
|             bodyData.put("PURCHASE_CGY", wmsSyncUtils.transferCodeByPk("bd_psndoc", "code", "pk_psndoc", headVO.getPk_pupsndoc())); | ||||
|             // 单位(可选)- 使用表头单位 | ||||
|             bodyData.put("UNIT", wmsSyncUtils.transferCodeByPk("bd_measdoc", "code", "pk_measdoc", headVO.getCastunitid())); | ||||
| //            bodyData.put("addWho", headVO.getCreator() != null ? headVO.getCreator() : ""); // 新增人员(可选)- 使用表头创建人 | ||||
|             String s = wmsSyncUtils.transferCodeByPk("sm_user", "user_code", "cuserid", headVO.getCreator()); | ||||
|             //将s转大写 | ||||
|             bodyData.put("addWhos",s==null?"" : s.toUpperCase() ); // 新增人员(可选)- 使用表头创建人 | ||||
|             headData.put("addWhos",s==null?"" : s.toUpperCase() ); // 新增人员(可选)- 使用表头创建人 | ||||
| 
 | ||||
|             bodyData.put("addTime", headVO.getCreationtime() != null ? headVO.getCreationtime().toString() : ""); // 新增时间(可选)- 使用表头创建时间 | ||||
| //            bodyData.put("editWho", headVO.getModifier() != null ? headVO.getModifier() : ""); // 编辑人(可选)- 使用表头修改人 | ||||
|             bodyData.put("editWho", wmsSyncUtils.transferCodeByPk("sm_user","user_code","pk_user", headVO.getModifier())); // 新增人员(可选)- 使用表头创建人 | ||||
|             bodyData.put("editTime", headVO.getModifiedtime() != null ? headVO.getModifiedtime().toString() : ""); // 编辑时间(可选)- 使用表头修改时间 | ||||
| 
 | ||||
|             bodyDataList.add(bodyData); | ||||
| 
 | ||||
|             arriveItemVO[0].setVfree1(old_productionDept); | ||||
|             arriveItemVO[0].setVbatchcode(old_vbatchcode); | ||||
|             arriveItemVO[0].setCproductorid(old_manufacturer); | ||||
|             arriveItemVO[0].setCprojectid(old_cprojectid); | ||||
|             // 组装最终数据结构 | ||||
|             headData.put("details", bodyDataList); | ||||
|             jsonArray.add(headData); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void checkInfo(ApplyVO applyVO) throws BusinessException { | ||||
|         ApplyHeaderVO headVO = applyVO.getHVO(); | ||||
|         ApplySourceItemVO[] itemVOs = applyVO.getB2VO(); | ||||
|         if (headVO == null) { | ||||
|             throw new BusinessException("报检单表头或明细为空,无法构造WMS数据"); | ||||
|         } | ||||
| 
 | ||||
|         String vbillcode = headVO.getVbillcode(); | ||||
|         if (itemVOs == null || itemVOs.length == 0) { | ||||
|             throw new BusinessException("报检单报检单【" + vbillcode + "】明细为空,无法构造WMS数据"); | ||||
|         } | ||||
|         String orgCode = null; | ||||
|         try { | ||||
|             orgCode = wmsSyncUtils.transferCodeByPk("org_stockorg", "code", "pk_stockorg", headVO.getPk_stockorg()); | ||||
|         } catch (Exception e) { | ||||
|             throw new BusinessException("报检单【" + vbillcode + "】, 查询组织编码失败" + e.getMessage()); | ||||
|         } | ||||
|         if (orgCode == null || StringUtils.isEmpty(orgCode)) { | ||||
|             throw new BusinessException("报检单【" + vbillcode + "】, 未获取到组织编码"); | ||||
|         } | ||||
|         if (!wmsSyncUtils.checkIfIncludeOrg(orgCode)) { | ||||
|             throw new BusinessException("报检单【" + vbillcode + "】, 不在WMS同步范围内"); | ||||
|         } | ||||
|         if ("Y".equalsIgnoreCase(headVO.getVdef3())) { | ||||
|             throw new BusinessException("报检单【" + vbillcode + "】, 已同步成功,无法再次同步"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 回写上游到货单明细的自定义项2成功 | ||||
|      */ | ||||
|     private void handleUpstreamArriveOrderSuccess(ApplyVO[] applyVOs) throws BusinessException { | ||||
|         //获取所有明细信息 | ||||
|         log.error("回写到货单Vbdef22和Vmemob开始--接口失败回滚,接口成功落库"); | ||||
|         Set<String> arriveItemIds = new HashSet<>(); | ||||
|         for (ApplyVO applyVO : applyVOs) { | ||||
|             String vbillcode = applyVO.getHVO().getVbillcode(); | ||||
|             ApplySourceItemVO[] b2VOs = applyVO.getB2VO(); | ||||
|             if (b2VOs == null || b2VOs.length < 1) { | ||||
|                 throw new BusinessException("发送wms前回写上游到货单失败,明细行为空"); | ||||
|             } | ||||
|             for (ApplySourceItemVO itemVO : b2VOs) { | ||||
|                 String csourcebid = itemVO.getCsourcebid(); | ||||
|                 if (StringUtils.isEmpty(csourcebid)) { | ||||
|                     throw new BusinessException("发送wms前回写上游到货单失败,明细行[Csourcebid]字段为空"); | ||||
|                 } | ||||
|                 arriveItemIds.add(csourcebid); | ||||
|             } | ||||
|         } | ||||
|         VOQuery<ArriveItemVO> voQuery = new VOQuery<>(ArriveItemVO.class); | ||||
|         ArriveItemVO[] arriveItems = voQuery.query(arriveItemIds.toArray(new String[0])); | ||||
| 
 | ||||
|         if (arriveItems == null || arriveItems.length < 1) { | ||||
|             throw new BusinessException("发送wms前回写上游到货单失败,未查询到上游到货单明细信息"); | ||||
|         } | ||||
|         //检查回写的到货单是否为质检的 | ||||
|         for (ArriveItemVO arriveItem : arriveItems) { | ||||
|             String vbdef50 = arriveItem.getVbdef50(); | ||||
|             String pkOrderB = arriveItem.getPk_order_b(); | ||||
|             if(!"Y".equals(vbdef50)){ | ||||
|                 throw new BusinessException("请检查,存在到货单明细为免检,生成报检单,到货单明细【"+pkOrderB+"】"); | ||||
|             } | ||||
|             arriveItem.setVbdef22("Y"); // 标记同步成功 | ||||
|             arriveItem.setVmemob("发送WMS成功"); // 记录失败原因 | ||||
|             arriveItem.setStatus(1); | ||||
|         } | ||||
|         new VOUpdate<ArriveItemVO>().update(arriveItems, new String[]{"vbdef22", "vmemob"}); | ||||
|         log.error("回写到货单Vbdef22和Vmemob结束--接口失败回滚,接口成功落库"); | ||||
|     } | ||||
| 
 | ||||
|     private void checkMaterialInfo(ApplySourceItemVO itemVO, String orgCode, ArriveItemVO arriveItemVO) throws BusinessException { | ||||
|         String materialPk = itemVO.getPk_material(); | ||||
|         String vbatchcode = arriveItemVO.getVbatchcode(); | ||||
|         String manufacturer = arriveItemVO.getCproductorid(); | ||||
|         String projectNo = arriveItemVO.getCprojectid(); | ||||
|         String productionDept = arriveItemVO.getVfree1(); | ||||
|         if (materialPk == null || materialPk.trim().isEmpty()) { | ||||
|             log.error("物料主键为空,无法检查自由辅助属性"); | ||||
|             throw new BusinessException("物料主键为空"); | ||||
|         } | ||||
| 
 | ||||
|         if (orgCode == null || orgCode.trim().isEmpty()) { | ||||
|             log.error("组织主键为空,无法检查自由辅助属性"); | ||||
|             throw new BusinessException("组织主键为空"); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             // 查询物料库存信息中的自由辅助属性 | ||||
|             String sql = "SELECT fixasst2, fixasst4, freeasst1,wholemanaflag  " + | ||||
|                     "FROM bd_materialstock " + | ||||
|                     "WHERE pk_material = ? AND pk_org = ?"; | ||||
| 
 | ||||
|             SQLParameter sqlParameter = new SQLParameter(); | ||||
|             sqlParameter.addParam(materialPk); | ||||
|             sqlParameter.addParam(orgCode); | ||||
| 
 | ||||
|             Object result = dao.executeQuery(sql, sqlParameter, (ResultSetProcessor) rs -> { | ||||
|                 if (rs.next()) { | ||||
|                     Map<String, String> row = new HashMap<>(); | ||||
|                     row.put("fixasst2", rs.getString("fixasst2")); // 对应项目号 | ||||
|                     row.put("fixasst4", rs.getString("fixasst4")); // 对应生产厂商 | ||||
|                     row.put("freeasst1", rs.getString("freeasst1")); // 对应生产部门 | ||||
|                     row.put("wholemanaflag", rs.getString("wholemanaflag")); // 批次管理标识 | ||||
|                     return row; | ||||
|                 } | ||||
|                 return null; | ||||
|             }); | ||||
| 
 | ||||
|             if (result == null) { | ||||
|                 log.error("未查询到物料库存信息,物料主键:" + materialPk + ",组织主键:" + orgCode); | ||||
|                 throw new BusinessException("未查询到物料库存信息,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|             } | ||||
| 
 | ||||
|             @SuppressWarnings("unchecked") | ||||
|             Map<String, String> materialStockInfo = (Map<String, String>) result; | ||||
| 
 | ||||
|             log.debug("查询到物料库存信息,物料主键:" + materialPk + ",组织主键:" + orgCode + | ||||
|                     ",自由辅助属性配置:" + materialStockInfo); | ||||
|             // 如果物料启用了批次管理 | ||||
|             String batchManageFlag = materialStockInfo.get("wholemanaflag"); | ||||
|             if ("Y".equals(batchManageFlag)) { | ||||
|                 if (vbatchcode == null || vbatchcode.trim().isEmpty()) { | ||||
|                     log.error("物料启用了批次管理,但批次号为空,物料主键:" + materialPk); | ||||
|                     throw new BusinessException("物料启用了批次管理,但批次号为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("物料启用了批次管理且批次号不为空,检查通过,物料主键:" + materialPk + ",批次号:" + vbatchcode); | ||||
|             } else { | ||||
|                 if (vbatchcode != null && !vbatchcode.trim().isEmpty()) { | ||||
|                     log.error("物料没有启用批次管理,但批次号不为空,物料主键:" + materialPk); | ||||
|                     arriveItemVO.setVbatchcode(null); | ||||
| //                    throw new BusinessException("物料没有启用批次管理,但批次号不为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 // 不需要批次管理的物料,直接返回true | ||||
|                 log.debug("物料未启用批次管理,检查通过,物料主键:" + materialPk); | ||||
|             } | ||||
|             // 检查项目号(对应fixasst2) | ||||
|             String projectFlag = materialStockInfo.get("fixasst2"); | ||||
|             if ("Y".equals(projectFlag)) { | ||||
|                 if (projectNo == null || projectNo.trim().isEmpty()) { | ||||
|                     log.error("物料启用了项目号属性,但项目号为空,物料主键:" + materialPk); | ||||
|                     throw new BusinessException("物料启用了项目号属性,但项目号为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("项目号属性校验通过,物料主键:" + materialPk + ",项目号:" + projectNo); | ||||
|             } else { | ||||
|                 if (projectNo != null && !projectNo.trim().isEmpty()) { | ||||
|                     log.error("物料未启用项目号属性,但项目号不为空,物料主键:" + materialPk); | ||||
|                     arriveItemVO.setCprojectid(null); | ||||
| //                    throw new BusinessException("物料未启用项目号属性,但项目号不为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("物料未启用项目号属性,跳过校验,物料主键:" + materialPk); | ||||
|             } | ||||
| 
 | ||||
|             // 检查生产厂商(对应fixasst4) | ||||
|             String manufacturerFlag = materialStockInfo.get("fixasst4"); | ||||
|             if ("Y".equals(manufacturerFlag)) { | ||||
|                 if (manufacturer == null || manufacturer.trim().isEmpty()) { | ||||
|                     log.error("物料启用了生产厂商属性,生产厂商不能为空,物料主键:" + materialPk); | ||||
|                     throw new BusinessException("物料启用了生产厂商属性,生产厂商不能为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("生产厂商属性校验通过,物料主键:" + materialPk + ",生产厂商:" + manufacturer); | ||||
|             } else { | ||||
|                 if (manufacturer != null && !manufacturer.trim().isEmpty()) { | ||||
|                     log.error("物料未启用生产厂商属性,生产厂商应为空,物料主键:" + materialPk); | ||||
|                     arriveItemVO.setCproductorid(null); | ||||
| //                    throw new BusinessException("物料未启用生产厂商属性,生产厂商应为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("物料未启用生产厂商属性,跳过校验,物料主键:" + materialPk); | ||||
|             } | ||||
| 
 | ||||
|             //2025年8月28日15点32分--生产部门按照物料基本信息页签控制 --start | ||||
|             IMaterialPubService_C marService = NCLocator.getInstance().lookup(IMaterialPubService_C.class); | ||||
|             Map<String, MaterialVO> materialMap = marService.queryMaterialBaseInfoByPks(new String[]{materialPk}, | ||||
|                     new String[]{MaterialVO.PK_MARASSTFRAME, MaterialVO.NAME, MaterialVO.NAME2, MaterialVO.NAME3, | ||||
|                             MaterialVO.NAME4, MaterialVO.NAME5, MaterialVO.NAME6}); | ||||
|             Set<String> marFramePkSet = new HashSet<String>(); | ||||
|             for (Map.Entry<String, MaterialVO> entry : materialMap.entrySet()) { | ||||
|                 String pk_marasstframe = entry.getValue().getPk_marasstframe(); | ||||
|                 if (pk_marasstframe != null) { | ||||
|                     marFramePkSet.add(pk_marasstframe); | ||||
|                 } | ||||
|             } | ||||
|             Map<String, List<Integer>> marFrameMap = MarAssistantCheckUtils | ||||
|                     .queryMarAsstFrameIncludeDefPropIndex(marFramePkSet.toArray(new String[0])); | ||||
|             if (marFrameMap == null || marFrameMap.size() < 1) { | ||||
|                 if (productionDept != null && !productionDept.trim().isEmpty()) { | ||||
|                     log.error("物料基础信息页签未启用生产部门属性,但生产部门不为空,物料主键:" + materialPk); | ||||
|                     arriveItemVO.setVfree1(null); | ||||
| //                    throw new BusinessException("物料基础信息页签未启用生产部门属性,但生产部门不为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                 } | ||||
|                 log.debug("物料基础信息页签未启用生产部门属性,跳过校验,物料主键:" + materialPk); | ||||
|             } else { | ||||
|                 String pkMarasstframe = materialMap.get(materialPk).getPk_marasstframe(); | ||||
|                 List<Integer> integers = marFrameMap.get(pkMarasstframe); | ||||
|                 if (integers.contains(6)) { | ||||
|                     //启用生产部门 | ||||
|                     if (productionDept == null || productionDept.trim().isEmpty()) { | ||||
|                         log.error("物料基础信息页签启用了生产部门属性,但生产部门为空,物料主键:" + materialPk); | ||||
|                         throw new BusinessException("物料基础信息页签启用了生产部门属性,但生产部门为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                     } | ||||
|                     log.debug("生产部门属性校验通过,物料主键:" + materialPk + ",生产部门:" + productionDept); | ||||
|                 } else { | ||||
|                     if (productionDept != null && !productionDept.trim().isEmpty()) { | ||||
|                         log.error("物料基础信息页签未启用生产部门属性,但生产部门不为空,物料主键:" + materialPk); | ||||
|                         arriveItemVO.setVfree1(null); | ||||
| //                        throw new BusinessException("物料基础信息页签未启用生产部门属性,但生产部门不为空,物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             //2025年8月28日15点32分--生产部门按照物料基本信息页签控制 --end | ||||
| 
 | ||||
|         } catch (BusinessException e) { | ||||
|             throw e; | ||||
|         } catch (Exception e) { | ||||
|             log.error("检查物料自由辅助属性失败:" + e.getMessage() + ",物料主键:" + materialPk + ",组织主键:" + orgCode, e); | ||||
|             throw new BusinessException("检查物料自由辅助属性失败:" + e.getMessage() + ",物料编码:" + this.transferCodeByPk(MaterialVO.getDefaultTableName(), MaterialVO.CODE, MaterialVO.PK_MATERIAL, materialPk)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public String transferCodeByPk(String tableName, String selectField, String pkField, String pk) throws BusinessException { | ||||
|         if (pk == null || pk.trim().isEmpty()) { | ||||
|             log.error("未传入主键信息,无法查询编码:" + pkField + ":" + tableName + ":" + selectField); | ||||
|             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(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 根据表体源头单据类型编码确定WMS订单类型 | ||||
|      * | ||||
|      * @param itemVOs 报检点明细数组 | ||||
|      * @return WMS订单类型 | ||||
|      */ | ||||
|     private String getAsnTypeByFirstTypeCode(ApplySourceItemVO[] itemVOs) throws BusinessException { | ||||
|         if (itemVOs == null || itemVOs.length == 0) { | ||||
|             log.error("ArriveForQCImpl - 报检点明细为空,使用默认类型CGRK"); | ||||
|             throw new BusinessException("报检点明细为空,无法确定WMS订单类型"); | ||||
|         } | ||||
| 
 | ||||
|         // 取第一个表体行的源头单据类型编码 | ||||
|         String firstTypeCode = itemVOs[0].getCfirsttypecode(); | ||||
|         if (StringUtils.isEmpty(firstTypeCode)) { | ||||
|             log.error("ArriveForQCImpl - 源头单据类型编码为空,使用默认类型CGRK"); | ||||
|             throw new BusinessException("源头单据类型编码为空,无法确定WMS订单类型"); | ||||
|         } | ||||
|         return switch (firstTypeCode) { | ||||
|             case "21" -> // 采购订单 | ||||
|                     "CGRK"; | ||||
|             case "61" -> // 委外订单 | ||||
|                     "WWRK"; | ||||
|             default -> { | ||||
|                 log.error("ArriveForQCImpl - 未知的源头单据类型编码: " + firstTypeCode + ",不同步此报检单"); | ||||
|                 yield null; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,57 @@ | |||
| package nc.itf.pu.m23.qc; | ||||
| 
 | ||||
| import nc.vo.pu.m23.entity.ArriveItemVO; | ||||
| import nc.vo.pu.m23.entity.ArriveVO; | ||||
| import nc.vo.pub.BusinessException; | ||||
| import nc.vo.qc.c001.entity.ApplyVO; | ||||
| 
 | ||||
| /** | ||||
|  * <p> | ||||
|  * <b>到货单的针对质量管理的接口定义,本类主要完成以下功能:</b> | ||||
|  * <ul> | ||||
|  * <li>到货单的质检 | ||||
|  * <li>到货单的反检 | ||||
|  * </ul> | ||||
|  * <p> | ||||
|  * <p> | ||||
|  * | ||||
|  * @version 6.0 | ||||
|  * @since 6.0 | ||||
|  * @author hanbin | ||||
|  * @time 2010-1-11 下午01:40:39 | ||||
|  */ | ||||
| public interface IArriveForQC { | ||||
| 
 | ||||
|     /** | ||||
|      * 方法功能描述:>到货单的反检 | ||||
|      * <p> | ||||
|      * <b>参数说明</b> | ||||
|      * | ||||
|      * @param aggVO | ||||
|      * @throws BusinessException | ||||
|      *           <p> | ||||
|      * @since 6.0 | ||||
|      * @author hanbin | ||||
|      * @time 2010-1-13 上午09:43:38 | ||||
|      */ | ||||
|     public ArriveItemVO[] antiQualityCheck(ArriveItemVO[] bills) throws BusinessException; | ||||
| 
 | ||||
|     /** | ||||
|      * 方法功能描述:到货单的质检 | ||||
|      * <p> | ||||
|      * <b>参数说明</b> | ||||
|      * | ||||
|      * @param aggVO | ||||
|      * @param isCheck 免检存货是否报检 | ||||
|      * @throws BusinessException | ||||
|      *           <p> | ||||
|      * @since 6.0 | ||||
|      * @author hanbin | ||||
|      * @time 2010-1-13 上午09:43:38 | ||||
|      */ | ||||
|     public Object[] qualityCheck(ArriveVO[] bills, boolean isCheck) | ||||
|             throws BusinessException; | ||||
| 
 | ||||
|     public ApplyVO[] pushWmsByArriveVOs(ArriveVO[] bills) | ||||
|             throws Exception; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue