备料计划api类同步代码-张明&李正

This commit is contained in:
mzr 2025-10-11 08:49:01 +08:00
parent e9a6d413a8
commit 2c12487d2a
4 changed files with 1395 additions and 0 deletions

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding='gb2312'?>
<module>
<rest>
<resource classname="nccloud.openapi.mmpac.pickm.PickmResouce" exinfo="流程备料计划增删改查接口"/>
</rest>

View File

@ -0,0 +1,585 @@
package nc.impl.mmpac.pickm;
import java.util.*;
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.bs.mmpac.pickm.bp.PickmApproveBP;
import nc.bs.mmpac.pickm.bp.PickmDeleteBP;
import nc.bs.mmpac.pickm.bp.PickmFinishBP;
import nc.bs.mmpac.pickm.bp.PickmInsertBP;
import nc.bs.mmpac.pickm.bp.PickmUnApproveBP;
import nc.bs.mmpac.pickm.bp.PickmUnFinishBP;
import nc.bs.mmpac.pickm.bp.PickmUpdateBP;
import nc.bs.uapbd.util.ThirdPartyPostRequestUtil;
import nc.impl.pubapp.pattern.data.vo.VOQuery;
import nc.itf.bd.material.baseinfo.IMaterialBaseInfoQueryService;
import nc.itf.mmpac.pickm.IPickmMaintainService;
import nc.itf.mmpac.pickm.IPickmTransTypeService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.para.SysInitQuery;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.bc.pmpub.project.ProjectHeadVO;
import nc.vo.bd.material.MaterialVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.mmpac.pickm.entity.PickmHeadVO;
import nc.vo.mmpac.pickm.entity.PickmItemVO;
import nc.vo.mmpac.pickm.entity.PickmTransTypeVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.IVOMeta;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.pubapp.pattern.model.meta.entity.bill.IBillMeta;
import nc.vo.pubapp.pattern.model.transfer.bill.ClientBillCombinServer;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.scmpub.util.ArrayUtil;
import nc.vo.scmpub.util.CollectionUtils;
import nc.vo.util.CloneUtil;
import nccloud.pubitf.mmpub.commit.service.IBatchRunScriptService;
import nccloud.pubitf.riart.pflow.CloudPFlowContext;
/**
* 备料计划操作实现类
*/
public class PickmMaintainServiceImpl implements IPickmMaintainService {
private static Log log = Log.getInstance("rzmomlog");
private static BaseDAO dao = new BaseDAO();
/**
* 备料计划审核分别有流程和离散重写
*/
@Override
public AggPickmVO[] auditPickm(AggPickmVO[] vos) throws BusinessException {
// 审批操作
PickmApproveBP auditbp = new PickmApproveBP();
return auditbp.batchApprovePickm(vos);
}
/**
* 删除备料计划
*/
@Override
public void delete(AggPickmVO[] vos) throws BusinessException {
try {
// 删除操作
PickmDeleteBP deleteBP = new PickmDeleteBP();
deleteBP.delete(vos, false);
} catch (Exception e) {
ExceptionUtils.marsh(e);
}
}
/**
* 备料计划完成分别有流程离散重写
*/
@Override
public AggPickmVO[] finishPickm(AggPickmVO[] vos) throws BusinessException {
// 完成操作
PickmFinishBP finishbp = new PickmFinishBP();
return finishbp.finish(vos);
}
/**
* 新增备料计划
*/
@Override
public AggPickmVO[] insert(AggPickmVO[] vos) throws BusinessException {
// vos =
// NCLocator.getInstance().lookup(IPickmMaintainService.class).insert_RequiresNew(vos);
// // 根据交易类型进行保存即审核规则
// IRule<AggPickmVO> pickmAutoApproveRule = new PickmAutoApproveAfterSaveRule();
// pickmAutoApproveRule.process(vos);
try {
PickmInsertBP bp = new PickmInsertBP();
return bp.insert(vos);
} catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
* 备料计划弃审分别由流程离散重写
*/
@Override
public AggPickmVO[] unAuditPickm(AggPickmVO[] vos) throws BusinessException {
// 审批操作
PickmUnApproveBP auditbp = new PickmUnApproveBP();
return auditbp.batchUnApprovePickm(vos);
}
/**
* 备料计划取消完成分别有流程离散备料计划重写
*/
@Override
public AggPickmVO[] unfinishPickm(AggPickmVO[] vos) throws BusinessException {
// 取消完成操作
PickmUnFinishBP finishbp = new PickmUnFinishBP();
return finishbp.unfinish(vos);
}
/**
* 修改备料计划
*/
@Override
public AggPickmVO[] update(AggPickmVO[] vos) throws BusinessException {
try {
// 更新操作
PickmUpdateBP bp = new PickmUpdateBP();
vos = bp.update(vos, false, false);
} catch (Exception e) {
ExceptionUtils.marsh(e);
}
return vos;
}
/**
* 修改备料计划同时更新预留
*/
@Override
public AggPickmVO[] updateForYL(AggPickmVO[] vos) throws BusinessException {
try {
// 更新操作
PickmUpdateBP bp = new PickmUpdateBP(true);
vos = bp.update(vos, true, false);
} catch (Exception e) {
ExceptionUtils.marsh(e);
}
return vos;
}
@Override
public AggPickmVO[] updateForYLForNcc(AggPickmVO[] vos) throws BusinessException {
try {
// 更新操作
PickmUpdateBP bp = new PickmUpdateBP(true);
vos = bp.update(vos, true, false);
} catch (Exception e) {
ExceptionUtils.marsh(e);
}
return vos;
}
@Override
public AggPickmVO[] saveAndCommitPickm(AggPickmVO[] vos, UFBoolean isUpdate, UFBoolean isUpdateForYL)
throws BusinessException {
ClientBillCombinServer<AbstractBill> utils = new ClientBillCombinServer<AbstractBill>();
PickmUpdateBP updateBP = new PickmUpdateBP(true);
Object[] objects = null;
if (MMValueCheck.isTrue(isUpdate)) {
if (MMValueCheck.isTrue(isUpdateForYL)) {
objects = updateBP.update(vos, true, false);
} else {
objects = updateBP.update(vos, false, false);
}
} else {
PickmInsertBP insertBP = new PickmInsertBP();
objects = insertBP.insert(vos);
}
this.filterDeleteBodyData(vos);
utils.combine(vos, (AbstractBill[]) objects);
UFBoolean autoAuditFlag = this.getBSaveToAuditByTransTypeID(vos[0].getParentVO().getVbusitypeid());
if (MMValueCheck.isNotEmpty(vos)) {
if (autoAuditFlag.booleanValue()) {// 非保存即审核时执行提交
return vos;
}
// 执行提交
CloudPFlowContext context = new CloudPFlowContext();
context.setBillType("55A3");
context.setActionName("SAVE");
context.setBillVos(vos);
IBatchRunScriptService service = NCLocator.getInstance().lookup(IBatchRunScriptService.class);
Object[] obj = service.run(context, AggPickmVO.class);
this.filterDeleteBodyData(vos);
utils.combine(vos, (AbstractBill[]) obj);
return vos;
}
return null;
}
@Override
public AggPickmVO[] pushRZMes(AggPickmVO[] vos) throws BusinessException {
if (ArrayUtil.isEmpty(vos)) {
return null;
}
try {
AggPickmVO[] cloneOrderVOS = (AggPickmVO[]) CloneUtil.deepClone(vos);
// 检查并筛选领料组织
List<AggPickmVO> newAggPickmVOS = checkAndFilterBillSrcOrg(cloneOrderVOS);
if (newAggPickmVOS.isEmpty()) {
return vos;
}
Boolean is55A2OR30=checkSrcBillType(newAggPickmVOS);
if(is55A2OR30){
//来源生产订单
pushToRZMOMBy55A2(newAggPickmVOS.toArray(new AggPickmVO[0]));
}else{
//来源委外订单
pushToRZMOMBy61(newAggPickmVOS.toArray(new AggPickmVO[0]));
}
} catch (Exception e) {
ExceptionUtils.wrappException(e);
}
return vos;
}
/**
* 过滤删除的行 TODO
*
* @param uiBillArrays
*
*/
private void filterDeleteBodyData(AbstractBill[] uiBillArrays) {
for (AbstractBill bill : uiBillArrays) {
// change by zhangshqb 改为支持一主多子的聚合VO
IBillMeta metaData = bill.getMetaData();
IVOMeta[] children = metaData.getChildren();
for (IVOMeta ivoMeta : children) {
List<ISuperVO> normal = new ArrayList<ISuperVO>();
ISuperVO[] childs = bill.getChildren(ivoMeta);
if (childs != null && childs.length > 0) {
for (ISuperVO child : childs) {
if (child.getStatus() != VOStatus.DELETED) {
normal.add(child);
}
}
bill.setChildren(ivoMeta, CollectionUtils.listToArray(normal));
}
}
}
}
private UFBoolean getBSaveToAuditByTransTypeID(String vbusitypeid) {
IPickmTransTypeService service = NCLocator.getInstance().lookup(IPickmTransTypeService.class);
try {
PickmTransTypeVO typevo = service.queryTransTypeVO(vbusitypeid);
if (MMValueCheck.isEmpty(typevo)) {
return UFBoolean.FALSE;
}
return typevo.getBautoaduitaftersave() == null ? UFBoolean.FALSE : typevo.getBautoaduitaftersave();
} catch (BusinessException e) {
ExceptionUtils.wrappException(e);
}
return UFBoolean.FALSE;
}
private Boolean checkSrcBillType(List<AggPickmVO> newAggPickmVOS) throws BusinessException {
UFBoolean is61=UFBoolean.FALSE;
UFBoolean is55A2OR30=UFBoolean.FALSE;
for (AggPickmVO aggPickmVO : newAggPickmVOS) {
String vfirstbilltype = aggPickmVO.getParentVO().getVfirstbilltype();
if("61".equals(vfirstbilltype)){
is61=UFBoolean.TRUE;
}else if("55A2".equals(vfirstbilltype)){
is55A2OR30=UFBoolean.TRUE;
}else if("30".equals(vfirstbilltype)){
is55A2OR30=UFBoolean.TRUE;
}
}
if(is55A2OR30.booleanValue()&&is61.booleanValue()){
throw new BusinessException("备料计划推送锐制失败,原因:不允许源头单据类型为生产订单和委外订单的单据同时审批");
}
return is55A2OR30.booleanValue();
}
private void buildSyncDataBy55A2(PickmHeadVO head, PickmItemVO[] bodys, JSONArray details) throws BusinessException {
Integer fsourcetype = head.getFsourcetype();
if(fsourcetype!=0){
return;
}
//2025年8月12日08点55分--新增生产订单项目字段信息
String csourcebillrowid = head.getCsourcebillrowid();
PMOItemVO[] srcBVOs = new VOQuery<PMOItemVO>(PMOItemVO.class).query(new String[]{csourcebillrowid});
ProjectHeadVO[] cprojectVOs=null;
if(srcBVOs!=null&&srcBVOs.length>0){
String cprojectid = srcBVOs[0].getCprojectid();
if(!StringUtils.isEmpty(cprojectid)){
cprojectVOs= new VOQuery<ProjectHeadVO>(ProjectHeadVO.class).query(new String[]{cprojectid});
}
}
//end
for (PickmItemVO body : bodys) {
JSONObject singleObj = new JSONObject();
String vsourcebillcode = head.getVsourcebillcode();
String wlbm_wbid =body.getCbmaterialvid();
String scgx_wbid =head.getVstdprocid();
//wbid varchar (200) 第三方系统主键id
singleObj.put("wbid", head.getCpickmid()+"_"+body.getCpickm_bid()); // 第三方系统主键id
//operate int 操作状态 必填 1新增/修改2删除删除时只需上传wbid
singleObj.put("operate", "1");
//wbzbid varchar (200) 第三方系统分组id
singleObj.put("wbzbid", head.getCpickmid());
//wbqjpx varchar(2000) 全局排序 必填 BOM表物料行号
singleObj.put("wbqjpx", body.getVrowno());
//scjh_wbid varchar(100) 第三方系统生产计划ID 必填 生产计划号外部ID一般ERP系统的生产订单号
singleObj.put("scjh_wbid", head.getCsourcebillid());
//jhxh numeric(5) 计划序号 -生产订单行号
singleObj.put("jhxh", head.getVsourcebillrowno());
singleObj.put("wlbm_wbid", wlbm_wbid); // 第三方系统材料id
//bomlx int BOM类型 必填 默认=0即传入生产BOM1为包装BOM
singleObj.put("bomlx", 0);
if(body.getNunituseastnum()==null ){
singleObj.put("dwyl", UFDouble.ZERO_DBL.getDouble()); // 单位用量nunituseastnum
singleObj.put("djyl", UFDouble.ZERO_DBL.getDouble()); // 单据用量nunituseastnum
}else{
singleObj.put("dwyl", body.getNunituseastnum().getDouble()); // 单位用量nunituseastnum
singleObj.put("djyl", body.getNunituseastnum().getDouble()); // 单据用量nunituseastnum
}
singleObj.put("clyl", body.getNplanoutastnum().getDouble()); // 材料用量
// String rccode = transferCodeByPk(RcVO.getDefaultTableName(), RcVO.VRCCODE, RcVO.CRCID, head.getVstdprocid());
singleObj.put("scgx_wbid", body.getVbdef11());
// singleObj.put("scgx_wbid", rccode); // 第三方系统使用工序id
//sdbj int 锁定标记 必填 默认1正常业务ERP审核后传输至锐制MOM
singleObj.put("sdbj", 1);
//shbj int 审核标记 必填 默认1正常业务ERP审核后传输至锐制MOM
singleObj.put("shbj", 1);
//jylxbm --
singleObj.put("jylxbm", head.getVbusitype());
//2025年8月12日08点55分--新增生产订单项目字段信息 start
if(cprojectVOs!=null && cprojectVOs.length>0){
singleObj.put("wlzdycs06", cprojectVOs[0].getProject_code());
singleObj.put("wlzdycs11", cprojectVOs[0].getProject_name());
}
//2025年8月12日08点55分--新增生产订单项目字段信息 end
//2025年9月1日15点14分--新增需用日期字段 -start
UFDate drequiredate = body.getDrequiredate();
singleObj.put("wlzdycs19", drequiredate==null?null:drequiredate.toStdString());
//2025年9月1日15点14分--新增需用日期字段 -end
details.add(singleObj);
}
}
private void buildSyncDataBy61(PickmHeadVO head, PickmItemVO[] bodys, JSONArray details) throws BusinessException {
Integer fsourcetype = head.getFsourcetype();
if(fsourcetype!=1){
return;
}
for (PickmItemVO body : bodys) {
JSONObject singleObj = new JSONObject();
String vsourcebillcode = head.getVsourcebillcode();
String wlbm_wbid =body.getCbmaterialvid();
String scgx_wbid =head.getVstdprocid();
//wbid varchar (200) 第三方系统主键id
singleObj.put("wbid", head.getCpickmid()+"_"+body.getCpickm_bid()); // 第三方系统主键id
//wbzbid varchar (200) 第三方系统分组id
singleObj.put("wbpid", head.getCpickmid());
//operate int 操作状态 必填 1新增/修改2删除删除时只需上传wbid
singleObj.put("operate", "1");
//djly varchar(20) 来源单据 必填 取值read_djlyb中编号
//领料通知默认1011
singleObj.put("djly", "1011");
//_id varchar(50) 单据id 必填 后台该单据类型的唯一ID
singleObj.put("djbh_id", head.getCpickmid());
//djbh varchar(100) 单据编号 必填 前台单据编号
singleObj.put("djbh", head.getVbillcode());
//djxh numeric(5) 单据序号 必填 前台单据序号
singleObj.put("djxh", body.getVrowno());
//djrq datetime 单据日期 必填
singleObj.put("djrq", head.getDmakedate().toString());
//wlbm_wbid varchar(100) 第三方系统物料名称id 必填 物料编码的后台ID
singleObj.put("wlbm_wbid", wlbm_wbid);
//djsl numeric(18,3) 单据数量 必填
UFDouble djsl = body.getNplanoutastnum() == null ? UFDouble.ZERO_DBL : body.getNplanoutastnum();
singleObj.put("djsl", djsl.getDouble());
//sddd varchar(510)送达地点 必填 传仓库名称要求上位ERP仓库名称不重复
// singleObj.put("sddd", transferCodeByPk(StordocVO.getDefaultTableName(), StordocVO.NAME, StordocVO.PK_STORDOC, body.getCoutstockid()));
//ckbh_wbid varchar(100) 第三方系统仓库id 必填 储区根据仓库默认同仓库多储区时两者必填
// singleObj.put("ckbh_wbid",body.getCoutstockid());
//qfbj int 签发标记 必填 默认1上位系统审核传至MOM 1
singleObj.put("qfbj", 1);
//cght_wbid varchar(100) 第三方系统合同id 必填 委外订单主键ID
singleObj.put("cght_wbid",head.getCfirstbillid());
//htbh varchar(100) 合同号 委外订单单据号
singleObj.put("htbh",head.getVfirstbillcode());
//htxh numeric(5) 合同序号 委外订单单据序号
singleObj.put("htxh",head.getVfirstbillrowno());
//cght_wbid varchar(100) 第三方系统合同id 必填
// singleObj.put("cght_wbid", transferCodeByPk("bd_defdoc", DefdocVO.CODE, DefdocVO.PK_DEFDOC, body.getVbdef5()));
details.add(singleObj);
}
}
private List<AggPickmVO> checkAndFilterBillSrcOrg(AggPickmVO[] aggPickmVOS) throws BusinessException {
List<AggPickmVO> aggvoList = new ArrayList<>();
List<AggPickmVO> finalList = new ArrayList<>();
for (AggPickmVO aggvo : aggPickmVOS) {
String pkOrg = aggvo.getParentVO().getPk_org();
String orgCode = transferCodeByPk(OrgVO.getDefaultTableName(), OrgVO.CODE, OrgVO.PK_ORG, pkOrg);
//过滤上游不是生产订单和委外订单的备料计划
String vfirstbilltype = aggvo.getParentVO().getVfirstbilltype();
String vdef20 = aggvo.getParentVO().getVdef20();
if(vdef20==null||"N".equals(vdef20)){
if ("C022".equals(orgCode)&& 1 == aggvo.getParentVO().getFbillstatus()&&aggvo.getChildrenVO()!=null && aggvo.getChildrenVO().length > 0) {
if("61".equals(vfirstbilltype)||"55A2".equals(vfirstbilltype)||"30".equals(vfirstbilltype)){
//2025年7月2日10点33分--新增不传--表体物料编码前三位为103时不传
//获取表体物料信息
aggvoList.add(aggvo);
}
}
}
}
//再次筛选
//2025年7月2日10点33分--新增不传--表体物料编码前三位为103时不传
//获取表体物料信息
if(aggvoList.isEmpty()){
return aggvoList;
}
Set<String> materialpks=new HashSet<>();
for (AggPickmVO aggvo : aggvoList) {
PickmItemVO[] items = (PickmItemVO[]) aggvo.getChildren(PickmItemVO.class);
for (PickmItemVO item : items) {
String cbmaterialvid = item.getCbmaterialvid();
materialpks.add(cbmaterialvid);
}
}
if(materialpks.isEmpty()){
return aggvoList;
}
//根据物料id查询物料信息
MaterialVO[] vos = NCLocator.getInstance().lookup(IMaterialBaseInfoQueryService.class).queryDataByPks(materialpks.toArray(new String[0]));
//组装Map
Map<String, String> materialMap = new HashMap<>();
if(vos==null || vos.length<1){
throw new BusinessException("Failed to query material info , please check !!!");
}
for (MaterialVO vo : vos) {
String cmaterialvid = vo.getPk_material();
String cmaterialcode =vo.getCode();
materialMap.put(cmaterialvid, cmaterialcode);
}
//筛选行数据
for (AggPickmVO aggvo : aggvoList) {
List<PickmItemVO> newItems = new ArrayList<>();
PickmItemVO[] items = (PickmItemVO[]) aggvo.getChildren(PickmItemVO.class);
for (PickmItemVO item : items) {
String cmaterialvid = item.getCbmaterialvid();
if (materialMap.containsKey(cmaterialvid)) {
String materialCode = materialMap.get(cmaterialvid);
if(!materialCode.startsWith("103")){
newItems.add(item);
}
}
}
if (!newItems.isEmpty()) {
aggvo.setChildren(PickmItemVO.class,newItems.toArray(new PickmItemVO[0]));
finalList.add(aggvo);
}
}
return finalList;
}
private void pushToRZMOMBy55A2(AggPickmVO[] aggPickmVOS) throws BusinessException {
String rzwmsip = SysInitQuery.getParaString("GLOBLE00000000000000", "RZWMSIP");
JSONObject jsonObject = new JSONObject();
JSONObject dataIn = new JSONObject();
JSONObject dataIn2 = new JSONObject();
JSONArray details = new JSONArray();
jsonObject.put("dataflow", "用友BIP→RZMOMv6");
jsonObject.put("actionCode", "scbomb");
for (AggPickmVO aggPickmVO : aggPickmVOS) {
PickmHeadVO head = aggPickmVO.getParentVO();
PickmItemVO[] bodys = (PickmItemVO[]) aggPickmVO.getChildrenVO();
buildSyncDataBy55A2(head, bodys, details);
}
dataIn2.put("Details", details);
dataIn.put("Data", dataIn2);
jsonObject.put("data", dataIn);
log.error("生产BOW推送锐制请求报文" + jsonObject.toJSONString());
String result = ThirdPartyPostRequestUtil.sendPostRequest(rzwmsip, jsonObject.toJSONString());
JSONObject resultObj = JSONObject.parseObject(result);
if (resultObj == null || !"true".equals(resultObj.getString("success"))) {
String errorMsg = resultObj == null ? "接口返回为空" : resultObj.getString("msg");
throw new BusinessException("RZ同步失败原因" + errorMsg);
}else{
log.error("RZMOM同步成功返回参数【"+resultObj.toJSONString()+"");
}
}
private void pushToRZMOMBy61(AggPickmVO[] aggPickmVOS) throws BusinessException {
String rzwmsip = SysInitQuery.getParaString("GLOBLE00000000000000", "RZWMSIP");
JSONObject jsonObject = new JSONObject();
JSONObject dataIn = new JSONObject();
JSONObject dataIn2 = new JSONObject();
JSONArray details = new JSONArray();
jsonObject.put("dataflow", "用友BIP→RZMOMv6");
jsonObject.put("actionCode", "wwfhtzdb");
for (AggPickmVO aggPickmVO : aggPickmVOS) {
PickmHeadVO head = aggPickmVO.getParentVO();
PickmItemVO[] bodys = (PickmItemVO[]) aggPickmVO.getChildrenVO();
buildSyncDataBy61(head, bodys, details);
}
dataIn2.put("Details", details);
dataIn.put("Data", dataIn2);
jsonObject.put("data", dataIn);
log.error("生产BOW推送锐制请求报文" + jsonObject.toJSONString());
String result = ThirdPartyPostRequestUtil.sendPostRequest(rzwmsip, jsonObject.toJSONString());
JSONObject resultObj = JSONObject.parseObject(result);
if (resultObj == null || !"true".equals(resultObj.getString("success"))) {
String errorMsg = resultObj == null ? "接口返回为空" : resultObj.getString("msg");
throw new BusinessException("RZ同步失败原因" + errorMsg);
}else{
log.error("RZMOM同步成功返回参数【"+resultObj.toJSONString()+"");
}
}
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();
}
}

View File

@ -0,0 +1,103 @@
package nc.itf.mmpac.pickm;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
/**
* 标准单据业务操作接口,增删改查
*
* @since 6.0
* @version 2010-12-16 下午04:36:00
* @author
*/
public interface IPickmMaintainService {
/**
* 删除备料计划单据
*
* @param AggPickmVO
* @throws BusinessException
*/
void delete(AggPickmVO[] vos) throws BusinessException;
/**
* 新增备料计划单据
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] insert(AggPickmVO[] vos) throws BusinessException;
/**
* 更新备料计划单据
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] update(AggPickmVO[] vos) throws BusinessException;
/**
* 为预留更新单据
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] updateForYL(AggPickmVO[] vos) throws BusinessException;
AggPickmVO[] updateForYLForNcc(AggPickmVO[] vos) throws BusinessException;
/**
* 备料计划审核
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] auditPickm(AggPickmVO[] vos) throws BusinessException;
/**
* 备料计划取消审核
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] unAuditPickm(AggPickmVO[] vos) throws BusinessException;
/**
* 备料计划完成
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] finishPickm(AggPickmVO[] vos) throws BusinessException;
/**
* 备料计划取消完成
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] unfinishPickm(AggPickmVO[] vos) throws BusinessException;
/**
* 备料计划保存提交
*
* @param AggPickmVO
* @return AggPickmVO
* @throws BusinessException
*/
AggPickmVO[] saveAndCommitPickm(AggPickmVO[] vos,UFBoolean isUpdate,UFBoolean isUpdateForYL) throws BusinessException;
/**
* 推送RZMES
* @param vos
* @return
* @throws BusinessException
*/
AggPickmVO[] pushRZMes(AggPickmVO[] vos) throws BusinessException;
}

View File

@ -0,0 +1,702 @@
package nccloud.openapi.mmpac.pickm;
import java.util.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Log;
import nc.bs.scmpub.query.SCMBillQuery;
import nc.itf.mmpac.pickm.IPickmMaintainService;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.util.mmf.framework.base.MMCollectionUtil;
import nc.vo.bd.bom.bom0202.entity.AggBomVO;
import nc.vo.bd.bom.bom0202.entity.BomItemVO;
import nc.vo.bd.bom.bom0202.entity.BomVO;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.material.measdoc.MeasdocVO;
import nc.vo.bd.psn.PsndocVO;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.mmpac.pickm.entity.PickmHeadVO;
import nc.vo.mmpac.pickm.entity.PickmItemVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOHeadVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.org.GroupVO;
import nc.vo.org.OrgVO;
import nc.vo.org.StockOrgVO;
import nc.vo.pub.*;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.vorg.StockOrgVersionVO;
import nc.ws.opm.pub.utils.result.APIErrCodeEnum;
import nccloud.api.rest.utils.ResultMessageUtil;
import nccloud.ws.rest.resource.AbstractNCCRestResource;
import org.json.JSONString;
@Path("mmpac/pickm")
public class PickmResouce extends AbstractNCCRestResource {
private static String HEADTABLE = "mm_pickm";
private static String BODYTABLE = "mm_pickm_b";
private static final BaseDAO BASE_DAO = new BaseDAO();
private static final Log logger = Log.getInstance("pmoresouceLogger");
private static Map<String, String> entityNameToClassName = new HashMap();
public PickmResouce() {
}
/**
* 备料计划 新增修改删除三个接口 openapi , 提供给mes,
* 备料计划是审批后的, 传递的是流程生产订单明细行主键,
* 操作的是流程备料计划的明细行,新增修改删除是针对于明细行来说的
* 根据流程生产订单明细行的主键 可以查询到流程备料计划的AggVO,然后操作他的明细
*/
@POST
@Path("save")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString save(Map<String, Object> paramMap) {
logger.debug("开始进行备料计划明细行的新增操作");
// 如果没有传递data属性
if (!paramMap.containsKey("data")) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
try {
List<Map<String, Object>> batchData = (List) paramMap.get("data");
IPickmMaintainService serv = (IPickmMaintainService) NCLocator.getInstance().lookup(IPickmMaintainService.class);
// 如果没有数据
if (MMCollectionUtil.isEmpty(batchData)) {
logger.info("传入数据异常参数要包含data");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
List<AggPickmVO> resAggVOS = new ArrayList<>();
// 批量处理每一个主子表对象
for (Map<String, Object> singleData : batchData) {
if (!singleData.containsKey("pk_pmo")) {
logger.info("传入数据异常参数要包含pk_pmo");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含pk_pmo", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
String pk_pmo = (String) singleData.get("pk_pmo");
// 查询表头
String searchHeadSql = "SELECT * FROM mm_pickm WHERE nvl(dr,0) = 0 AND vsourcemocode = '" + pk_pmo + "'";
List<Map<String, Object>> pickmHeadRows = (List<Map<String, Object>>) BASE_DAO.executeQuery(searchHeadSql, new MapListProcessor());
if (pickmHeadRows == null) {
logger.info("根据pk_pmo查询的流程备料计划不存在");
return ResultMessageUtil.exceptionToJSON("根据pk_pmo查询的流程备料计划不存在", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
PickmHeadVO pickmHeadVO = transferToPickmHeadVO(pickmHeadRows.get(0), VOStatus.UPDATED);
if (!singleData.containsKey("mm_pickm_b")) {
logger.info("传入数据异常参数要包含mm_pickm_b");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含mm_pickm_b", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
List<Map<String, Object>> batchPickms = (List<Map<String, Object>>) singleData.get("mm_pickm_b");
// 循环请求体中每一个备料计划明细
List<PickmItemVO> finalPickmItemVOS = null;
for (Map<String, Object> singlePickm : batchPickms) {
// 需要将singleData中的每一个code转为主键重新存储
Map<String, Object> newMap = transferSingleDataCodeToPk(singlePickm);
PickmItemVO pickmItemVO = transferToPickmItemVO(newMap, VOStatus.NEW);
// 查询表体
String searchBodySql = "SELECT * FROM mm_pickm_b WHERE nvl(dr,0) = 0 AND cpickmid = '" + pickmHeadVO.getCpickmid() + "'";
List<PickmItemVO> existingPickmItemVOS = (List<PickmItemVO>) BASE_DAO.executeQuery(searchBodySql, new BeanListProcessor(PickmItemVO.class));
if (existingPickmItemVOS == null) {
logger.info("根据pk_pmo查询的流程备料计划明细不存在");
return ResultMessageUtil.exceptionToJSON("根据pk_pmo查询的流程备料计划明细不存在", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 如果已存在的不为空
finalPickmItemVOS = new ArrayList<>(existingPickmItemVOS);
// 如果新增加的不为空
finalPickmItemVOS.add(pickmItemVO);
}
if (finalPickmItemVOS == null) {
logger.info("数据异常 处理后备料计划明细为空");
return ResultMessageUtil.exceptionToJSON("数据异常 处理后备料计划明细为空", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 转换为AggVO
PickmItemVO[] array = (PickmItemVO[]) finalPickmItemVOS.toArray(new PickmItemVO[0]);
AggPickmVO aggPickmVO = new AggPickmVO();
aggPickmVO.setParent(pickmHeadVO);
aggPickmVO.setChildren(PickmItemVO.class, array);
aggPickmVO.getParentVO().setStatus(VOStatus.UPDATED);
this.setDefaultValue(aggPickmVO);
resAggVOS.add(aggPickmVO);
}
// 更新
AggPickmVO[] updatedAggVOS = (AggPickmVO[]) resAggVOS.toArray(new AggPickmVO[0]);
AggPickmVO[] insertBills = serv.update(updatedAggVOS);
logger.info("备料计划明细行新增成功");
return ResultMessageUtil.toJSON(insertBills, "备料计划明细行新增成功");
} catch (Exception e) {
logger.error("备料计划明细行新增异常", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
@POST
@Path("update")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString update(Map<String, Object> paramMap) {
logger.debug("开始进行备料计划明细行的修改操作");
// 如果没有传递data属性
if (!paramMap.containsKey("data")) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
try {
List<Map<String, Object>> batchData = (List) paramMap.get("data");
IPickmMaintainService serv = (IPickmMaintainService) NCLocator.getInstance().lookup(IPickmMaintainService.class);
// 如果没有数据
if (MMCollectionUtil.isEmpty(batchData)) {
logger.info("传入数据异常参数要包含data");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
List<AggPickmVO> resAggVOS = new ArrayList<>();
// 批量处理每一个主子表对象
for (Map<String, Object> singleData : batchData) {
if (!singleData.containsKey("pk_pmo")) {
logger.info("传入数据异常参数要包含pk_pmo");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含pk_pmo", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 根据流程生产订单明细
String pk_pmo = (String) singleData.get("pk_pmo");
PMOItemVO pmoItemVO = (PMOItemVO) BASE_DAO.retrieveByPK(PMOItemVO.class, pk_pmo);
if (pmoItemVO == null) {
logger.info("根据pk_pmo查询的流程生产订单明细行不存在");
return ResultMessageUtil.exceptionToJSON("根据pk_pmo查询的流程生产订单明细行不存在", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
List<PickmHeadVO> pickmHeadVOS = (List<PickmHeadVO>) BASE_DAO.retrieveByClause(PickmHeadVO.class, PickmHeadVO.VSOURCEMOROWID + " = '" + pk_pmo + "'");
if (pickmHeadVOS == null || pickmHeadVOS.isEmpty()) {
logger.info("根据流程生产订单明细主键查询备料计划失败");
return ResultMessageUtil.exceptionToJSON("根据流程生产订单明细主键查询备料计划失败", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
PickmHeadVO pickmHeadVO = pickmHeadVOS.get(0);
if (!singleData.containsKey("mm_pickm_b")) {
logger.info("传入数据异常参数要包含mm_pickm_b");
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含mm_pickm_b", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 拿到每一个明细 进行修改
List<Map<String, Object>> batchPickms = (List<Map<String, Object>>) singleData.get("mm_pickm_b");
// 先将物料编码相同的明细进行分组
Map<String, List<Map<String, Object>>> materialGroups = new HashMap<>();
for (Map<String, Object> singlePicm : batchPickms) {
String cbmaterialvid = (String) singlePicm.get("cbmaterialvid");
if (cbmaterialvid == null) {
return ResultMessageUtil.exceptionToJSON("传入数据异常流程备料计划明细行中参数要包含cbmaterialvid", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
materialGroups.computeIfAbsent(cbmaterialvid, k -> new ArrayList<>()).add(singlePicm);
}
// 查询该备料计划下的所有明细
String searchBodySql = "SELECT * FROM mm_pickm_b WHERE nvl(dr,0) = 0 AND cpickmid = '" + pickmHeadVO.getCpickmid() + "'";
List<PickmItemVO> existingPickmItemVOS = (List<PickmItemVO>) BASE_DAO.executeQuery(searchBodySql, new BeanListProcessor(PickmItemVO.class));
if (existingPickmItemVOS == null || existingPickmItemVOS.isEmpty()) {
logger.info("根据备料计划主键查询的流程备料计划明细不存在");
return ResultMessageUtil.exceptionToJSON("根据备料计划主键查询的流程备料计划明细不存在", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
List<PickmItemVO> finalPickmItemVOS = new ArrayList<>();
// 处理每个物料组
for (Map.Entry<String, List<Map<String, Object>>> entry : materialGroups.entrySet()) {
String materialCode = entry.getKey();
List<Map<String, Object>> materialItems = entry.getValue();
// 将物料编码转换为主键
String materialPk = transferPkByCode(MaterialVO.getDefaultTableName(), MaterialVO.PK_MATERIAL, MaterialVO.CODE, materialCode);
// 查询该物料对应的所有备料计划明细
List<PickmItemVO> materialPickmItems = new ArrayList<>();
for (PickmItemVO item : existingPickmItemVOS) {
if (materialPk.equals(item.getCbmaterialvid())) {
materialPickmItems.add(item);
}
}
if (materialPickmItems.isEmpty()) {
logger.info("未找到物料编码 " + materialCode + " 对应的备料计划明细");
return ResultMessageUtil.exceptionToJSON("未找到物料编码 " + materialCode + " 对应的备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 判断是否有重复物料同一物料编码但isvirtual不同
if (materialItems.size() == 1) {
// 无重复直接更新
Map<String, Object> singlePicm = materialItems.get(0);
Map<String, Object> newSinglePicm = transferSingleDataCodeToPk(singlePicm);
PickmItemVO pickmItemVO = transferToPickmItemVO(newSinglePicm, VOStatus.UPDATED);
// 直接取第一个匹配的明细进行更新
PickmItemVO existingPickmItemVO = materialPickmItems.get(0);
for (String attributeName : pickmItemVO.getAttributeNames()) {
if (pickmItemVO.getAttributeValue(attributeName) != null) {
existingPickmItemVO.setAttributeValue(attributeName, pickmItemVO.getAttributeValue(attributeName));
}
}
finalPickmItemVOS.add(existingPickmItemVO);
} else if (materialItems.size() == 2) {
// 有重复需要通过BOM逻辑进行匹配
// 先查询BOM信息
String bomSql = "cbmaterialvid = '" + pmoItemVO.getCmaterialvid() + "' and vbbomversionnumber = '" + pmoItemVO.getVbomversion() + "'";
BomVO bomHeadVO = (BomVO) BASE_DAO.retrieveByClause(BomVO.class, bomSql);
if (bomHeadVO == null) {
logger.info("未找到对应的BOM信息");
return ResultMessageUtil.exceptionToJSON("未找到对应的BOM信息", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
String bombSql = BomVO.CBOMID + " = '" + bomHeadVO.getCbomid() + "'";
List<BomItemVO> bomItemVOS = (List<BomItemVO>) BASE_DAO.retrieveByClause(BomItemVO.class, bombSql);
// 分离实项和虚项
Map<String, Object> realItem = null;
Map<String, Object> virtualItem = null;
for (Map<String, Object> item : materialItems) {
String isVirtual = (String) item.get("isvirtual");
if (isVirtual == null || (!isVirtual.equals("Y") && !isVirtual.equals("N"))) {
return ResultMessageUtil.exceptionToJSON("isvirtual参数错误,必须为Y或者N", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
if ("N".equals(isVirtual)) {
realItem = item;
} else {
virtualItem = item;
}
}
if (realItem == null || virtualItem == null) {
return ResultMessageUtil.exceptionToJSON("重复物料组中必须包含一个实项(isvirtual=N)和一个虚项(isvirtual=Y)", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 处理实项 - 通过BOM查找对应的备料计划明细
Map<String, Object> newRealItem = transferSingleDataCodeToPk(realItem);
PickmItemVO realPickmItemVO = transferToPickmItemVO(newRealItem, VOStatus.UPDATED);
PickmItemVO realExistingItem = null;
// 先检查BOM表头
String hcmaterialvid = bomHeadVO.getHcmaterialvid();
UFBoolean hisvirtual = bomHeadVO.getHisvirtual();
if (hcmaterialvid != null && hisvirtual != null &&
hcmaterialvid.equals(realPickmItemVO.getCbmaterialvid()) && !hisvirtual.booleanValue()) {
for (PickmItemVO item : materialPickmItems) {
if (bomHeadVO.getCbomid().equals(item.getCbombid())) {
realExistingItem = item;
break;
}
}
}
// 如果表头没找到查找BOM明细
if (realExistingItem == null) {
for (BomItemVO bomItemVO : bomItemVOS) {
if (bomItemVO != null) {
String cmaterialvid = bomItemVO.getCmaterialvid();
UFBoolean bisvirtual = bomItemVO.getBisvirtual();
if (cmaterialvid != null && bisvirtual != null &&
cmaterialvid.equals(realPickmItemVO.getCbmaterialvid()) && !bisvirtual.booleanValue()) {
for (PickmItemVO item : materialPickmItems) {
if (bomItemVO.getCbom_bid().equals(item.getCbombid())) {
realExistingItem = item;
break;
}
}
if (realExistingItem != null) break;
}
}
}
}
if (realExistingItem == null) {
logger.error("未找到实项对应的备料计划明细");
return ResultMessageUtil.exceptionToJSON("未找到实项对应的备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 更新实项
for (String attributeName : realPickmItemVO.getAttributeNames()) {
if (realPickmItemVO.getAttributeValue(attributeName) != null) {
realExistingItem.setAttributeValue(attributeName, realPickmItemVO.getAttributeValue(attributeName));
}
}
finalPickmItemVOS.add(realExistingItem);
// 处理虚项 - 排除法找到另一个明细
PickmItemVO virtualExistingItem = null;
for (PickmItemVO item : materialPickmItems) {
if (!item.equals(realExistingItem)) {
virtualExistingItem = item;
break;
}
}
if (virtualExistingItem == null) {
logger.error("未找到虚项对应的备料计划明细");
return ResultMessageUtil.exceptionToJSON("未找到虚项对应的备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 更新虚项
Map<String, Object> newVirtualItem = transferSingleDataCodeToPk(virtualItem);
PickmItemVO virtualPickmItemVO = transferToPickmItemVO(newVirtualItem, VOStatus.UPDATED);
for (String attributeName : virtualPickmItemVO.getAttributeNames()) {
if (virtualPickmItemVO.getAttributeValue(attributeName) != null) {
virtualExistingItem.setAttributeValue(attributeName, virtualPickmItemVO.getAttributeValue(attributeName));
}
}
finalPickmItemVOS.add(virtualExistingItem);
} else {
return ResultMessageUtil.exceptionToJSON("同一物料编码最多只能有2个明细(一个实项一个虚项)", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
}
PickmItemVO[] array = finalPickmItemVOS.toArray(new PickmItemVO[0]);
AggPickmVO aggPickmVO = new AggPickmVO();
aggPickmVO.setParent(pickmHeadVO);
aggPickmVO.setChildren(PickmItemVO.class, array);
aggPickmVO.getParentVO().setStatus(VOStatus.UPDATED);
this.setDefaultValue(aggPickmVO);
resAggVOS.add(aggPickmVO);
}
// 更新
AggPickmVO[] updatedAggVOS = resAggVOS.toArray(new AggPickmVO[0]);
AggPickmVO[] updateBills = serv.update(updatedAggVOS);
logger.info("备料计划明细行修改成功");
return ResultMessageUtil.toJSON(updateBills, "备料计划明细行修改成功");
} catch (Exception e) {
logger.error("备料计划明细行修改异常", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
@POST
@Path("delete")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString delete(Map<String, Object> paramMap) {
logger.debug("开始进行备料计划明细行的删除操作");
// 如果没有传递data属性
if (!paramMap.containsKey("data")) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
try {
List<Map<String, Object>> paramList = (List) paramMap.get("data");
if (MMCollectionUtil.isEmpty(paramList)) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含data", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
IPickmMaintainService serv = (IPickmMaintainService) NCLocator.getInstance().lookup(IPickmMaintainService.class);
List<AggPickmVO> resultAggVOList = new ArrayList<>();
// 按pk_pmo分组处理
Map<String, List<Map<String, Object>>> pmoGroups = new HashMap<>();
for (Map<String, Object> map : paramList) {
String pk_pmo = (String) map.get("pk_pmo");
if (pk_pmo == null) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含pk_pmo", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
pmoGroups.computeIfAbsent(pk_pmo, k -> new ArrayList<>()).add(map);
}
for (Map.Entry<String, List<Map<String, Object>>> pmoEntry : pmoGroups.entrySet()) {
String pk_pmo = pmoEntry.getKey();
List<Map<String, Object>> pmoItems = pmoEntry.getValue();
// 根据流程生产订单明细查询PMO信息
PMOItemVO pmoItemVO = (PMOItemVO) BASE_DAO.retrieveByPK(PMOItemVO.class, pk_pmo);
if (pmoItemVO == null) {
logger.info("根据pk_pmo查询的流程生产订单明细行不存在");
return ResultMessageUtil.exceptionToJSON("根据pk_pmo查询的流程生产订单明细行不存在", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 根据流程生产订单明细主键查询备料计划
List<PickmHeadVO> pickmHeadVOS = (List<PickmHeadVO>) BASE_DAO.retrieveByClause(PickmHeadVO.class, PickmHeadVO.VSOURCEMOID + " = '" + pmoItemVO.getCmoid() + "'");
if (pickmHeadVOS == null || pickmHeadVOS.isEmpty()) {
logger.info("根据流程生产订单明细主键查询备料计划失败");
return ResultMessageUtil.exceptionToJSON("根据流程生产订单明细主键查询备料计划失败", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
PickmHeadVO pickmHeadVO = pickmHeadVOS.get(0);
// 获取当前head对应所有子项
String searchBodySql = "SELECT * FROM mm_pickm_b WHERE nvl(dr,0) = 0 AND CPICKMID = '" + pickmHeadVO.getCpickmid() + "'";
List<PickmItemVO> existingPickmItemVOS = (List<PickmItemVO>) BASE_DAO.executeQuery(searchBodySql, new BeanListProcessor(PickmItemVO.class));
if (existingPickmItemVOS == null || existingPickmItemVOS.isEmpty()) {
return ResultMessageUtil.exceptionToJSON("未找到对应的备料计划明细pk_pmo: " + pk_pmo, APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 收集所有materials并按物料编码分组
Map<String, List<Map<String, Object>>> materialGroups = new HashMap<>();
for (Map<String, Object> pmoItem : pmoItems) {
List<Map<String, Object>> materials = (List<Map<String, Object>>) pmoItem.get("materials");
if (MMCollectionUtil.isEmpty(materials)) {
return ResultMessageUtil.exceptionToJSON("传入数据异常参数要包含materials", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
for (Map<String, Object> material : materials) {
String cbmaterialvid = (String) material.get("cbmaterialvid");
String isvirtual = (String) material.get("isvirtual");
if (cbmaterialvid == null || isvirtual == null) {
return ResultMessageUtil.exceptionToJSON("传入数据异常material要包含cbmaterialvid和isvirtual", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
materialGroups.computeIfAbsent(cbmaterialvid, k -> new ArrayList<>()).add(material);
}
}
// 处理每个物料组
for (Map.Entry<String, List<Map<String, Object>>> materialEntry : materialGroups.entrySet()) {
String materialCode = materialEntry.getKey();
List<Map<String, Object>> materialItems = materialEntry.getValue();
// 将物料编码转换为主键
String materialPk = transferPkByCode(MaterialVO.getDefaultTableName(), MaterialVO.PK_MATERIAL, MaterialVO.CODE, materialCode);
// 查询该物料对应的所有备料计划明细
List<PickmItemVO> materialPickmItems = new ArrayList<>();
for (PickmItemVO item : existingPickmItemVOS) {
if (materialPk.equals(item.getCbmaterialvid())) {
materialPickmItems.add(item);
}
}
if (materialPickmItems.isEmpty()) {
logger.info("未找到物料编码 " + materialCode + " 对应的备料计划明细");
return ResultMessageUtil.exceptionToJSON("未找到物料编码 " + materialCode + " 对应的备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 判断删除逻辑
if (materialItems.size() == 1) {
// 删除单个物料明细
Map<String, Object> material = materialItems.get(0);
String isvirtual = (String) material.get("isvirtual");
if (materialPickmItems.size() == 1) {
// 只有一个明细直接删除
materialPickmItems.get(0).setStatus(VOStatus.DELETED);
} else if (materialPickmItems.size() == 2) {
// 有两个明细根据isvirtual判断删除哪个
if ("N".equals(isvirtual)) {
// 删除实项通过BOM逻辑查找
PickmItemVO realItem = findRealItemByBOM(materialPickmItems, pmoItemVO, materialPk);
if (realItem != null) {
realItem.setStatus(VOStatus.DELETED);
} else {
return ResultMessageUtil.exceptionToJSON("未找到对应的实项备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
} else if ("Y".equals(isvirtual)) {
// 删除虚项通过排除法查找
PickmItemVO realItem = findRealItemByBOM(materialPickmItems, pmoItemVO, materialPk);
PickmItemVO virtualItem = null;
for (PickmItemVO item : materialPickmItems) {
if (!item.equals(realItem)) {
virtualItem = item;
break;
}
}
if (virtualItem != null) {
virtualItem.setStatus(VOStatus.DELETED);
} else {
return ResultMessageUtil.exceptionToJSON("未找到对应的虚项备料计划明细", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
}
}
} else if (materialItems.size() == 2) {
// 删除两个明细验证必须包含一个实项和一个虚项
boolean hasReal = false;
boolean hasVirtual = false;
for (Map<String, Object> material : materialItems) {
String isvirtual = (String) material.get("isvirtual");
if ("N".equals(isvirtual)) {
hasReal = true;
} else if ("Y".equals(isvirtual)) {
hasVirtual = true;
}
}
if (!hasReal || !hasVirtual) {
return ResultMessageUtil.exceptionToJSON("删除重复物料组必须包含一个实项(isvirtual=N)和一个虚项(isvirtual=Y)", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
// 删除该物料的所有明细
for (PickmItemVO item : materialPickmItems) {
item.setStatus(VOStatus.DELETED);
}
} else {
return ResultMessageUtil.exceptionToJSON("同一物料编码的删除项数量不能超过2个", APIErrCodeEnum.BUSINESSEXCCODE.getCode());
}
}
// 设置未删除的明细状态为更新
for (PickmItemVO item : existingPickmItemVOS) {
if (item.getStatus() != VOStatus.DELETED) {
item.setStatus(VOStatus.UPDATED);
}
}
PickmItemVO[] array = existingPickmItemVOS.toArray(new PickmItemVO[0]);
AggPickmVO aggPickmVO = new AggPickmVO();
aggPickmVO.setParent(pickmHeadVO);
aggPickmVO.getParentVO().setStatus(VOStatus.UPDATED);
aggPickmVO.setChildren(PickmItemVO.class, array);
this.setDefaultValue(aggPickmVO);
resultAggVOList.add(aggPickmVO);
}
if (!resultAggVOList.isEmpty()) {
serv.update(resultAggVOList.toArray(new AggPickmVO[0]));
}
logger.info("备料计划明细行删除成功");
return ResultMessageUtil.toJSON(new String[0], "备料计划明细行删除成功");
} catch (Exception e) {
logger.error("备料计划明细行删除异常", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
/**
* 通过BOM逻辑查找实项isvirtual=N对应的明细
*/
private PickmItemVO findRealItemByBOM(List<PickmItemVO> materialPickmItems, PMOItemVO pmoItemVO, String materialPk) throws BusinessException {
try {
// 查询BOM信息
String bomSql = "cbmaterialvid = '" + pmoItemVO.getCmaterialvid() + "' and vbbomversionnumber = '" + pmoItemVO.getVbomversion() + "'";
BomVO bomHeadVO = (BomVO) BASE_DAO.retrieveByClause(BomVO.class, bomSql);
if (bomHeadVO == null) {
return null;
}
String bombSql = BomVO.CBOMID + " = '" + bomHeadVO.getCbomid() + "'";
List<BomItemVO> bomItemVOS = (List<BomItemVO>) BASE_DAO.retrieveByClause(BomItemVO.class, bombSql);
// 先检查BOM表头
String hcmaterialvid = bomHeadVO.getHcmaterialvid();
UFBoolean hisvirtual = bomHeadVO.getHisvirtual();
if (hcmaterialvid != null && hisvirtual != null &&
hcmaterialvid.equals(materialPk) && !hisvirtual.booleanValue()) {
for (PickmItemVO item : materialPickmItems) {
if (bomHeadVO.getCbomid().equals(item.getCbombid())) {
return item;
}
}
}
// 如果表头没找到查找BOM明细
for (BomItemVO bomItemVO : bomItemVOS) {
if (bomItemVO != null) {
String cmaterialvid = bomItemVO.getCmaterialvid();
UFBoolean bisvirtual = bomItemVO.getBisvirtual();
if (cmaterialvid != null && bisvirtual != null &&
cmaterialvid.equals(materialPk) && !bisvirtual.booleanValue()) {
for (PickmItemVO item : materialPickmItems) {
if (bomItemVO.getCbom_bid().equals(item.getCbombid())) {
return item;
}
}
}
}
}
return null;
} catch (Exception e) {
logger.error("查找实项明细异常", e);
return null;
}
}
/**
* 将请求参数转换为PickmHeadVO
*/
public static PickmHeadVO transferToPickmHeadVO(Map<String, Object> row, Integer type) throws BusinessException {
if (row == null) {
throw new BusinessException("根据pk_pmo未查询出相关流程备料计划");
}
PickmHeadVO pickmHeadVO = new PickmHeadVO();
pickmHeadVO.setPk_group(AppContext.getInstance().getPkGroup());
pickmHeadVO.setStatus(type);
for (String key : row.keySet()) {
pickmHeadVO.setAttributeValue(key, row.get(key));
}
return pickmHeadVO;
}
/**
* 将请求参数mm_pickm_b数组中的每一个个体转换为PickmItemVO个体
*/
public static PickmItemVO transferToPickmItemVO(Map<String, Object> pickmBody, Integer type) throws BusinessException {
PickmItemVO body = new PickmItemVO();
for (String key : pickmBody.keySet()) {
body.setAttributeValue(key, pickmBody.get(key));
}
body.setStatus(type);
return body;
}
private void setDefaultValue(AggPickmVO vo) {
String pk = vo.getParentVO().getCpickmid();
for (PickmItemVO item : (PickmItemVO[]) vo.getChildrenVO()) {
if (2 == item.getStatus()) {
item.setCpickmid(pk);
item.setCpickm_bid((String) null);
}
}
}
/**
* 根据编码查询主键
*/
private String transferPkByCode(String tableName, String selectField, String codeField, String code) throws BusinessException {
if (code == null || code.trim().isEmpty()) {
return null;
}
SqlBuilder sqlBuilder = new SqlBuilder();
sqlBuilder.append(" select " + selectField);
sqlBuilder.append(" from " + tableName);
sqlBuilder.append(" where ");
sqlBuilder.append(codeField, code);
Object o = BASE_DAO.executeQuery(sqlBuilder.toString(), new ColumnProcessor());
if (o == null) {
throw new BusinessException("未查询到主键信息sql【" + sqlBuilder + "");
}
return o.toString();
}
// transferSingleDataCodeToPk
private Map<String, Object> transferSingleDataCodeToPk(Map<String, Object> singleData) throws BusinessException {
// 1. 创建新 Map复制原始数据浅拷贝
Map<String, Object> newData = new HashMap<>(singleData);
// 2. 只修改需要的字段其他字段保持不变
String org_code = transferPkByCode(OrgVO.getDefaultTableName(), OrgVO.PK_ORG, OrgVO.CODE, (String) singleData.get("pk_org"));
newData.put("pk_org", org_code); // 修改新 Map不影响原 Map
String group_code = transferPkByCode(GroupVO.getDefaultTableName(), GroupVO.PK_GROUP, GroupVO.CODE, (String) singleData.get("pk_group"));
newData.put("pk_group", group_code);
String csupplyorgvidcode = transferPkByCode(StockOrgVersionVO.getDefaultTableName(), StockOrgVersionVO.PK_VID, StockOrgVersionVO.CODE, (String) singleData.get("csupplyorgvid"));
newData.put("csupplyorgvid", csupplyorgvidcode);
String cbmaterialvidcode = transferPkByCode(MaterialVO.getDefaultTableName(), MaterialVO.PK_MATERIAL, MaterialVO.CODE, (String) singleData.get("cbmaterialvid"));
newData.put("cbmaterialvid", cbmaterialvidcode);
String cdeliverorgvidcode = transferPkByCode(StockOrgVersionVO.getDefaultTableName(), StockOrgVersionVO.PK_VID, StockOrgVersionVO.CODE, (String) singleData.get("cdeliverorgvid"));
newData.put("cdeliverorgvid", cdeliverorgvidcode);
String cdeliverorgidcode = transferPkByCode(StockOrgVO.getDefaultTableName(), StockOrgVO.PK_STOCKORG, StockOrgVO.CODE, (String) singleData.get("cdeliverorgid"));
newData.put("cdeliverorgid", cdeliverorgidcode);
String cbunitidcode = transferPkByCode(MeasdocVO.getDefaultTableName(), MeasdocVO.PK_MEASDOC, MeasdocVO.CODE, (String) singleData.get("cbunitid"));
newData.put("cbunitid", cbunitidcode);
return newData;
}
public String getModule() {
return "mmpac";
}
}