预留功能

This commit is contained in:
lihao 2026-02-06 10:02:56 +08:00
parent dd1fb2158b
commit 9b00072073
3 changed files with 292 additions and 0 deletions

View File

@ -0,0 +1,275 @@
package nccloud.web.setanalysis.action;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.impl.pubapp.pattern.data.vo.VOUpdate;
import nc.itf.ic.reserve.IReserveAssist;
import nc.itf.ic.reserve.IReserveMaintenance;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.ic.reserve.entity.OnhandReserveVO;
import nc.vo.ic.reserve.entity.PreReserveVO;
import nc.vo.ic.reserve.entity.ReserveBillVO;
import nc.itf.mmpac.pickm.IPickmQueryService;
import nc.itf.mmpub.setanalysis.ISaMatchService;
import nc.pubitf.uapbd.IMaterialPubService;
import nc.util.mmf.framework.base.MMArrayUtil;
import nc.util.mmf.framework.base.MMValueCheck;
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.PMOItemVO;
import nc.vo.mmpub.setanalysis.entity.AggAnalysisVO;
import nc.vo.mmpub.setanalysis.entity.SaDemandVO;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nccloud.framework.core.exception.BusinessException;
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 nc.vo.ic.reserve.entity.ReserveVO;
/**
* @Description: 自动预留功能
* @Author: zhangxinah
* @Date: 2025/11/9 14:30
*/
public class AnalysisAutoReserveAction implements ICommonAction {
public Object doAction(IRequest request) {
String read = request.read();
IJson json = JsonFactory.create();
Map<String, Map<String, Object>> paramMap = (Map) json.fromJson(read, Map.class);
ArrayList<?> list = (ArrayList<?>) paramMap.get("model").get("rows");
ArrayList<String> pkList = new ArrayList<String>();
String pk_org = "";
for (int i = 0; i < list.size(); i++) {
Map<String, Map<String, Object>> map = (Map<String, Map<String, Object>>) list.get(i);
Map<String, String> value = (Map<String, String>) map.get("values").get("pk_analysis");
String pk_analysi = value.get("value");
Map<String, String> orgvalue = (Map<String, String>) map.get("values").get("pk_demandorg");
pk_org = orgvalue.get("value");
pkList.add(pk_analysi);
}
List<String> resultList = new ArrayList<String>();
String[] pk_analysiss = pkList.toArray(new String[pkList.size()]);
List<PMOItemVO> successList = new ArrayList<PMOItemVO>();
IPickmQueryService service = ServiceLocator.find(IPickmQueryService.class);
List<String> materialList = new ArrayList<>();
try {
materialList = getNotNeedReserveMaterial(pk_org);
} catch (nc.vo.pub.BusinessException e) {
throw new BusinessException("查询不需要预留的物料时报错!" + e.getMessage());
}
if (MMValueCheck.isNotEmpty(pk_analysiss)) {
for (String pk_analysis : pk_analysiss) {
AggAnalysisVO agg = ((ISaMatchService) ServiceLocator.find(ISaMatchService.class))
.queryBodyDataByID4NCC(pk_analysis, "2");
// 查询齐套分析-材料匹配明细
SaDemandVO[] saDemandVOs = (SaDemandVO[]) agg.getChildren(SaDemandVO.class);
if (saDemandVOs == null || saDemandVOs.length == 0) {
throw new BusinessException("请先进行齐套分析!");
}
// 生产订单表体主键
String vsrcbid = saDemandVOs[0].getVsrcbid();
PMOItemVO itemvo = null;
try {
itemvo = (PMOItemVO) new BaseDAO().retrieveByPK(PMOItemVO.class, vsrcbid);
} catch (DAOException e) {
throw new BusinessException("查询齐套分析对象报错!");
}
if (itemvo == null || "Y".equals(itemvo.getVdef9())) {
continue;
}
int count = 0;
// 遍历进行预留功能
for (SaDemandVO vo : saDemandVOs) {
if (vo.getNremainnum().compareTo(UFDouble.ZERO_DBL) != 0) {
continue;
}
String vdemandcode = vo.getVdemandcode();
// 生产订单表体主键
String vdemandrowno = vo.getVdemandrowno();
// 根据自定义档案-业务单元GY_BYLWL判断物料是否需要预留
if (materialList != null && materialList.contains(vo.getCmaterialid())) {
resultList.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,已在档案里配置了不需要进行预留!");
continue;
}
// 预留功能处理逻辑
// 需求单据主键
String cdemandbillid = vo.getCdemandbillid();
// 需求单据明细主键
String cdemandbillbid = vo.getCdemandbillbid();
// 查询备料计划
AggPickmVO aggPickmVO = null;
try {
aggPickmVO = service.querySingleBillByPk(cdemandbillid);
if (aggPickmVO != null) {
PickmItemVO pickmItemVO = service.queryPickmItemByPK(cdemandbillbid);
if (pickmItemVO == null) {
resultList.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,未查询到对应的备料计划。");
continue;
}
if (pickmItemVO != null) {
// TODO: 处理备料计划明细数据
// 现存量查询
ReserveVO reserveVO = buildReserVO(aggPickmVO.getParentVO(), pickmItemVO);
ReserveBillVO[] reserveBillVO = ((IReserveAssist) ServiceLocator
.find(IReserveAssist.class)).allocReserve(new ReserveVO[] { reserveVO });
OnhandReserveVO[] reserveVos = (OnhandReserveVO[]) reserveBillVO[0]
.getChildren(OnhandReserveVO.class);
if (reserveVos == null) {
resultList
.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,预留失败,原因是:现存量不足!");
continue;
}
// 处理预留数量
reserveBillVO = dealReservoNum(reserveBillVO, pickmItemVO);
try {
ReserveBillVO[] resultvos = ServiceLocator.find(IReserveMaintenance.class)
.insert(reserveBillVO);
// 后续业务如何处理
if (MMArrayUtil.isNotEmpty(resultvos)) {
count++;
// 预留单号
String vrescode = (String) resultvos[0].getParentVO()
.getAttributeValue("vrescode");
resultList.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,已自动预留,预留单号:"
+ vrescode);
}
} catch (Exception e) {
resultList
.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,预留失败,原因是:现存量不足!");
}
}
}
} catch (Exception e) {
resultList
.add("需求单据号:" + vdemandcode + ", 行号:" + vdemandrowno + " ,预留失败,原因是:" + e.getMessage());
}
}
if (count > 0) {
if (saDemandVOs.length == count) {
// 查询生产订单表体
itemvo.setVdef9("全部预留");
} else {
itemvo.setVdef9("部分预留");
}
successList.add(itemvo);
}
}
}
if (successList != null && successList.size() > 0) {
new VOUpdate<>().update(successList.toArray(new PMOItemVO[successList.size()]), new String[] { "vdef9" });
}
String resultMst = String.join("\n", resultList);
return resultMst;
}
private List<String> getNotNeedReserveMaterial(String pk_org) throws nc.vo.pub.BusinessException {
String sql = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='GY_BYLWL') and nvl(dr,0)=0 ";
List<DefdocVO> list = (List<DefdocVO>) new BaseDAO().retrieveByClause(DefdocVO.class, sql);
List<String> materialClassList = new ArrayList<String>();
List<String> materialList = new ArrayList<String>();
if (MMValueCheck.isNotEmpty(list)) {
for (DefdocVO vo : list) {
if (vo.getDef1() != null && vo.getDef1().length() > 10) {
materialClassList.add(vo.getDef1());
}
if (vo.getDef2() != null && vo.getDef2().length() > 10) {
materialList.add(vo.getDef2());
}
}
}
IMaterialPubService service = ServiceLocator.find(IMaterialPubService.class);
if (MMValueCheck.isNotEmpty(materialClassList)) {
Map<String, List<String>> materialMap = service
.queryMaterialOidByBaseClass(materialClassList.toArray(new String[0]));
if (MMValueCheck.isNotEmpty(materialMap)) {
// 2. 流式编程合并所有字符串到一个 List
List<String> resultList = materialMap.values() // 第一步获取所有的 List<String>
.stream() // 第二步 Collection 转换为 Stream
.flatMap(List::stream) // 第三步扁平化处理 Stream<List<String>> 转为 Stream<String>
.collect(Collectors.toList()); // 第四步 Stream<String> 收集为 List<String>
materialList.addAll(resultList);
}
}
return materialList;
}
/**
* 根据维护的自定义档案判断物料是否需求参与预留
*
* @param pk_org
* @param cmaterialid
* @return
*/
private boolean checkNeedReserve(String pk_org, String cmaterialid) {
// TODO Auto-generated method stub
return false;
}
private ReserveBillVO[] dealReservoNum(ReserveBillVO[] reserveBillVO, PickmItemVO pickmItemVO) {
if (reserveBillVO != null && reserveBillVO.length > 0) {
for (ReserveBillVO billVO : reserveBillVO) {
// 遍历处理每个ReserveBillVO
billVO.getParentVO().setAttributeValue("nrsnum", pickmItemVO.getNplanoutnum());
// billVO.getParentVO().setAttributeValue("ntalrsnum",
// pickmItemVO.getNplanoutastnum());
billVO.getParentVO().setAttributeValue("nreqnum", pickmItemVO.getNplanoutastnum());
OnhandReserveVO[] reserveVos = (OnhandReserveVO[]) billVO.getChildren(OnhandReserveVO.class);
if (reserveVos == null) {
continue;
}
for (OnhandReserveVO reserveVO : reserveVos) {
reserveVO.setNrsnum(pickmItemVO.getNplanoutnum());
}
PreReserveVO[] prereserveVos = (PreReserveVO[]) billVO.getChildren(PreReserveVO.class);
if (prereserveVos != null) {
billVO.setChildren(PreReserveVO.class, new PreReserveVO[] {});
}
}
}
return reserveBillVO;
}
private ReserveVO buildReserVO(PickmHeadVO pickmHeadVO, PickmItemVO pickmItemVO) {
ReserveVO reserveVO = new ReserveVO();
reserveVO.setPk_group(pickmHeadVO.getPk_group());
reserveVO.setPk_org(pickmHeadVO.getPk_org());
reserveVO.setPk_org_v(pickmHeadVO.getPk_org_v());
reserveVO.setVreqbillcode(pickmHeadVO.getVbillcode());
reserveVO.setCmaterialoid(pickmItemVO.getCbmaterialid());
reserveVO.setCmaterialvid(pickmItemVO.getCbmaterialvid());
reserveVO.setCreqbillid(pickmHeadVO.getPrimaryKey());
reserveVO.setCreqbillbid(pickmItemVO.getPrimaryKey());
reserveVO.setCreqbilltype("55A3");
reserveVO.setCreqbillrowno(pickmItemVO.getVrowno());
reserveVO.setCreqtranstype(pickmHeadVO.getVbusitypeid());
reserveVO.setCunitid(pickmItemVO.getCbastunitid());
reserveVO.setCwarehouseid(pickmItemVO.getCoutstockid());
reserveVO.setDreqdate(new UFDate());
reserveVO.setFreservetype(1);
reserveVO.setFresstate(1);
// 计划出库主数量
reserveVO.setNrsnum(pickmItemVO.getNplanoutnum());
reserveVO.setNreqnum(pickmItemVO.getNplanoutnum());
// 计划出库数量
reserveVO.setNtalrsnum(pickmItemVO.getNplanoutastnum());
reserveVO.setReqbillrowts(pickmItemVO.getTs());
return reserveVO;
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<actions>
<action>
<name>mmpub.setanalysis.autoreserve</name>
<label>齐套分析自动预留</label>
<clazz>nccloud.web.setanalysis.action.AnalysisAutoReserveAction</clazz>
</action>
</actions>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<authorizes>
<authorize>
<appcode>*</appcode>
<actions>
<action>mmpub.setanalysis.autoreserve</action>
</actions>
</authorize>
</authorizes>