ic_自动拣货根据拣货拆行

This commit is contained in:
李正@用友 2025-04-10 09:45:27 +08:00
parent 56e0d88e55
commit d21223789f
4 changed files with 3254 additions and 0 deletions

View File

@ -0,0 +1,872 @@
package nc.bs.ic.onhand.action;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.pub.db.SqlIn;
import nc.bs.ic.pub.env.ICBSContext;
import nc.itf.scmpub.reference.uap.group.SysInitGroupQuery;
import nc.pubitf.ic.onhand.IOnhandQry;
import nc.vo.ic.location.ICLocationVO;
import nc.vo.ic.material.define.InvBasVO;
import nc.vo.ic.material.define.InvMeasVO;
import nc.vo.ic.onhand.define.BalanceOnhandRes;
import nc.vo.ic.onhand.define.ICBillOnhandReq;
import nc.vo.ic.onhand.define.IOnhandReq;
import nc.vo.ic.onhand.define.OnhandBalanceResult;
import nc.vo.ic.onhand.define.OnhandRes;
import nc.vo.ic.onhand.entity.OnhandDimVO;
import nc.vo.ic.onhand.entity.OnhandNumVO;
import nc.vo.ic.onhand.entity.OnhandSNVO;
import nc.vo.ic.onhand.entity.OnhandSNViewVO;
import nc.vo.ic.onhand.entity.OnhandVO;
import nc.vo.ic.onhand.pub.OnhandQryCond;
import nc.vo.ic.onhand.pub.OnhandVOTools;
import nc.vo.ic.pub.calc.BusiCalculator;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.ic.pub.sql.SqlUtil;
import nc.vo.ic.pub.util.CollectionUtils;
import nc.vo.ic.pub.util.DimMatchUtil;
import nc.vo.ic.pub.util.NCBaseTypeUtils;
import nc.vo.ic.pub.util.StringUtil;
import nc.vo.ic.pub.util.VOEntityUtil;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.commons.lang.ArrayUtils;
/**
* <p>
* <b>结存资源平衡</b>
* <ul>
* <li>捡货的现存量处理分配
* <li>预留的现存量分配
* </ul>
* <p>
* <b>变更历史</b>
* <p>
*
* @version v60
* @since v60
* @author yangb
* @time 2010-4-10 下午02:13:20
*/
public class OnhandResBalance<T extends IOnhandReq> implements ResAlloc {
private BusiCalculator calculator;
// 使用交易类型作为结存的过滤条件
private List<String> ctranstypes;
// 分配结果
private Map<T, OnhandBalanceResult<T>> mapResults;
// // 分配结果
// private Map<T, List<OnhandSNViewVO>> mapSnResults;
// 现有的结存
private Map<String, OnhandVO> mapyethandvo;
// 需求对象
private T[] onhandReq;
// 序列号需求对象
private T[] onhandSNReq;
private OnhandResManager onhandres;
// 需求与结存资源的匹配器
private DimMatchUtil<T> reqsmatch;
private String[] onhandSNDimFields = new String[] {
OnhandDimVO.PK_GROUP, OnhandDimVO.PK_ORG,
OnhandDimVO.CWAREHOUSEID, OnhandDimVO.CMATERIALVID, OnhandDimVO.CMATERIALOID,
OnhandDimVO.CASTUNITID, OnhandDimVO.PK_BATCHCODE, OnhandDimVO.CVMIVENDERID,
OnhandDimVO.CINVCUSTID, OnhandDimVO.CSTATEID, OnhandDimVO.CVENDORID,
OnhandDimVO.CPROJECTID, OnhandDimVO.CASSCUSTID, OnhandDimVO.CPRODUCTORID,
OnhandDimVO.CFFILEID, OnhandDimVO.VFREE1, OnhandDimVO.VFREE2,
OnhandDimVO.VFREE3, OnhandDimVO.VFREE4, OnhandDimVO.VFREE5,
OnhandDimVO.VFREE6, OnhandDimVO.VFREE7, OnhandDimVO.VFREE8,
OnhandDimVO.VFREE9, OnhandDimVO.VFREE10
};
/**
* zhengxinm 处理序列号拣货没有查不到数据的问题 去掉批次属性 志强用的是上面的
*/
private String[] onhandSNDimFieldsWithoutBatch = new String[] {
OnhandDimVO.PK_GROUP, OnhandDimVO.PK_ORG,
OnhandDimVO.CWAREHOUSEID, OnhandDimVO.CMATERIALVID, OnhandDimVO.CMATERIALOID,
OnhandDimVO.CASTUNITID, OnhandDimVO.CVMIVENDERID,
OnhandDimVO.CINVCUSTID, OnhandDimVO.CSTATEID, OnhandDimVO.CVENDORID,
OnhandDimVO.CPROJECTID, OnhandDimVO.CASSCUSTID, OnhandDimVO.CPRODUCTORID,
OnhandDimVO.CFFILEID, OnhandDimVO.VFREE1, OnhandDimVO.VFREE2,
OnhandDimVO.VFREE3, OnhandDimVO.VFREE4, OnhandDimVO.VFREE5,
OnhandDimVO.VFREE6, OnhandDimVO.VFREE7, OnhandDimVO.VFREE8,
OnhandDimVO.VFREE9, OnhandDimVO.VFREE10
};
/**
* OnhandResBalance 的构造子
*/
public OnhandResBalance(T[] reqs) {
this.onhandReq = reqs;
this.calculator = BusiCalculator.getBusiCalculatorAtBS();
}
/**
* 赋予资源 return true ---表示该资源已能满足需求, 或明细已经超过当前结存,无需继续搜索
*/
@Override
public boolean assignRes(OnhandRes handres) {
List<T> lreqs = this.reqsmatch.searchMatchedDimObj(handres, -1);
if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
return true;
}
boolean byetoverhand = this.processResDataForHand(handres);
OnhandBalanceResult<T> balancerow = null;
int ireqs = lreqs.size();
for (T req : lreqs) {
balancerow = this.mapResults.get(req);
if (balancerow == null) {
balancerow = new OnhandBalanceResult<T>(req);
this.mapResults.put(req, balancerow);
}
// 如果调用balancerow.isFull() 辅单位不记结存的情况下存量辅数量为空或0会认为没有满足,改为调用balancerow.isFull(boolean,boolean,boolean)
boolean isNumAssign = handres.isNumUseable();
boolean isAstNumAssign = handres.isAstnumUseable();
boolean isGrossNumAssign = handres.isGrossnumUseable();
this.assignRes(balancerow, handres);
if (balancerow.isFull(isNumAssign, isAstNumAssign, isGrossNumAssign)) {
this.reqsmatch.remoteMatchedDimObj(req);
ireqs--;
}
if (!handres.isUseable()) {
break;
}
}
if (byetoverhand) {
return true;
}
if (ireqs <= 0) {
return true;
}
return false;
}
/**
* 方法功能描述获取平衡结果 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
public OnhandBalanceResult<T> getResults(T req) {
if (this.mapResults == null) {
return null;
}
return this.mapResults.get(req);
}
/**
* 方法功能描述现存量平衡计算 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
public void onhandBalance() {
// 检查数据
this.processData();
// add by wangceb 序列号拣货 start
this.processAllocSNData();
// add by wangceb 序列号拣货 end
if (ValueCheckUtil.isNullORZeroLength(this.onhandReq)
|| this.reqsmatch == null) {
return;
}
if (ValueCheckUtil.isNullORZeroLength(this.mapyethandvo)) {
return;
}
OnhandVO[] handvos =
this.mapyethandvo.values().toArray(
new OnhandVO[this.mapyethandvo.size()]);
// 分配明细
this.getOnhandRes().matchRes(handvos, this);
// 分配单品
this.allocSn(handvos);
}
/**
* @param ctranstype 要设置的 ctranstype
*/
public void setCtranstype(List<String> ctranstypes) {
this.ctranstypes = ctranstypes;
}
/**
* 分配单品,基于已分配结存的结果
*/
private void allocSn(OnhandVO[] handvos) {
if (ValueCheckUtil.isNullORZeroLength(handvos)
|| ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
return;
}
Set<String> onhandpks =
VOEntityUtil.getVOsValueSet(handvos, OnhandDimVO.PK_ONHANDDIM);
// 查询单品资源
List<String>[] ls = this.getOuttrackinOnhandRes();
if (!ValueCheckUtil.isNullORZeroLength(ls)
&& !ValueCheckUtil.isNullORZeroLength(ls[0])) {
this.getOnhandRes().loadSNRes(handvos,
ls[0].toArray(new String[ls[0].size()]),
ls[1].toArray(new String[ls[1].size()]));
}
else {
this.getOnhandRes().loadSNRes(handvos, null, null);
}
OnhandSNVO[] snvos = null;
for (OnhandBalanceResult<T> rts : this.mapResults.values()) {
if (rts.getResults() == null) {
continue;
}
for (BalanceOnhandRes res : rts.getResults()) {
// 待处理存量主键如果不含资源中的存量主键说明已经处理不再处理
if (res.getNastnum() == null
|| !onhandpks.contains(res.getOnhanddimvo().getPk_onhanddim())) {
continue;
}
// 单品
snvos = this.getOnhandRes().getSNRes(res.getOnhanddimvo(),
res.getCgeneralbid(), res.getNastnum().intValue());
res.addSnVo(snvos);
}
}
}
/**
* 方法功能描述分配计算 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
private void assignRes(OnhandBalanceResult<T> balance, OnhandRes res) {
if (!res.isUseable()) {
return;
}
UFDouble dtemp = null;
BalanceOnhandRes balanceres = new BalanceOnhandRes(res);
// //单品
// OnhandSNVO[] snvos = getOnhandRes().getSNRes(res.getOnhanddimvo(),
// res.getCgeneralbid(),
// balance.getNreqnum().intValue());
// balanceres.addSnVo(snvos);
if (res.isNumUseable()) {
dtemp = NCBaseTypeUtils.sub(res.getNuseablenum(), balance.getNreqnum());
if (NCBaseTypeUtils.isGtZero(dtemp)) {
balanceres.setNnum(balance.getNreqnum());
balance.setNreqnum(UFDouble.ZERO_DBL);
res.setNuseablenum(dtemp);
}
else {
balanceres.setNnum(res.getNuseablenum());
balance.setNreqnum(NCBaseTypeUtils.sub(balance.getNreqnum(), balanceres
.getNnum()));
res.setNuseablenum(UFDouble.ZERO_DBL);
}
}else{
balanceres.setNnum(UFDouble.ZERO_DBL);
}
if (res.isAstnumUseable()) {
dtemp =
NCBaseTypeUtils.sub(res.getNuseableastnum(), balance.getNreqastnum());
if (NCBaseTypeUtils.isGtZero(dtemp)) {
balanceres.setNastnum(balance.getNreqastnum());
balance.setNreqastnum(UFDouble.ZERO_DBL);
res.setNuseableastnum(dtemp);
}
else {
balanceres.setNastnum(res.getNuseableastnum());
balance.setNreqastnum(NCBaseTypeUtils.sub(balance.getNreqastnum(),
balanceres.getNastnum()));
res.setNuseableastnum(UFDouble.ZERO_DBL);
}
}else{
balanceres.setNastnum(UFDouble.ZERO_DBL);
}
if (res.isGrossnumUseable()) {
dtemp =
NCBaseTypeUtils.sub(res.getNuseablegrossnum(), balance
.getNreqgrossnum());
if (NCBaseTypeUtils.isGtZero(dtemp)) {
balanceres.setNgrossnum(balance.getNreqgrossnum());
balance.setNreqgrossnum(UFDouble.ZERO_DBL);
res.setNuseablegrossnum(dtemp);
}
else {
balanceres.setNgrossnum(res.getNuseablegrossnum());
balance.setNreqgrossnum(NCBaseTypeUtils.sub(balance.getNreqgrossnum(),
balanceres.getNgrossnum()));
res.setNuseablegrossnum(UFDouble.ZERO_DBL);
}
}else{
balanceres.setNgrossnum(UFDouble.ZERO_DBL);
}
balance.addBalanceOnhandRes(balanceres);
}
/**
* 方法功能描述过滤需求 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
@SuppressWarnings("unchecked")
private void filterReqsData() {
if (ValueCheckUtil.isNullORZeroLength(this.onhandReq)) {
return;
}
List<T> datas = new ArrayList<T>();
List<T> sndatas = new ArrayList<T>();
for (T req : this.onhandReq) {
if (req == null) {
continue;
}
if (req.getOnhandDim() == null) {
continue;
}
if (req.getOnhandDim().getPk_org() == null
|| req.getOnhandDim().getCmaterialvid() == null
|| req.getOnhandDim().getCmaterialoid() == null) {
continue;
}
if (NCBaseTypeUtils.isNullOrZero(req.getReqNum())
&& NCBaseTypeUtils.isNullOrZero(req.getReqAssistNum())
&& NCBaseTypeUtils.isNullOrZero(req.getReqGrossNum())) {
continue;
}
if (this.isNeedSearchSN(req)) {
sndatas.add(req);
// continue;
}
datas.add(req);
}
if (datas.size() > 0) {
T[] arrtemp =
(T[]) Array.newInstance(datas.get(0).getClass(), datas.size());
this.onhandReq = datas.toArray(arrtemp);
} else {
this.onhandReq = null;
}
if (sndatas.size() > 0) {
T[] arrtemp =
(T[]) Array.newInstance(sndatas.get(0).getClass(), sndatas.size());
this.onhandSNReq = sndatas.toArray(arrtemp);
}
}
/**
* 孙表录入序列号且序列号数量与应发数量相同
* @param req
* @return
*/
private boolean isNeedSearchSN(T req) {
ICLocationVO[] locationvos = req.getLocationVOs();
if (ValueCheckUtil.isNullORZeroLength(locationvos)) {
return false;
}
String key = SysInitGroupQuery.isSNEnabled() ? ICPubMetaNameConst.PK_SERIALCODE : ICPubMetaNameConst.VSERIALCODE;
String[] snvalues = VOEntityUtil.getVOsValuesNotDel(locationvos, key, String.class);
if (StringUtil.isSEmptyOrNullForAll(snvalues)) {
return false;
}
// if (NCBaseTypeUtils.isNullOrZero(req.getReqAssistNum()) || snvalues.length != req.getReqAssistNum().intValue()) {
// return false;
// }
return true;
}
/**
* 方法功能描述获取现存量资源 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
private OnhandResManager getOnhandRes() {
if (this.onhandres == null) {
this.onhandres = new OnhandResManager();
if (!ValueCheckUtil.isNullORZeroLength(this.ctranstypes)) {
this.onhandres.setCtranstype(this.ctranstypes);
}
}
return this.onhandres;
}
/**
* 获取出库跟踪入库的入库单明细
*/
@SuppressWarnings("unchecked")
private List<String>[] getOuttrackinOnhandRes() {
if (ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
return null;
}
List<String> listbid = new ArrayList<String>();
List<String> listbilltype = new ArrayList<String>();
String cgeneralbid = null;
for (OnhandBalanceResult<T> rts : this.mapResults.values()) {
if (rts.getResults() == null) {
continue;
}
for (BalanceOnhandRes res : rts.getResults()) {
cgeneralbid = res.getCgeneralbid();
if (cgeneralbid == null) {
continue;
}
if (listbid.contains(cgeneralbid)) {
continue;
}
listbid.add(cgeneralbid);
listbilltype.add(res.getCbilltype());
}
}
if (listbid.size() <= 0) {
return null;
}
return new List[] {
listbilltype, listbid
};
}
/**
* 方法功能描述 预分配现存量资源,对于: (先进先出,后进先出) (出库跟踪入库) 的物料,<br>
* 可以直接根据现存量分配资源即可,<br>
* 不用继续查询单据明细,这样提高效率<br>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
private OnhandVO[] preAllocHandRes(OnhandVO[] handvos) {
if (ValueCheckUtil.isNullORZeroLength(handvos)) {
return handvos;
}
this.getOnhandRes().loadInv(handvos);
this.processNrsastnum(handvos);
List<OnhandVO> lrethandvos = new ArrayList<OnhandVO>();
List<OnhandVO> lprehandvos = new ArrayList<OnhandVO>();
for (OnhandVO handvo : handvos) {
if (NCBaseTypeUtils.isLEZero(OnhandVOTools.calcHandNum(handvo))
&& NCBaseTypeUtils.isLEZero(OnhandVOTools.calcHandAstNum(handvo))) {
continue;
}
if (this.getOnhandRes().isNeedSearchFlow(handvo.getPk_org(),
handvo.getCmaterialvid())) {
lrethandvos.add(handvo);
continue;
}
OnhandRes handres = new OnhandRes(handvo);
List<T> lreqs = this.reqsmatch.searchMatchedDimObj(handres, -1);
if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
continue;
}
OnhandBalanceResult<T> balancerow = null;
lprehandvos.add(handvo);
for (T req : lreqs) {
balancerow = this.mapResults.get(req);
if (balancerow == null) {
balancerow = new OnhandBalanceResult<T>(req);
this.mapResults.put(req, balancerow);
}
boolean isNumAssign=handres.isNumUseable();
boolean isAstNumAssign=handres.isAstnumUseable();
boolean isGrossNumAssign= handres.isGrossnumUseable();
this.assignRes(balancerow, handres);
if (balancerow.isFull(isNumAssign,isAstNumAssign,isGrossNumAssign)) {
this.reqsmatch.remoteMatchedDimObj(req);
}
if (!handres.isUseable()) {
break;
}
}
}
if (lprehandvos.size() > 0) {
this.allocSn(CollectionUtils.listToArray(lprehandvos));
}
return CollectionUtils.listToArray(lrethandvos);
}
/**
* 辅计量记结存的并且有预留存量的要重新计算预留辅数量否则拣货后单据辅数量错误
* @param handvos
*/
private void processNrsastnum(OnhandVO[] handvos){
Map<String, InvMeasVO> mapmeasInv =this.loadInvMeas(handvos);
if (ValueCheckUtil.isNullORZeroLength(mapmeasInv)) {
return ;
}
List<OnhandVO> reserveVOs = new ArrayList<OnhandVO>();
for (OnhandVO onhandVO : handvos) {
String key = onhandVO.getCmaterialvid()+onhandVO.getCastunitid();
InvMeasVO invmeasVO = mapmeasInv.get(key);
if(invmeasVO == null){
reserveVOs.add(onhandVO);
continue;
}
//辅单位计结存且预留数量不为空
if(ValueCheckUtil.isTrue(invmeasVO.getIsstorebalance())
&& !NCBaseTypeUtils.isNullOrZero(onhandVO.getNrsnum())){
reserveVOs.add(onhandVO);
}
}
if(ValueCheckUtil.isNullORZeroLength(reserveVOs)){
return;
}
// Map<String, InvBasVO> invvos =
// this.loadInvBas(reserveVOs.toArray(new OnhandVO[0]));
for (OnhandVO onhandVO : reserveVOs) {
// InvBasVO invvo = invvos.get(onhandVO.getCmaterialvid());
// if (invvo == null) {
// continue;
// }
// String cunitid = invvo.getPk_measdoc();
InvMeasVO invmeasvo =
mapmeasInv.get(onhandVO.getCmaterialvid() + onhandVO.getCastunitid());
if (invmeasvo == null) {
onhandVO.setNrsastnum(onhandVO.getNrsnum());
continue;
}
String convertRate = invmeasvo.getMeasrate();
String cunitid = invmeasvo.getPk_measdoc();
UFDouble nrsnum = onhandVO.getNrsnum();
onhandVO.setNrsastnum(this.calculator.calculateAstNum(nrsnum,
convertRate, cunitid));
}
}
/**
* 加载物料辅计量信息
*
* @param handvos
* @return
*/
private Map<String, InvMeasVO> loadInvMeas(OnhandVO[] handvos) {
Map<String, InvMeasVO> mapInv = new HashMap<String, InvMeasVO>();
if (handvos == null || handvos.length <= 0) {
return null;
}
ICBSContext con = new ICBSContext();
InvMeasVO[] invvos =
con.getInvInfo().getInvMeasVO(
VOEntityUtil.getVOsValues(handvos, OnhandDimVO.CMATERIALVID,
String.class),
VOEntityUtil.getVOsValues(handvos, OnhandDimVO.CASTUNITID,
String.class));
if (invvos == null) {
return null;
}
for (InvMeasVO invvo : invvos) {
if (invvo == null) {
continue;
}
mapInv.put(invvo.getPk_material() + invvo.getPk_measdoc(), invvo);
}
return mapInv;
}
/**
* 加载物料基本信息用于获取主单位
* @param handvos
* @return
*/
private Map<String, InvBasVO> loadInvBas(OnhandVO[] handvos) {
Map<String, InvBasVO> mapInv = new HashMap<String, InvBasVO>();
if (handvos == null || handvos.length <= 0) {
return null;
}
ICBSContext con = new ICBSContext();
InvBasVO[] invvos =
con.getInvInfo().getInvBasVO(
VOEntityUtil.getVOsValues(handvos, OnhandDimVO.CMATERIALVID,
String.class));
if (invvos == null) {
return null;
}
for (InvBasVO invvo : invvos) {
if (invvo == null) {
continue;
}
mapInv.put(invvo.getPk_material(), invvo);
}
return mapInv;
}
/**
* 根据序列号拣货
*/
private void processAllocSNData() {
if (ValueCheckUtil.isNullORZeroLength(onhandSNReq)) {
return;
}
for (T req : onhandSNReq) {
// 取得所有查询key -- 序列号或者pk
Set<String> llist = this.getAllSNValues(req);
// 查询序列号结存
OnhandSNViewVO[] snvos = this.queryOnhandSNs(llist, req);
if (ValueCheckUtil.isNullORZeroLength(snvos)) {
return;
}
if (ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
this.mapResults = new HashMap<T, OnhandBalanceResult<T>>();
}
String key = SysInitGroupQuery.isSNEnabled() ? ICPubMetaNameConst.PK_SERIALCODE
: ICPubMetaNameConst.VSERIALCODE;
Map<String, OnhandSNViewVO> onhandsnmap = CollectionUtils.hashVOArray(
key, snvos);
// 处理每个需求对象
this.processAllocSNReq(key, onhandsnmap, req);
}
}
private void processAllocSNReq(String key,
Map<String, OnhandSNViewVO> onhandsnmap, T req) {
OnhandBalanceResult<T> balancerow = this.mapResults.get(req);
if (balancerow == null) {
balancerow = new OnhandBalanceResult<T>(req);
this.mapResults.put(req, balancerow);
}
List<OnhandSNViewVO> snList = new ArrayList<OnhandSNViewVO>();
// 选择孙表对应的序列号结存
ICLocationVO[] lovs = req.getLocationVOs();
for (ICLocationVO lov : lovs) {
String keyvalue = (String) lov.getAttributeValue(key);
if(onhandsnmap.get(keyvalue) != null) {
snList.add(onhandsnmap.get(keyvalue));
}
}
if(snList.size() < 1) {
return;
}
Map<String, List<OnhandSNViewVO>> snmap = VOEntityUtil
.groupVOByKeys(new String[] { OnhandDimVO.PK_ONHANDDIM },
CollectionUtils.listToArray(snList));
for (Map.Entry<String, List<OnhandSNViewVO>> entry : snmap
.entrySet()) {
BalanceOnhandRes res = new BalanceOnhandRes();
res.setOnhanddimvo(entry.getValue().get(0).getOnhandDimVO());
List<OnhandSNVO> listsnvo = new ArrayList<OnhandSNVO>();
for (OnhandSNViewVO viewvo : entry.getValue()) {
listsnvo.add(viewvo.getOnhandSNVO());
}
//标志这条结果来自于序列号拣货
res.setBySN(true);
res.setListsnvo(listsnvo);
UFDouble[] dsums = VOEntityUtil.sumVOsFieldValuesNotDel(
CollectionUtils.listToArray(entry.getValue()),
new String[] { OnhandSNVO.NONHANDNUM,
OnhandSNVO.NONHANDASTNUM});
res.setNnum(dsums[0]);
res.setNastnum(dsums[1]);
balancerow.addBalanceOnhandRes(res);
}
}
private OnhandSNViewVO[] queryOnhandSNs(Set<String> llist, T req) {
// OnhandSelectDim select = new OnhandSelectDim();
// select.addSelectFields(OnhandDimVO.getContentFields());
OnhandQryCond cond = new OnhandQryCond();
Object[] voValues = VOEntityUtil.getVOValues(((ICBillOnhandReq)req).getOnhandDim(), onhandSNDimFields);
cond.addFilterDimConditon(onhandSNDimFieldsWithoutBatch, voValues);
cond.addAllSelectFields();
OnhandSNViewVO[] snvos = null;
try {
if (SysInitGroupQuery.isSNEnabled()) {
String where =
SqlIn.formInSQL(OnhandSNVO.ALIASNAME + "." + ICPubMetaNameConst.PK_SERIALCODE, new ArrayList<String>(llist));
where += " and " + SqlUtil.getFun_COALESCE(OnhandSNVO.ALIASNAME + "." + OnhandNumVO.NONHANDNUM, "0.0") + " > 0.0";
cond.setWhere(where);
snvos = NCLocator
.getInstance()
.lookup(IOnhandQry.class)
.queryOnhandSN(cond);
// 用这个方法就只是单纯的用序列号去查结存没有考虑到维度问题ncc的逻辑修改成改仓库不清序列号所以必须要以仓库作为维度去过滤
// 所以修改为使用上面的方法 --raoczh 2019.8.19
// .queryOnhandSNBySNCode(select,
// CollectionUtils.setToArray(llist));
} else {
String where =
SqlIn.formInSQL(OnhandSNVO.ALIASNAME + "." + OnhandSNVO.VSNCODE, new ArrayList<String>(llist));
where += " and " + SqlUtil.getFun_COALESCE(OnhandSNVO.ALIASNAME + "." + OnhandNumVO.NONHANDNUM, "0.0") + " > 0.0";
cond.setWhere(where);
snvos = NCLocator
.getInstance()
.lookup(IOnhandQry.class)
.queryOnhandSN(cond);
// .queryOnhandSNBySNCodes(select,
// CollectionUtils.setToArray(llist));
}
} catch (BusinessException e) {
ExceptionUtils.wrappException(e);
}
return snvos;
}
private Set<String> getAllSNValues(T onhandSN) {
Set<String> llist = new HashSet<String>();
String key = SysInitGroupQuery.isSNEnabled() ? ICPubMetaNameConst.PK_SERIALCODE
: ICPubMetaNameConst.VSERIALCODE;
// 获取所有序列号
if(ArrayUtils.isNotEmpty(onhandSN.getLocationVOs())) {
for(ICLocationVO lvo : onhandSN.getLocationVOs()) {
if(lvo.getAttributeValue(key) != null) {
llist.add((String)lvo.getAttributeValue(key));
}
}
// String[] value = VOEntityUtil.getVOsValuesNotDel(
// onhandSN.getLocationVOs(), key, String.class);
// CollectionUtils.addArrayToSet(llist, value);
}
return llist;
}
/**
* 方法功能描述平衡计算前的数据预处理 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
private void processData() {
//过滤需求对象和增加序列号需求对象
this.filterReqsData();
if (ValueCheckUtil.isNullORZeroLength(this.onhandReq)) {
return;
}
// 按实际结存维度处理查询条件
OnhandDimVO[] dimvos = new OnhandDimVO[this.onhandReq.length];
for (int i = 0; i < this.onhandReq.length; i++) {
dimvos[i] = this.onhandReq[i].getOnhandDim();
}
dimvos =
OnhandVOTools.getRealOnhandDim(new ICBSContext().getInvInfo(), dimvos);
OnhandVO[] handvos = this.getOnhandRes().loadOnhandRes(dimvos);
if (ValueCheckUtil.isNullORZeroLength(handvos)) {
return;
}
this.reqsmatch =
new DimMatchUtil<T>(this.onhandReq, OnhandDimVO.getDimContentFields(),
new String[] {
OnhandDimVO.PK_GROUP, OnhandDimVO.PK_ORG,
OnhandDimVO.CWAREHOUSEID, OnhandDimVO.CMATERIALOID,
OnhandDimVO.CMATERIALVID,
});
this.mapResults = new HashMap<T, OnhandBalanceResult<T>>();
handvos = this.preAllocHandRes(handvos);
if (ValueCheckUtil.isNullORZeroLength(handvos)) {
this.reqsmatch = null;
return;
}
this.processOnhandData(handvos);
}
/**
* 方法功能描述处理查询后的现存量 过滤0结存,按统计库存组织+仓库+物料统计实际可以结存 优化后续明细查询 <b>参数说明</b>
*
* @author yangb
* @time 2010-4-10 下午03:10:01
*/
private void processOnhandData(OnhandVO[] handvos) {
// 过滤并处理资源数量
String key = null;
this.mapyethandvo = new HashMap<String, OnhandVO>();
for (OnhandVO handvo : handvos) {
key =
handvo.getAttributeValue(OnhandDimVO.VSUBHASHCODE)
+ handvo.getClocationid();
this.mapyethandvo.put(key, handvo);
}
}
/**
* 处理资源与现有结存的关系
*/
private boolean processResDataForHand(OnhandRes handres) {
String onhandkey =
handres.getOnhanddimvo().getVsubhashcode()
+ handres.getOnhanddimvo().getClocationid();
OnhandVO handvo = this.mapyethandvo.get(onhandkey);
if (handvo == null) {
handres.setNuseablenum(UFDouble.ZERO_DBL);
handres.setNuseableastnum(UFDouble.ZERO_DBL);
handres.setNuseablegrossnum(UFDouble.ZERO_DBL);
return true;
}
handres.getOnhanddimvo().setPk_onhanddim(handvo.getPk_onhanddim());
// 是否超出结存资源
boolean byetoverhand = false;
// 不包含预留冻结数量
UFDouble onhandnum = OnhandVOTools.calcHandNum(handvo);
UFDouble dtemp = NCBaseTypeUtils.sub(onhandnum, handres.getNuseablenum());
if (NCBaseTypeUtils.isLEZero(dtemp)) {
handres.setNuseablenum(onhandnum);
handvo.setNonhandnum(UFDouble.ZERO_DBL);
}
if (handvo.getCastunitid() != null) {
// 不包含预留冻结数量
UFDouble onhandasnum =
OnhandVOTools.calcRealAstHandNum(handvo.getOnhandNumVO());
UFDouble dtemp1 =
NCBaseTypeUtils.sub(onhandasnum, handres.getNuseableastnum());
if (NCBaseTypeUtils.isLEZero(dtemp1)) {
handres.setNuseableastnum(onhandasnum);
handvo.setNonhandastnum(UFDouble.ZERO_DBL);
}
}
else {
handres.setNuseableastnum(this.calculator.calculateAstNum(
handres.getNuseablenum(), handres.getOnhanddimvo().getVchangerate(),
handres.getOnhanddimvo().getCastunitid()));
handvo.setNonhandastnum(UFDouble.ZERO_DBL);
}
if (NCBaseTypeUtils.isGtZero(handvo.getNgrossnum())) {
// 不包含预留冻结数量
UFDouble onhandgrossnum =
OnhandVOTools.calcRealGrossHandNum(handvo.getOnhandNumVO());
UFDouble dtemp2 =
NCBaseTypeUtils.sub(onhandgrossnum, handres.getNuseablegrossnum());
if (NCBaseTypeUtils.isLEZero(dtemp2)) {
handres.setNuseablegrossnum(onhandgrossnum);
handvo.setNgrossnum(UFDouble.ZERO_DBL);
}
}
if (NCBaseTypeUtils.isLEZero(OnhandVOTools.calcHandNum(handvo))
&& NCBaseTypeUtils.isLEZero(OnhandVOTools.calcRealAstHandNum(handvo
.getOnhandNumVO()))) {
byetoverhand = true;
this.mapyethandvo.remove(onhandkey);
}
return byetoverhand;
}
}

View File

@ -0,0 +1,737 @@
package nc.impl.ic.onhand.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.onhand.action.OnhandResBalance;
import nc.bs.ic.onhand.bp.OnhandBaseQry;
import nc.bs.ic.onhand.bp.OnhandDataFactory;
import nc.bs.ic.onhand.bp.OnhandLocationQry;
import nc.bs.ic.onhand.bp.OnhandSynQuery;
import nc.bs.ic.pub.env.ICBSContext;
import nc.impl.pubapp.bd.material.assistant.MarAssistantCheckUtils;
import nc.itf.ic.onhand.OnhandResService;
import nc.itf.scmpub.reference.uap.bd.customer.CustomerPubService;
import nc.itf.scmpub.reference.uap.bd.supplier.SupplierPubService;
import nc.pubitf.ic.reserve.ReserveInOut;
import nc.pubitf.uapbd.IMaterialPubService_C;
import nc.pubitf.uapbd.assistant.IMarAssistantPubService;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.userdefrule.UserdefitemVO;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.general.define.ICBillHeadVO;
import nc.vo.ic.general.define.ICBillVO;
import nc.vo.ic.material.define.InvCalBodyVO;
import nc.vo.ic.onhand.define.ICBillOnhandReq;
import nc.vo.ic.onhand.define.ICBillPickResults;
import nc.vo.ic.onhand.define.OnhandBalanceResult;
import nc.vo.ic.onhand.entity.OnhandDimVO;
import nc.vo.ic.onhand.entity.OnhandVO;
import nc.vo.ic.onhand.pub.HashVOUtils;
import nc.vo.ic.onhand.pub.OnhandQueryDim;
import nc.vo.ic.onhand.pub.OnhandSelectDim;
import nc.vo.ic.onhand.pub.OnhandVOTools;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.ic.pub.util.CollectionUtils;
import nc.vo.ic.pub.util.DimMatchedObj;
import nc.vo.ic.pub.util.NCBaseTypeUtils;
import nc.vo.ic.pub.util.StringUtil;
import nc.vo.ic.pub.util.VOEntityUtil;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.MapList;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.sc.m61.entity.SCOrderIssueVO;
import nc.vo.scmpub.res.billtype.ICBillType;
/**
* <p>
* <b>结存资源服务</b>
*
* @version v60
* @since v60
* @author yangb
* @time 2010-4-15 下午10:14:36
*/
public class OnhandResServiceImpl implements OnhandResService {
/**
* OnhandResServiceImpl 的构造子
*/
public OnhandResServiceImpl() {
// 默认构造
}
@Override
public SCOrderIssueVO[] getSCOrderIssueVOs(AggregatedValueObject[] billvos)
throws BusinessException {
if (ValueCheckUtil.isNullORZeroLength(billvos)) {
return null;
}
try {
return OnhandDataFactory.getOnhandDataSource(billvos[0])
.getSCOrderIssueVOs(billvos);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
@Override
public ICBillPickResults pickAuto(ICBillVO billvo) throws BusinessException {
return this.pickAuto(billvo, true);
}
/**
* 自动拣货
* @param billvo 单据vo
* @param pickNumNotNull 实发数量不为零的行是否需要重新拣货
* @return
* @throws BusinessException
*/
public ICBillPickResults pickAuto(ICBillVO billvo, boolean pickNumNotNull) throws BusinessException {
try {
List<OnhandBalanceResult<ICBillOnhandReq>> retults =
this.pickAutoInner(new ICBillVO[] {
billvo
}, pickNumNotNull);
if (retults == null || retults.size() <= 0) {
return null;
}
if(retults.get(0).isResPick()) {
return null;
}
ICBillPickResults ret = new ICBillPickResults(retults, billvo.getBodys());
ret.getPickBodys();
return ret;
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
*
*/
@Override
public ICBillVO[] pickAuto(ICBillVO[] bills) throws BusinessException {
return this.pickAuto(bills, true);
}
/**
* 自动拣货考虑预留的情况需要控制预留的行需不需要重新拣货这块加一个开关
* modify by yangls7 for hwpoc
* @param bills
* @param pickNumNotNull 是否重新捡实发数量不为0的行
* @return
* @throws BusinessException
*/
public ICBillVO[] pickAuto(ICBillVO[] bills, boolean pickNumNotNull) throws BusinessException {
for(ICBillVO billvo : bills) {
ICBillBodyVO[] bodyvos = billvo.getBodys();
for (int i = 0; i < bodyvos.length; i++) {
bodyvos[i].setAttributeValue(ICPubMetaNameConst.NNUM, null);
bodyvos[i].setAttributeValue(ICPubMetaNameConst.NASSISTNUM, null);
bodyvos[i].setAttributeValue(ICPubMetaNameConst.VNOTEBODY, null);
}
}
// 处理预留拣货
NCLocator.getInstance().lookup(ReserveInOut.class)
.reserveOutAutoPick(bills, false);
List<OnhandBalanceResult<ICBillOnhandReq>> retults =
this.pickAutoInner(bills, pickNumNotNull);
// if (retults == null || retults.size() <= 0) {
// return bills;
// }
try {
List<ICBillBodyVO> lbodys = new ArrayList<ICBillBodyVO>();
for (ICBillVO bill : bills) {
ICBillBodyVO[] bodys = bill.getBodys();
if (ValueCheckUtil.isNullORZeroLength(bodys)) {
continue;
}
for (ICBillBodyVO body : bodys) {
lbodys.add(body);
}
}
ICBillPickResults ret =
new ICBillPickResults(retults, lbodys.toArray(new ICBillBodyVO[lbodys
.size()]));
ICBillBodyVO[] pickbodys = ret.getPickBodys();
MapList<Integer, ICBillBodyVO> mapPickBodyVOs =
new MapList<Integer, ICBillBodyVO>();
//根据供应商 客户oid 日期 设置vid的值
HashSet<String> cvendoridset = new HashSet<String>();
HashSet<String> casscustidset = new HashSet<String>();
// 货主客户
HashSet<String> ctplcustomeridset = new HashSet<String>();
// 寄存供应商
HashSet<String> cvmivenderidset = new HashSet<String>();
for (ICBillBodyVO body : pickbodys) {
String cvendorid = body.getCvendorid();
String casscustid = body.getCasscustid();
String ctplcustomerid = body.getCtplcustomerid();
String cvmivenderid = body.getCvmivenderid();
if (cvendorid != null) {
cvendoridset.add(cvendorid);
}
if (casscustid != null) {
casscustidset.add(casscustid);
}
if (ctplcustomerid != null) {
ctplcustomeridset.add(ctplcustomerid);
}
if (cvmivenderid != null) {
cvmivenderidset.add(cvmivenderid);
}
}
// 获取所有表体的供应商oid 拣货后台逻辑未变只带出物料辅助属性的客户 供应商oid 补充vid
HashMap<String, String> cvendoridMap = new HashMap<String, String>();
HashMap<String, String> casscustidMap = new HashMap<String, String>();
HashMap<String, String> ctplcustomeridMap = new HashMap<String, String>();
HashMap<String, String> cvmivenderidMap = new HashMap<String, String>();
HashMap<String, UFDate> cvendoridAndDate= new HashMap<String, UFDate>();
HashMap<String, UFDate> casscustidAndDate= new HashMap<String, UFDate>();
HashMap<String, UFDate> ctplcustomeridAndDate = new HashMap<String, UFDate>();
HashMap<String, UFDate> cvmivenderidAndDate = new HashMap<String, UFDate>();
UFDate busidate = AppContext.getInstance().getBusiDate();
if (cvendoridset != null && cvendoridset.size() > 0) {
for(String cvendorid : cvendoridset) {
cvendoridAndDate.put(cvendorid,busidate);
}
//根据供应商oid和业务日期查询vid
cvendoridMap = (HashMap<String, String>) SupplierPubService.querySupplierVidsByOidAndDate(cvendoridAndDate);
}
if (casscustidset != null && casscustidset.size() > 0) {
for(String casscustid : casscustidset) {
casscustidAndDate.put(casscustid,busidate);
}
//根据客户oid和业务日期查询vid
casscustidMap = (HashMap<String, String>) CustomerPubService.queryCustomerVidsByOidsAndDate(casscustidAndDate);
}
if (ctplcustomeridset != null && ctplcustomeridset.size() > 0) {
for (String ctplcustomerid : ctplcustomeridset) {
ctplcustomeridAndDate.put(ctplcustomerid, busidate);
}
// 根据货主客户oid和业务日期查询vid
ctplcustomeridMap = (HashMap<String, String>) CustomerPubService
.queryCustomerVidsByOidsAndDate(ctplcustomeridAndDate);
}
if (cvmivenderidset != null && cvmivenderidset.size() > 0) {
for (String cvmivenderid : cvmivenderidset) {
cvmivenderidAndDate.put(cvmivenderid, busidate);
}
// 根据寄存供应商oid和业务日期查询vid
cvmivenderidMap = (HashMap<String, String>) SupplierPubService
.querySupplierVidsByOidAndDate(cvmivenderidAndDate);
}
//根据客户 供应商oid对vid赋值
for (ICBillBodyVO body : pickbodys) {
if (body.getCvendorid() != null) {
body.setCvendorvid(cvendoridMap.get(body.getCvendorid()));
}
if (body.getCasscustid() != null) {
body.setCasscustvid(casscustidMap.get(body.getCasscustid()));
}
if (body.getCtplcustomerid() != null) {
body.setCtplcustomervid(ctplcustomeridMap.get(body.getCtplcustomerid()));
}
if (body.getCvmivenderid() != null) {
body.setCvmivendervid(cvmivenderidMap.get(body.getCvmivenderid()));
}
}
for (ICBillBodyVO pickbody : pickbodys) {
mapPickBodyVOs.put(pickbody.getPseudoColumn(), pickbody);
}
for (ICBillVO bill : bills) {
lbodys = mapPickBodyVOs.get(bill.getHead().getPseudoColumn());
if (ValueCheckUtil.isNullORZeroLength(lbodys)) {
continue;
}
bill.setChildrenVO(CollectionUtils.listToArray(lbodys));
// 记录拣货标识
bill.getHead().setAttributeValue("ispickauto", "Y");
}
// 新增预留拣货需要处理行备注
for(ICBillVO bill : bills) {
for(ICBillBodyVO bodyVO : bill.getBodys()) {
if(MathTool.equals(bodyVO.getNnum(), bodyVO.getNshouldnum())) {
bodyVO.setVnotebody(null);
}
}
}
return bills;
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return bills;
}
/**
* 方法功能描述查询单据的现存量(自动主辅计量平衡使用过滤非自动主辅计量平衡物料)
* <p>
* 非严格匹配的查询只用非空维度字段做过滤 <b>默认查询所有维度字段不做汇总处理包括可用和不可用的结存</b>
*
* @param bills 查询维度
* @since 6.0
* @author yangb
* @time 2010-7-8 下午09:18:24
*/
@Override
public OnhandVO[] queryOnhandVOByBills(ICBillVO[] bills)
throws BusinessException {
try {
List<OnhandDimVO> ldimvos =
OnhandVOTools.getOnhandDimVOs(bills, new ICBSContext().getInvInfo());
if (ValueCheckUtil.isNullORZeroLength(ldimvos)) {
return null;
}
ICBSContext context = new ICBSContext();
OnhandDimVO[] dimvos = ldimvos.toArray(new OnhandDimVO[ldimvos.size()]);
OnhandVOTools.getRealOnhandDim(context.getInvInfo(), dimvos);
InvCalBodyVO[] invCalVOs =
context.getInvInfo().getInvCalBodyVO(
VOEntityUtil.getVOsValues(dimvos, OnhandDimVO.PK_ORG,
String.class),
VOEntityUtil.getVOsValues(dimvos, OnhandDimVO.CMATERIALVID,
String.class));
List<OnhandDimVO> lbalancevos = new ArrayList<OnhandDimVO>();
Set<String> keysset = new HashSet<String>();
String key = null;
for (int i = 0; i < dimvos.length; i++) {
if (!ValueCheckUtil.isTrue(invCalVOs[i].getAutobalancemeas())) {
continue;
}
key = HashVOUtils.getContentKey(dimvos[i]);
if (keysset.contains(key)) {
continue;
}
lbalancevos.add(dimvos[i]);
}
if (ValueCheckUtil.isNullORZeroLength(lbalancevos)) {
return null;
}
return this.queryOnhandVOByDims(lbalancevos
.toArray(new OnhandDimVO[lbalancevos.size()]));
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
* 方法功能描述查询现存量
* <p>
* 非严格匹配的查询只用非空维度字段做过滤 <b>默认查询所有维度字段不做汇总处理包括可用和不可用的结存</b>
*
* @param dimvos 查询维度
* @since 6.0
* @author yangb
* @time 2010-7-8 下午09:18:24
*/
@Override
public OnhandVO[] queryOnhandVOByDims(OnhandDimVO[] dimvos)
throws BusinessException {
try {
OnhandSelectDim select = new OnhandSelectDim();
select.setSum(false);
select.addSelectFields(CollectionUtils.combineArrs(
OnhandDimVO.getDimContentFields(), new String[] {
OnhandDimVO.PK_ONHANDDIM, OnhandDimVO.VHASHCODE,
OnhandDimVO.VSUBHASHCODE
}));
return this.queryOnhandVOByDims(select, dimvos, false, null);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
@Override
public OnhandVO[] queryOnhandVOByDims(OnhandSelectDim select,
OnhandDimVO[] dimvos, boolean bqueryuseablestate, String bytranstype)
throws BusinessException {
try {
List<String> ltranstypes = null;
if (bytranstype != null) {
ltranstypes = new ArrayList<String>();
ltranstypes.add(bytranstype);
}
return new OnhandBaseQry().queryOnhandVOByDims(select, dimvos,
bqueryuseablestate, ltranstypes);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
* 方法功能描述根据现存量维度查询可用的存量为预留提供 仅仅查询库存状态可用的存量
*
* @author yangb
* @time 2010-6-5 下午10:43:05
*/
@Override
public OnhandVO[] queryUseableOnhand(OnhandDimVO[] dimvos)
throws BusinessException {
if (ValueCheckUtil.isNullORZeroLength(dimvos)) {
return null;
}
try {
OnhandSelectDim select = new OnhandSelectDim();
select.setSum(false);
select.addSelectFields(CollectionUtils.combineArrs(
OnhandDimVO.getDimContentFields(), new String[] {
OnhandDimVO.PK_ONHANDDIM, OnhandDimVO.VHASHCODE,
OnhandDimVO.VSUBHASHCODE
}));
return this.queryOnhandVOByDims(select, dimvos, true, null);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
* 方法功能描述根据现存量维度查询可用的存量为可用量提供 仅仅查询库存状态可用的存量
* 未除去不影响可用量的仓库
*
* @author yangb
* @time 2010-6-5 下午10:43:05
*/
@Override
public OnhandVO[] queryUseableOnhandForAtp(OnhandDimVO[] dimvos)
throws BusinessException {
try {
return new OnhandBaseQry().queryOnhandVOByDims(null, dimvos, true, null);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return null;
}
/**
*
* @param billvos
* @param pickNumNotNull 实发数量不为0的行是否需要重新拣货
* @return
*/
private List<OnhandBalanceResult<ICBillOnhandReq>> pickAutoInner(
ICBillVO[] billvos, boolean pickNumNotNull) {
if (ValueCheckUtil.isNullORZeroLength(billvos)) {
return null;
}
//对于物料辅助属性设置了boolean值且未启用 默认值是N 所以此处先进行清空处理 置为null
IMarAssistantPubService assistantPubService = NCLocator.getInstance().lookup(IMarAssistantPubService.class);
try {
UserdefitemVO[] userdefitemVOs = assistantPubService.queryMarAssistantDefine(AppContext.getInstance().getPkGroup());
boolean isUseDef = false;
if(userdefitemVOs!=null) {
for (UserdefitemVO vo : userdefitemVOs) {
if(vo.getClassid().equals("BS000010000100001032")) {
isUseDef = true;
}
}
}
if (isUseDef) {
this.processFreeDef(billvos);
}
} catch (BusinessException e) {
ExceptionUtils.wrappException(e);
}
List<String> ltranstypes = new ArrayList<String>();
List<ICBillOnhandReq> lreqs = new ArrayList<ICBillOnhandReq>();
int count = 0, totalrownum = 0;
Integer billno = null;
for (ICBillVO billvo : billvos) {
ICBillBodyVO[] bodys = billvo.getBodys();
ICBillHeadVO head = billvo.getHead();
ICBillOnhandReq req = null;
billno = Integer.valueOf(count);
head.setPseudoColumn(billno);
for (int i = 0; i < bodys.length; i++) {
bodys[i].setPseudoColumn(billno);
// 支持录入实发数量拣货
// 填写了实发的则不捡货, 红字单据拣货和v57保持一致
// 预留拣货在捡之前已经把实发置空这块不需要再捡了 modify by yangls7 for hwpoc
if (pickNumNotNull && (!NCBaseTypeUtils.isNullOrZero(bodys[i].getNnum())
|| !NCBaseTypeUtils.isNullOrZero(bodys[i].getNassistnum()))) {
// 不拣货也需要自动加1否则既有实发和应发行的时候会串行委外材料核销
totalrownum++;
continue;
}
if (MathTool.compareTo(bodys[i].getNshouldnum(), UFDouble.ZERO_DBL) < 0
&& MathTool.compareTo(bodys[i].getNshouldassistnum(),
UFDouble.ZERO_DBL) < 0) {
totalrownum++;
continue;
}
bodys[i].setPk_group(head.getPk_group());
bodys[i].setPk_org(head.getPk_org());
bodys[i].setPk_org_v(head.getPk_org_v());
bodys[i].setCbodywarehouseid(head.getCwarehouseid());
req = new ICBillOnhandReq(bodys[i]);
req.setRowno(String.valueOf(totalrownum));
totalrownum++;
lreqs.add(req);
if (!StringUtil.isSEmptyOrNull(head.getVtrantypecode())) {
ltranstypes.add(head.getVtrantypecode());
}
}
count++;
}
List<OnhandBalanceResult<ICBillOnhandReq>> results =
new ArrayList<OnhandBalanceResult<ICBillOnhandReq>>();
if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
results.add(new OnhandBalanceResult<ICBillOnhandReq>(true));
return results;
}
ICBillOnhandReq[] reqs = new ICBillOnhandReq[lreqs.size()];
reqs = lreqs.toArray(reqs);
OnhandResBalance<ICBillOnhandReq> resb =
new OnhandResBalance<ICBillOnhandReq>(reqs);
resb.setCtranstype(ltranstypes);
resb.onhandBalance();
OnhandBalanceResult<ICBillOnhandReq> result = null;
for (ICBillOnhandReq reqq : reqs) {
result = resb.getResults(reqq);
if (result != null) {
results.add(result);
}
}
return results;
}
private void processFreeDef(ICBillVO[] billvos) {
ICBillVO billvo = billvos[0];
MapList<String, String> checkvalue = check(ICPubMetaNameConst.CMATERIALVID, billvo.getBodys());
for (ICBillBodyVO bodyvo : billvo.getBodys()) {
if (checkvalue == null) {
for (int k = 1; k <= 10; k++) {
String index = "vfree" + k;
Object vfree = bodyvo.getAttributeValue(index);
if ((vfree != null && (vfree.equals("N") || vfree.equals("false"))) ) {
bodyvo.setAttributeValue(index, null);
}
}
} else {
Map<String, List<String>> maplist = checkvalue.toMap();
List<String> list = maplist.get(bodyvo.getAttributeValue(ICPubMetaNameConst.CMATERIALVID));
for (int k = 1; k <= 10; k++) {
String index = "vfree" + k;
Object vfree = bodyvo.getAttributeValue(index);
if ((vfree != null && (vfree.equals("N") || vfree.equals("false")))) {
if(list==null || !list.contains(index)) {
bodyvo.setAttributeValue(index, null);
}
}
}
}
}
}
public MapList<String, String> check(String materialField,ISuperVO[] valueObjects) {
MapList<String, String> materialMapList = new MapList<String, String>();
Map<String, MaterialVO> materialMap = this.getMaterialMap(materialField, valueObjects);//<pk,materialVo>
if (materialMap == null || materialMap.size() == 0) {
return null;
}
Map<String, List<Integer>> marFrameMap = this.getMarFrameMap(materialMap);
if (marFrameMap == null || marFrameMap.size() == 0) {
return null;
}
for (ISuperVO value : valueObjects) {
Object pk_material = value.getAttributeValue(materialField);
String pk_marasstframe = materialMap.get(pk_material).getPk_marasstframe();
List<Integer> list = marFrameMap.get(pk_marasstframe);
if(list==null) {
continue;
}
for(Integer listvlaue:list) {
if (pk_marasstframe != null) {
materialMapList.put(pk_material.toString(), "vfree"+(listvlaue-5));
}
}
}
return materialMapList;
}
private Map<String, List<Integer>> getMarFrameMap(Map<String, MaterialVO> materialMap) {
Map<String, List<Integer>> marFrameMap = null;
try {
Set<String> marFramePkSet = new HashSet<String>();
for (Entry<String, MaterialVO> entry : materialMap.entrySet()) {
String pk_marasstframe = entry.getValue().getPk_marasstframe();
if (pk_marasstframe != null) {
marFramePkSet.add(pk_marasstframe);
}
}
marFrameMap =
MarAssistantCheckUtils.queryMarAsstFrameIncludeDefPropIndex(marFramePkSet
.toArray(new String[0]));
} catch (BusinessException e) {
ExceptionUtils.wrappException(e);
}
return marFrameMap;
}
private Map<String, MaterialVO> getMaterialMap(String materialField, ISuperVO[] valueObjects) {
Map<String, MaterialVO> materialMap = null;
try {
Set<String> marPkSet = new HashSet<String>();
for (int i = 0; i < valueObjects.length; i++) {
String pk_material = (String) valueObjects[i].getAttributeValue(materialField);
marPkSet.add(pk_material);
}
IMaterialPubService_C marService =
NCLocator.getInstance().lookup(IMaterialPubService_C.class);
materialMap =
marService.queryMaterialBaseInfoByPks(marPkSet.toArray(new String[0]), new String[] {
MaterialVO.PK_MARASSTFRAME, MaterialVO.NAME, MaterialVO.NAME2, MaterialVO.NAME3,
MaterialVO.NAME4, MaterialVO.NAME5, MaterialVO.NAME6});
} catch (BusinessException e) {
ExceptionUtils.wrappException(e);
}
return materialMap;
}
@Override
public Map<String, String> queryLastInLocation(String pk_calbody,
String cwarehouseid, String[] cmaterialvids) throws BusinessException {
try {
return new OnhandLocationQry().queryLastInLocation(pk_calbody,
cwarehouseid, cmaterialvids);
}
catch (Exception ex) {
ExceptionUtils.marsh(ex);
return new HashMap<String, String>();
}
}
@Override
public Map<String, String> queryOnhandLocation(String pk_calbody,
String cwarehouseid, String[] cmaterialvids) throws BusinessException {
try {
return new OnhandLocationQry().queryOnhandLocation(pk_calbody,
cwarehouseid, cmaterialvids);
}
catch (Exception ex) {
ExceptionUtils.marsh(ex);
return new HashMap<String, String>();
}
}
@Override
public OnhandVO[] queryAtpOnhand(OnhandDimVO[] dimvos, boolean bextendWarehouse)
throws BusinessException {
try {
return new OnhandSynQuery().queryOnhandForAtp(null, getQueryDim(dimvos),
bextendWarehouse);
}
catch (Exception e) {
ExceptionUtils.marsh(e);
}
return new OnhandVO[0];
}
private OnhandQueryDim[] getQueryDim(OnhandDimVO[] dimvos) {
if (ValueCheckUtil.isNullORZeroLength(dimvos)) {
return null;
}
DimMatchedObj<OnhandDimVO> handkey = null;
OnhandQueryDim[] dimconds = new OnhandQueryDim[dimvos.length];
for (int i = 0; i < dimvos.length; i++) {
handkey =
new DimMatchedObj<OnhandDimVO>(dimvos[i],
OnhandDimVO.getDimContentFields());
dimconds[i] = new OnhandQueryDim();
dimconds[i].addDimCondition(handkey.getDimFields(),
VOEntityUtil.getVOValues(dimvos[i], handkey.getDimFields()));
}
return dimconds;
}
@Override
public OnhandVO[] queryAtpOnhandUP(OnhandDimVO[] dimvos,
UFDateTime tupdatetime, UFDateTime endtime, boolean bextendWarehouse) throws BusinessException {
return new OnhandSynQuery().queryOnhandForAtpUP(null,
this.getQueryDim(dimvos), tupdatetime, endtime, bextendWarehouse);
}
@Override
public ICBillPickResults reservePickAuto(ICBillVO[] billvos)
throws BusinessException {
//将实发数量清空
this.cleanBodyNum(billvos);
//处理预留预留拣货出来的后续不会再拣货了
billvos = this.processReserve(billvos);
return this.pickAuto(billvos[0], false);
}
/**
* 处理预留
* @param vos
* @return
*/
private ICBillVO[] processReserve(ICBillVO[] vos) {
if (ICBillType.GeneralOut.getCode().equals(
(vos[0].getHead().getBillType().getCode()))) {
return vos;
}
try {
// 预留处理
ICBillVO[] retvos = NCLocator.getInstance().lookup(ReserveInOut.class)
.reserveOutAutoPick(vos, false);
return retvos;
}
catch (Exception e) {
ExceptionUtils.wrappException(e);
}
return null;
}
/**
* 清空表体的实发数量实发主数量
* @param vos
* @return
*/
private void cleanBodyNum(ICBillVO[] vos) {
for(ICBillVO vo : vos) {
for(ICBillBodyVO bodyVO : vo.getBodys()) {
bodyVO.setNnum(null);
bodyVO.setNassistnum(null);
bodyVO.setVnotebody(null);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,492 @@
package nc.vo.ic.onhand.define;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.ic.pub.env.ICBSContext;
import nc.itf.scmpub.reference.uap.group.SysInitGroupQuery;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.location.ICLocationVO;
import nc.vo.ic.material.define.InvCalBodyVO;
import nc.vo.ic.onhand.entity.OnhandDimVO;
import nc.vo.ic.onhand.entity.OnhandSNVO;
import nc.vo.ic.onhand.pub.OnhandVOTools;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.ic.pub.lang.OnhandRes;
import nc.vo.ic.pub.util.CollectionUtils;
import nc.vo.ic.pub.util.NCBaseTypeUtils;
import nc.vo.ic.pub.util.StringUtil;
import nc.vo.ic.pub.util.VOEntityUtil;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.scale.ScaleUtils;
import nc.vo.pubapp.util.VORowNoUtils;
/**
* <p>
* <b>单据现存量捡货结果</b>
*
* @version 本版本号
* @since 上一版本号
* @author yangb
* @time 2010-4-16 下午01:05:00
*/
public class ICBillPickResults implements Serializable {
private static final long serialVersionUID = 201008201108000513L;
// 捡货后的单据表体VO
private ICBillBodyVO[] curbillbodyvos;
private Map<String, ICBillBodyVO[]> mapbodyvos;
// 原始表体的自然序号与捡货结果的对应关系
private transient Map<String, OnhandBalanceResult<ICBillOnhandReq>> maponhandbalanceresult;
// 捡货前的单据表体VO
private ICBillBodyVO[] originbillbodyvos;
// 捡货后结果
private List<OnhandBalanceResult<ICBillOnhandReq>> pickresults;
// 精度的工具类
private transient ScaleUtils scale;
//标识是否为预留拣货
private boolean isResPick = false;
/**
* @return the isResPick
*/
public boolean isResPick() {
return isResPick;
}
/**
* @param isResPick the isResPick to set
*/
public void setResPick(boolean isResPick) {
this.isResPick = isResPick;
}
/**
* OnhandBalanceResult 的构造子
*/
public ICBillPickResults(boolean isResPick) {
this.isResPick = isResPick;
}
/**
* ICBillPickResults 的构造子
*/
public ICBillPickResults(
List<OnhandBalanceResult<ICBillOnhandReq>> pickresults,
ICBillBodyVO[] originbodyvos) {
this.pickresults = pickresults;
this.originbillbodyvos = originbodyvos;
}
/**
* 获取捡货后的表体ICBillBodyVOs
*/
public ICBillBodyVO[] getPickBodys() {
if (this.curbillbodyvos != null) {
return this.curbillbodyvos;
}
List<ICBillBodyVO> retlist = new ArrayList<ICBillBodyVO>();
ICBillBodyVO[] bodyvos = null;
for (int i = 0; i < this.originbillbodyvos.length; i++) {
bodyvos = this.getPickBodys(i);
if (bodyvos == null || bodyvos.length <= 0) {
//如果没有拣到返回originvo并在备注上提示现存量不足
this.originbillbodyvos[i].setVnotebody(OnhandRes.getOnhandErro());
retlist.add(this.originbillbodyvos[i]);
continue;
}
//如果拣货后有对应的数据根据拣货的结果处理拣货行bodyvos上的备注
this.processBodyNote(this.originbillbodyvos[i], bodyvos);
CollectionUtils.addArrayToList(retlist, bodyvos);
}
this.curbillbodyvos = CollectionUtils.listToArray(retlist);
// 捡货后表体数据整理如换算率 批次 相关
this.processBodyData(this.curbillbodyvos);
return this.curbillbodyvos;
}
/**
* 处理表体备注如果原始行应发数量大于对应拣货结果总结存报现存量不足
*
* @param orivo 原始行
* @param curvos 拣货结果
*/
private void processBodyNote(ICBillBodyVO orivo, ICBillBodyVO[] curvos) {
UFDouble shouldNum = orivo.getNshouldnum();
UFDouble shouldasNum = orivo.getNshouldassistnum();
UFDouble totalNum = UFDouble.ZERO_DBL;
UFDouble totalasNum = UFDouble.ZERO_DBL;
for (ICBillBodyVO curvo : curvos) {
totalNum = NCBaseTypeUtils.add(totalNum, curvo.getNnum());
totalasNum = NCBaseTypeUtils.add(totalasNum, curvo.getNassistnum());
}
if (NCBaseTypeUtils.isGtZero(NCBaseTypeUtils.sub(shouldNum, totalNum))
|| NCBaseTypeUtils.isGtZero(NCBaseTypeUtils
.sub(shouldasNum, totalasNum))) {
for (ICBillBodyVO curvo : curvos) {
if (StringUtil.isSEmptyOrNull(curvo.getVnotebody())) {
curvo.setVnotebody(OnhandRes.getOnhandErro());
}
}
}
}
/**
* 获取捡货后的表体ICBillBodyVO
*/
public ICBillBodyVO[] getPickBodys(int row) {
if (this.mapbodyvos != null
&& this.mapbodyvos.containsKey(String.valueOf(row))) {
return this.mapbodyvos.get(String.valueOf(row));
}
OnhandBalanceResult<ICBillOnhandReq> result =
this.getMapResults().get(String.valueOf(row));
if (result == null) {
return null;
}
List<ICBillBodyVO> retlist = new ArrayList<ICBillBodyVO>();
if (result.getResults() == null || result.getResults().size() <= 0) {
ICBillBodyVO[] vos =
(ICBillBodyVO[]) Array.newInstance(result.getOnhandReq().getBodyvo()
.getClass(), 1);
vos[0] = result.getOnhandReq().getBodyvo();
return vos;
}
ICBillBodyVO bodyvo =
(ICBillBodyVO) result.getOnhandReq().getBodyvo().clone();
result.setResults(prepare(result.getResults(), bodyvo));
// 先按现存量维度分组不包括货位+对应入库单行ID
Map<String, List<BalanceOnhandRes>> mapgroup =
this.groupBalanceOnhandRes(result.getResults());
int rowCount = 0;
for (List<BalanceOnhandRes> lbalances : mapgroup.values()) {
rowCount = rowCount + 1;
if (retlist.size() > 0) {
bodyvo = (ICBillBodyVO) result.getOnhandReq().getBodyvo().clone();
bodyvo.setStatus(VOStatus.NEW);
bodyvo.setCgeneralbid(null);
bodyvo.setCrowno(null);
bodyvo.setPseudoColumn(bodyvo.getPseudoColumn());
//bodyvo.setNshouldnum(null);
//bodyvo.setNshouldassistnum(null);
}
//因为存在实发数量拣货,需要
this.synBodyData(bodyvo, lbalances.get(0));
ICLocationVO[] locs = null;
List<ICLocationVO> listlocs = new ArrayList<ICLocationVO>();
//因为存在实发数量拣货需清除原有的数量
bodyvo.setNnum(null);
bodyvo.setNassistnum(null);
for (BalanceOnhandRes balance : lbalances) {
UFDouble nnum =
NCBaseTypeUtils.add(bodyvo.getNnum(), balance.getNnum());
UFDouble nassistnum =
NCBaseTypeUtils.add(bodyvo.getNassistnum(), balance.getNastnum());
bodyvo.setNnum(this.getScale()
.adjustNumScale(nnum, bodyvo.getCunitid()));
bodyvo.setNassistnum(this.getScale().adjustNumScale(nassistnum,
bodyvo.getCastunitid()));
//不处理毛重
/*bodyvo.setNgrossnum(NCBaseTypeUtils.add(bodyvo.getNgrossnum(),
balance.getNgrossnum()));*/
locs = balance.getLocatonVO(bodyvo);
if (locs == null || locs.length <= 0) {
continue;
}
CollectionUtils.addArrayToList(listlocs, locs);
}
//拆行的话需要清空拆出来的行的应发数量
if(rowCount > 1) {
// bodyvo.setNshouldnum(null);
// bodyvo.setNshouldassistnum(null);
//78--2025年4月9日19点11分--sdlizheng--实发传输到应发最后一行做合计处理--start
bodyvo.setNshouldnum(retlist.get(0).getNshouldnum());
bodyvo.setNshouldassistnum(retlist.get(0).getNshouldassistnum());
//78--2025年4月9日19点11分--sdlizheng--实发传输到应发最后一行做合计处理--start
}
if (listlocs.size() > 0) {
//清除重复的孙表数据
// listlocs = clearDuplicatelvo(bodyvo, listlocs);
//处理修改时 带有孙表的自动拣货 重复出库问题 因为拣货把删除的数据给覆盖了 这里补充上
ICLocationVO[] originLocationVos = bodyvo.getLocationVOs();
if (originLocationVos != null && originLocationVos.length > 0) {
for (ICLocationVO lvo: originLocationVos) {
lvo.setStatus(VOStatus.DELETED);
listlocs.add(lvo);
}
}
//处理修改时 带有孙表的自动拣货 重复出库问题 因为拣货把删除的数据给覆盖了 这里补充上
bodyvo.setLocationVOs(listlocs.toArray((ICLocationVO[]) Array
.newInstance(listlocs.get(0).getClass(), listlocs.size())));
// 检出
this.reCalculateNum(bodyvo);
}
retlist.add(bodyvo);
}
ICBillBodyVO[] retvos = CollectionUtils.listToArray(retlist);
if (this.mapbodyvos == null) {
this.mapbodyvos = new HashMap<String, ICBillBodyVO[]>();
}
this.mapbodyvos.put(String.valueOf(row), retvos);
return retvos;
}
/**
* 预处理拣货结果序列号拣货的优先然后在不满足需求的前提下再加上全捡的部分结果
* @param resList
* @param bodyvo
*/
private List<BalanceOnhandRes> prepare(List<BalanceOnhandRes> resList, ICBillBodyVO bodyvo) {
List<BalanceOnhandRes> ret = new ArrayList<BalanceOnhandRes>();
String snField = SysInitGroupQuery.isSNEnabled() ? ICPubMetaNameConst.PK_SERIALCODE : OnhandSNVO.VSNCODE;
//行上没有序列号单位认为不是序列号管理不做处理
Map<String, InvCalBodyVO> mapInvvos = new ICBSContext().getInvInfo().getMapInvCalBodyVO(bodyvo.getPk_org(),
new String[] {bodyvo.getCmaterialvid()});
if(mapInvvos == null) {
return resList;
}
InvCalBodyVO invvo = mapInvvos.get(bodyvo.getCmaterialvid());
if(invvo == null || !ValueCheckUtil.isTrue(invvo.getSerialmanaflag())) {
return resList;
}
// if( bodyvo.getCSnunitid() == null) {
// return resList;
// }
//序列号需求数量的字段
String snNumReqField = invvo.getSernumunit() != null && invvo.getSernumunit().equals(bodyvo.getCastunitid()) ?
ICPubMetaNameConst.NSHOULDASSISTNUM : ICPubMetaNameConst.NSHOULDNUM;
//获取序列号拣货捡出的序列号集合
Set<String> bySNValues = new HashSet<String>();
//第一次循环找出序列号拣货捡出的所有序列号
for(BalanceOnhandRes res : resList) {
if(res.isBySN()) {
List<OnhandSNVO> locs = res.getListsnvo();
if (locs == null || locs.size() <= 0) {
continue;
}
CollectionUtils.addArrayToSet(bySNValues,
(VOEntityUtil.getVOsValueSet(locs.toArray(new OnhandSNVO[0]), snField)).toArray(new String[0]));
}
}
int needNum = ((UFDouble)bodyvo.getAttributeValue(snNumReqField)).intValue() - bySNValues.size();
ICLocationVO[] blvos = getLVOsBySNField(bodyvo, snField);
Set bsns = VOEntityUtil.getVOsValueSet(blvos, snField);
int needsnNum = ((UFDouble)bodyvo.getAttributeValue(snNumReqField)).intValue()-blvos.length;
//第二次循环对于非序列号拣货捡出的结果移除其中已有的序列号结果如果最终结果为空则移除这条结果
for(BalanceOnhandRes res : resList) {
if(res.isBySN()) {
ret.add(res);
}else {
List<OnhandSNVO> locs = res.getListsnvo();
if (locs == null || locs.size() <= 0) {
ret.add(res);
continue;
}
List<OnhandSNVO> list = new ArrayList<OnhandSNVO>();
String[] lpks = VOEntityUtil.getVOsValuesNotDel(blvos, ICLocationVO.PK_SERIALCODE, String.class);
for(OnhandSNVO lvo : locs) {
if(needsnNum > 0) {
if(lpks != null) {
if(lvo.getAttributeValue(snField) != null && !Arrays.asList(lpks).contains(lvo.getPk_serialcode())) {
list.add(lvo);
needsnNum--;
}
} else {
if(lvo.getAttributeValue(snField) != null) {
list.add(lvo);
needsnNum--;
}
}
}
}
if(list.size() > 0) {
res.setListsnvo(list);
// 根据孙表数量计算表体数量
UFDouble[] sums = VOEntityUtil.sumVOsFieldValuesNotDel(list.toArray(new OnhandSNVO[0]),
new String[]{OnhandSNVO.NONHANDNUM});
res.setNastnum(new UFDouble(list.size()));
res.setNnum(sums[0]);
ret.add(res);
}else {
res.setListsnvo(null);
}
}
}
return ret;
}
/**
* 有的场景会向后台传序列号的编码不传序列号的主键这个时候认为没有传孙表数据
* @param bodyvo
* @param snField
* @return
*/
private ICLocationVO[] getLVOsBySNField(ICBillBodyVO bodyvo, String snField) {
if(bodyvo.getLocationVOs() == null) {
return new ICLocationVO[] {};
}
List<ICLocationVO> list = new ArrayList<ICLocationVO>();
for(ICLocationVO lvo : bodyvo.getLocationVOs()) {
if(lvo.getAttributeValue(snField) != null && lvo.getStatus() != VOStatus.DELETED) {
list.add(lvo);
}
}
return list.toArray(new ICLocationVO[0]);
}
private void reCalculateNum(ICBillBodyVO bodyvo) {
ICLocationVO[] locs = bodyvo.getLocationVOs();
String[] vsns = VOEntityUtil.getVOsValuesNotDel(locs, ICLocationVO.VSERIALCODE, String.class);
if (StringUtil.isSEmptyOrNullForAll(vsns)) {
return;
}
// 根据孙表数量计算表体数量
UFDouble[] sums = VOEntityUtil.sumVOsFieldValuesNotDel(locs, new String[]{ICLocationVO.NNUM,ICLocationVO.NASSISTNUM});
bodyvo.setNnum(sums[0]);
bodyvo.setNassistnum(sums[1]);
}
/**
*
*/
private Map<String, OnhandBalanceResult<ICBillOnhandReq>> getMapResults() {
if (this.maponhandbalanceresult == null) {
this.maponhandbalanceresult =
new HashMap<String, OnhandBalanceResult<ICBillOnhandReq>>();
if (this.pickresults != null && this.pickresults.size() > 0) {
for (OnhandBalanceResult<ICBillOnhandReq> result : this.pickresults) {
if(result.getOnhandReq()!= null) {
this.maponhandbalanceresult.put(result.getOnhandReq().getRowno(),
result);
}
}
}
}
return this.maponhandbalanceresult;
}
/**
* 按现存量维度分组+对应入库单表体ID不包括货位
*/
private Map<String, List<BalanceOnhandRes>> groupBalanceOnhandRes(
List<BalanceOnhandRes> lbalances) {
String key = null;
Map<String, List<BalanceOnhandRes>> mapgroup =
new HashMap<String, List<BalanceOnhandRes>>();
List<BalanceOnhandRes> lbalance = null;
for (BalanceOnhandRes balance : lbalances) {
key = OnhandVOTools.getAstDimContentKey(balance.getOnhanddimvo());
key = key+balance.getCgeneralbid()+balance.getOnhanddimvo().getClocationid();
lbalance = mapgroup.get(key);
if (lbalance == null) {
lbalance = new ArrayList<BalanceOnhandRes>();
mapgroup.put(key, lbalance);
}
lbalance.add(balance);
}
return mapgroup;
}
/**
* 捡货后表体数据整理如换算率 批次 相关
*/
private ICBillBodyVO[] processBodyData(ICBillBodyVO[] bodyvos) {
if (bodyvos == null || bodyvos.length <= 0) {
return bodyvos;
}
// 处理行号
VORowNoUtils.setVOsRowNoByRule(bodyvos, ICPubMetaNameConst.CROWNO);
// ScaleUtils scaleutils = ScaleUtils.getScaleUtilAtBS();
// TODO 精度未处理 等待公共方法
ICBSContext context = new ICBSContext();
for (int i = 0; i < bodyvos.length; i++) {
bodyvos[i].setNcostmny(NCBaseTypeUtils.mult(bodyvos[i].getNcostprice(),
bodyvos[i].getNnum()));
bodyvos[i].setNplannedmny(NCBaseTypeUtils.mult(
bodyvos[i].getNplannedprice(), bodyvos[i].getNnum()));
// 实发数量和主数量都为空时不补业务日期
if(bodyvos[i].getNnum() == null && bodyvos[i].getNassistnum() == null){
continue;
}
// 如果业务日期为空的话补充 modify by guozhq
if(bodyvos[i].getDbizdate() == null) {
bodyvos[i].setDbizdate(context.getBizDate());
}
}
return bodyvos;
}
/**
* 设置捡货后的货位数据
*/
// private void synLocData(ICBillBodyVO bodyvo,BalanceOnhandRes
// balance,ICLocationVO locvo) {
// locvo.setCgeneralbid(bodyvo.getCgeneralbid());
// locvo.setPk_group(bodyvo.getPk_group());
// locvo.setCorpoid(bodyvo.getCorpoid());
// locvo.setCorpvid(bodyvo.getCorpvid());
// locvo.setNinspacenum(balance.getNnum());
// locvo.setNinspaceassistnum(balance.getNastnum());
// locvo.setNingrossnum(balance.getNgrossnum());
// }
/**
* 设置捡货后的表体数据
*/
private void synBodyData(ICBillBodyVO bodyvo, BalanceOnhandRes res) {
if (bodyvo == null || res == null) {
return;
}
//现存量维度的单位和单据界面的辅单位不能同步
String[] onhandDims=StringUtil.getArrayWithOutStr(OnhandDimVO.getDimContentFields(),
OnhandDimVO.CASTUNITID );
OnhandDimVO handdimvo = res.getOnhanddimvo();
for (String field : OnhandDimVO.getDimContentFields()) {
if (field.equals(OnhandDimVO.VCHANGERATE)) {
String vchangerate = handdimvo.getVchangerate();
// 如果换算率不记结存不同步换算率
if (StringUtil.isSEmptyOrNull(vchangerate)) {
onhandDims =
StringUtil
.getArrayWithOutStr(onhandDims, OnhandDimVO.VCHANGERATE);
}
break;
}
}
VOEntityUtil.copyVOByVO(bodyvo, onhandDims,
res.getOnhanddimvo(),onhandDims);
bodyvo.setCcorrespondtype(res.getCbilltype());
bodyvo.setCcorrespondtranstype(res.getVtrantypecode());
bodyvo.setCcorrespondcode(res.getVbillcode());
bodyvo.setCcorrespondhid(res.getCgeneralhid());
bodyvo.setCcorrespondbid(res.getCgeneralbid());
bodyvo.setCcorrespondrowno(res.getCrowno());
}
private ScaleUtils getScale() {
if (this.scale == null) {
this.scale = ScaleUtils.getScaleUtilAtBS();
}
return this.scale;
}
}