diff --git a/ic/src/private/nc/bs/ic/onhand/action/OnhandResBalance.java b/ic/src/private/nc/bs/ic/onhand/action/OnhandResBalance.java
new file mode 100644
index 0000000..4328566
--- /dev/null
+++ b/ic/src/private/nc/bs/ic/onhand/action/OnhandResBalance.java
@@ -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;
+
+/**
+ *
+ * 结存资源平衡
+ *
+ * - 捡货的现存量处理分配
+ *
- 预留的现存量分配
+ *
+ *
+ * 变更历史:
+ *
+ *
+ * @version v60
+ * @since v60
+ * @author yangb
+ * @time 2010-4-10 下午02:13:20
+ */
+public class OnhandResBalance implements ResAlloc {
+
+ private BusiCalculator calculator;
+
+ // 使用交易类型作为结存的过滤条件
+ private List ctranstypes;
+
+ // 分配结果
+ private Map> mapResults;
+
+// // 分配结果
+// private Map> mapSnResults;
+
+ // 现有的结存
+ private Map mapyethandvo;
+
+ // 需求对象
+ private T[] onhandReq;
+
+ // 序列号需求对象
+ private T[] onhandSNReq;
+
+ private OnhandResManager onhandres;
+
+ // 需求与结存资源的匹配器
+ private DimMatchUtil 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 lreqs = this.reqsmatch.searchMatchedDimObj(handres, -1);
+ if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
+ return true;
+ }
+ boolean byetoverhand = this.processResDataForHand(handres);
+ OnhandBalanceResult balancerow = null;
+ int ireqs = lreqs.size();
+ for (T req : lreqs) {
+ balancerow = this.mapResults.get(req);
+ if (balancerow == null) {
+ balancerow = new OnhandBalanceResult(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;
+ }
+
+ /**
+ * 方法功能描述:获取平衡结果 参数说明
+ *
+ * @author yangb
+ * @time 2010-4-10 下午03:10:01
+ */
+ public OnhandBalanceResult getResults(T req) {
+ if (this.mapResults == null) {
+ return null;
+ }
+ return this.mapResults.get(req);
+ }
+
+ /**
+ * 方法功能描述:现存量平衡计算 参数说明
+ *
+ * @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 ctranstypes) {
+ this.ctranstypes = ctranstypes;
+ }
+
+ /**
+ * 分配单品,基于已分配结存的结果
+ */
+ private void allocSn(OnhandVO[] handvos) {
+ if (ValueCheckUtil.isNullORZeroLength(handvos)
+ || ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
+ return;
+ }
+ Set onhandpks =
+ VOEntityUtil.getVOsValueSet(handvos, OnhandDimVO.PK_ONHANDDIM);
+
+ // 查询单品资源
+ List[] 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 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);
+ }
+ }
+ }
+
+ /**
+ * 方法功能描述:分配计算 参数说明
+ *
+ * @author yangb
+ * @time 2010-4-10 下午03:10:01
+ */
+ private void assignRes(OnhandBalanceResult 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);
+ }
+
+ /**
+ * 方法功能描述:过滤需求 参数说明
+ *
+ * @author yangb
+ * @time 2010-4-10 下午03:10:01
+ */
+ @SuppressWarnings("unchecked")
+ private void filterReqsData() {
+ if (ValueCheckUtil.isNullORZeroLength(this.onhandReq)) {
+ return;
+ }
+ List datas = new ArrayList();
+ List sndatas = new ArrayList();
+ 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;
+ }
+
+ /**
+ * 方法功能描述:获取现存量资源 参数说明
+ *
+ * @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[] getOuttrackinOnhandRes() {
+ if (ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
+ return null;
+ }
+ List listbid = new ArrayList();
+ List listbilltype = new ArrayList();
+ String cgeneralbid = null;
+ for (OnhandBalanceResult 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
+ };
+ }
+
+ /**
+ * 方法功能描述: 预分配现存量资源,对于: 非(先进先出,后进先出) 非(出库跟踪入库) 的物料,
+ * 可以直接根据现存量分配资源即可,
+ * 不用继续查询单据明细,这样提高效率
+ *
+ * @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 lrethandvos = new ArrayList();
+ List lprehandvos = new ArrayList();
+ 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 lreqs = this.reqsmatch.searchMatchedDimObj(handres, -1);
+ if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
+ continue;
+ }
+ OnhandBalanceResult balancerow = null;
+ lprehandvos.add(handvo);
+ for (T req : lreqs) {
+ balancerow = this.mapResults.get(req);
+ if (balancerow == null) {
+ balancerow = new OnhandBalanceResult(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 mapmeasInv =this.loadInvMeas(handvos);
+ if (ValueCheckUtil.isNullORZeroLength(mapmeasInv)) {
+ return ;
+ }
+ List reserveVOs = new ArrayList();
+
+ 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 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 loadInvMeas(OnhandVO[] handvos) {
+ Map mapInv = new HashMap();
+ 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 loadInvBas(OnhandVO[] handvos) {
+ Map mapInv = new HashMap();
+ 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 llist = this.getAllSNValues(req);
+ // 查询序列号结存
+ OnhandSNViewVO[] snvos = this.queryOnhandSNs(llist, req);
+ if (ValueCheckUtil.isNullORZeroLength(snvos)) {
+ return;
+ }
+ if (ValueCheckUtil.isNullORZeroLength(this.mapResults)) {
+ this.mapResults = new HashMap>();
+ }
+ String key = SysInitGroupQuery.isSNEnabled() ? ICPubMetaNameConst.PK_SERIALCODE
+ : ICPubMetaNameConst.VSERIALCODE;
+
+ Map onhandsnmap = CollectionUtils.hashVOArray(
+ key, snvos);
+ // 处理每个需求对象
+ this.processAllocSNReq(key, onhandsnmap, req);
+ }
+ }
+
+ private void processAllocSNReq(String key,
+ Map onhandsnmap, T req) {
+ OnhandBalanceResult balancerow = this.mapResults.get(req);
+ if (balancerow == null) {
+ balancerow = new OnhandBalanceResult(req);
+ this.mapResults.put(req, balancerow);
+ }
+ List snList = new ArrayList();
+ // 选择孙表对应的序列号结存
+ 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> snmap = VOEntityUtil
+ .groupVOByKeys(new String[] { OnhandDimVO.PK_ONHANDDIM },
+ CollectionUtils.listToArray(snList));
+ for (Map.Entry> entry : snmap
+ .entrySet()) {
+ BalanceOnhandRes res = new BalanceOnhandRes();
+ res.setOnhanddimvo(entry.getValue().get(0).getOnhandDimVO());
+ List listsnvo = new ArrayList();
+ 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 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(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(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 getAllSNValues(T onhandSN) {
+ Set llist = new HashSet();
+ 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;
+ }
+
+ /**
+ * 方法功能描述:平衡计算前的数据预处理 参数说明
+ *
+ * @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(this.onhandReq, OnhandDimVO.getDimContentFields(),
+ new String[] {
+ OnhandDimVO.PK_GROUP, OnhandDimVO.PK_ORG,
+ OnhandDimVO.CWAREHOUSEID, OnhandDimVO.CMATERIALOID,
+ OnhandDimVO.CMATERIALVID,
+ });
+
+ this.mapResults = new HashMap>();
+
+ handvos = this.preAllocHandRes(handvos);
+
+ if (ValueCheckUtil.isNullORZeroLength(handvos)) {
+ this.reqsmatch = null;
+ return;
+ }
+ this.processOnhandData(handvos);
+ }
+
+ /**
+ * 方法功能描述:处理查询后的现存量: 过滤0结存,按统计库存组织+仓库+物料统计实际可以结存 优化后续明细查询 参数说明
+ *
+ * @author yangb
+ * @time 2010-4-10 下午03:10:01
+ */
+ private void processOnhandData(OnhandVO[] handvos) {
+ // 过滤并处理资源数量
+ String key = null;
+ this.mapyethandvo = new HashMap();
+ 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;
+ }
+
+}
diff --git a/ic/src/private/nc/impl/ic/onhand/service/OnhandResServiceImpl.java b/ic/src/private/nc/impl/ic/onhand/service/OnhandResServiceImpl.java
new file mode 100644
index 0000000..9ac80ec
--- /dev/null
+++ b/ic/src/private/nc/impl/ic/onhand/service/OnhandResServiceImpl.java
@@ -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;
+
+/**
+ *
+ * 结存资源服务
+ *
+ * @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> 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> retults =
+ this.pickAutoInner(bills, pickNumNotNull);
+// if (retults == null || retults.size() <= 0) {
+// return bills;
+// }
+ try {
+ List lbodys = new ArrayList();
+ 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 mapPickBodyVOs =
+ new MapList();
+ //根据供应商 客户oid 日期 设置vid的值
+ HashSet cvendoridset = new HashSet();
+ HashSet casscustidset = new HashSet();
+ // 货主客户
+ HashSet ctplcustomeridset = new HashSet();
+ // 寄存供应商
+ HashSet cvmivenderidset = new HashSet();
+ 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 cvendoridMap = new HashMap();
+ HashMap casscustidMap = new HashMap();
+ HashMap ctplcustomeridMap = new HashMap();
+ HashMap cvmivenderidMap = new HashMap();
+ HashMap cvendoridAndDate= new HashMap();
+ HashMap casscustidAndDate= new HashMap();
+ HashMap ctplcustomeridAndDate = new HashMap();
+ HashMap cvmivenderidAndDate = new HashMap();
+ UFDate busidate = AppContext.getInstance().getBusiDate();
+ if (cvendoridset != null && cvendoridset.size() > 0) {
+ for(String cvendorid : cvendoridset) {
+ cvendoridAndDate.put(cvendorid,busidate);
+ }
+ //根据供应商oid和业务日期查询vid
+ cvendoridMap = (HashMap) SupplierPubService.querySupplierVidsByOidAndDate(cvendoridAndDate);
+ }
+ if (casscustidset != null && casscustidset.size() > 0) {
+ for(String casscustid : casscustidset) {
+ casscustidAndDate.put(casscustid,busidate);
+ }
+ //根据客户oid和业务日期查询vid
+ casscustidMap = (HashMap) CustomerPubService.queryCustomerVidsByOidsAndDate(casscustidAndDate);
+ }
+ if (ctplcustomeridset != null && ctplcustomeridset.size() > 0) {
+ for (String ctplcustomerid : ctplcustomeridset) {
+ ctplcustomeridAndDate.put(ctplcustomerid, busidate);
+ }
+ // 根据货主客户oid和业务日期查询vid
+ ctplcustomeridMap = (HashMap) CustomerPubService
+ .queryCustomerVidsByOidsAndDate(ctplcustomeridAndDate);
+ }
+ if (cvmivenderidset != null && cvmivenderidset.size() > 0) {
+ for (String cvmivenderid : cvmivenderidset) {
+ cvmivenderidAndDate.put(cvmivenderid, busidate);
+ }
+ // 根据寄存供应商oid和业务日期查询vid
+ cvmivenderidMap = (HashMap) 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;
+ }
+
+ /**
+ * 方法功能描述:查询单据的现存量(自动主辅计量平衡使用,过滤非自动主辅计量平衡物料)
+ *
+ * 非严格匹配的查询,只用非空维度字段做过滤 默认查询所有维度字段,不做汇总处理,包括可用和不可用的结存
+ *
+ * @param bills 查询维度
+ * @since 6.0
+ * @author yangb
+ * @time 2010-7-8 下午09:18:24
+ */
+ @Override
+ public OnhandVO[] queryOnhandVOByBills(ICBillVO[] bills)
+ throws BusinessException {
+ try {
+ List 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 lbalancevos = new ArrayList();
+ Set keysset = new HashSet();
+ 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;
+ }
+
+ /**
+ * 方法功能描述:查询现存量
+ *
+ * 非严格匹配的查询,只用非空维度字段做过滤 默认查询所有维度字段,不做汇总处理,包括可用和不可用的结存
+ *
+ * @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 ltranstypes = null;
+ if (bytranstype != null) {
+ ltranstypes = new ArrayList();
+ 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> 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 ltranstypes = new ArrayList();
+ List lreqs = new ArrayList();
+ 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> results =
+ new ArrayList>();
+ if (ValueCheckUtil.isNullORZeroLength(lreqs)) {
+ results.add(new OnhandBalanceResult(true));
+ return results;
+ }
+ ICBillOnhandReq[] reqs = new ICBillOnhandReq[lreqs.size()];
+ reqs = lreqs.toArray(reqs);
+ OnhandResBalance resb =
+ new OnhandResBalance(reqs);
+ resb.setCtranstype(ltranstypes);
+
+ resb.onhandBalance();
+ OnhandBalanceResult 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 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> maplist = checkvalue.toMap();
+ List 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 check(String materialField,ISuperVO[] valueObjects) {
+ MapList materialMapList = new MapList();
+ Map materialMap = this.getMaterialMap(materialField, valueObjects);//
+ if (materialMap == null || materialMap.size() == 0) {
+ return null;
+ }
+ Map> 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 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> getMarFrameMap(Map materialMap) {
+ Map> marFrameMap = null;
+ try {
+ Set marFramePkSet = new HashSet();
+ for (Entry 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 getMaterialMap(String materialField, ISuperVO[] valueObjects) {
+ Map materialMap = null;
+ try {
+ Set marPkSet = new HashSet();
+ 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 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();
+ }
+
+ }
+
+ @Override
+ public Map 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();
+ }
+ }
+
+ @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 handkey = null;
+ OnhandQueryDim[] dimconds = new OnhandQueryDim[dimvos.length];
+ for (int i = 0; i < dimvos.length; i++) {
+ handkey =
+ new DimMatchedObj(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);
+ }
+ }
+ }
+
+
+}
diff --git a/ic/src/private/nccloud/pubimpl/ic/pub/service/PickAutoServiceImpl.java b/ic/src/private/nccloud/pubimpl/ic/pub/service/PickAutoServiceImpl.java
new file mode 100644
index 0000000..dddc921
--- /dev/null
+++ b/ic/src/private/nccloud/pubimpl/ic/pub/service/PickAutoServiceImpl.java
@@ -0,0 +1,1153 @@
+package nccloud.pubimpl.ic.pub.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.InvocationInfoProxy;
+import nc.bs.framework.common.NCLocator;
+import nc.bs.ic.pub.env.ICBSContext;
+import nc.impl.pubapp.bd.material.assistant.MarAssistantCheckUtils;
+import nc.impl.pubapp.pattern.database.DataAccessUtils;
+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.itf.scmpub.reference.uap.group.SysInitGroupQuery;
+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.batchcode.BatchSynchronizer;
+import nc.vo.ic.batchcode.ICBatchFields;
+import nc.vo.ic.general.deal.ICBillValueSetter;
+import nc.vo.ic.general.define.ICBillBodyVO;
+import nc.vo.ic.general.define.ICBillVO;
+import nc.vo.ic.general.define.MetaNameConst;
+import nc.vo.ic.location.ICLocationVO;
+import nc.vo.ic.material.define.InvBasAndCalInfo;
+import nc.vo.ic.material.define.InvCalBodyVO;
+import nc.vo.ic.material.define.InvMeasVO;
+import nc.vo.ic.onhand.define.ICBillPickResults;
+import nc.vo.ic.onhand.entity.OnhandDimVO;
+import nc.vo.ic.pub.calc.BusiCalculator;
+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.ic.sncode.ICSnFields;
+import nc.vo.ic.sncode.ICSnForLocationFields;
+import nc.vo.ic.sncode.SnCodeForLocationVOSynchronizer;
+import nc.vo.ic.sncode.SnCodeSynchronizer;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.CircularlyAccessibleValueObject;
+import nc.vo.pub.ISuperVO;
+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.AppContext;
+import nc.vo.pubapp.pattern.data.IRowSet;
+import nc.vo.pubapp.pattern.exception.ExceptionUtils;
+import nc.vo.pubapp.pattern.pub.MapList;
+import nc.vo.pubapp.pattern.pub.MathTool;
+import nc.vo.pubapp.pattern.pub.SqlBuilder;
+import nccloud.commons.collections.MapUtils;
+import nccloud.dto.scmpub.pub.context.BillCardBodyChangedRow;
+import nccloud.dto.scmpub.pub.context.BillCardBodyEditEvent;
+import nccloud.pubimpl.ic.pub.operator.bodyafterrule.NumEventRule;
+import nccloud.pubitf.ic.pub.service.IPickAutoService;
+
+/**
+ * 自动拣货
+ *
+ * @author hujieh
+ *
+ */
+public class PickAutoServiceImpl implements IPickAutoService {
+
+ Map invInfoMap = new HashMap();
+ private Map isasunitstore;
+
+ private BusiCalculator calc = BusiCalculator.getBusiCalculatorAtBS();
+
+
+ @Override
+ public Object autoPick(ICBillVO billvo, Map userObject) {
+ List delbodys = this.processDelBody(new ICBillVO[]{billvo});
+ //拣货前,先清除行备注,防止错误提示
+ this.clearBodyNote(billvo);
+ ICBillVO retBillvo = (ICBillVO) billvo.clone();
+// ICBillBodyVO[] bodyvos = retBillvo.getBodys();
+ this.preprocess(retBillvo);
+ OnhandResService resserver = NCLocator.getInstance().lookup(
+ OnhandResService.class);
+ try {
+
+ // 预留处理
+ ICBillVO[] retvos = NCLocator.getInstance().lookup(ReserveInOut.class)
+ .reserveOutAutoPick(new ICBillVO[] {retBillvo}, false);
+ retBillvo = retvos[0];
+ ICBillBodyVO[] bodyvos = retvos[0].getBodys();
+ //支持预留拣货 modify by yangls7
+// ICBillPickResults results = resserver.reservePickAuto(billvo);
+ ICBillPickResults results = resserver.pickAuto(retBillvo);
+ if (results == null) {
+ this.setBodyNoteOnhandErro(retBillvo.getBodys(), results);
+ return retBillvo;
+ }
+ if(results.isResPick()) {
+ fireNumEditEvent(retBillvo, ICPubMetaNameConst.NNUM, retBillvo.getBody(0).getNnum(), -1, userObject);
+ return retBillvo;
+ }
+ // 查询物料基本信息和库存信息放到invInfoMap中
+ this.loadInvCalBodyInfo(retBillvo);
+ // 逐行遍历,如果这一行没捡到或就设置提示信息
+// this.setBodyNoteOnhandErro(retBillvo.getBodys(), results);
+ // 处理是否辅计量结存,把物料是否勾选了辅单位是否计入结存记录下来
+ this.getBAstunitStorebalance(retBillvo);
+ // 同步序列号档案上信息到孙表
+ this.fillSNDocToLocation(retBillvo, results);
+ List newBodyVOs = new ArrayList();
+ // 设置数据
+ for (int i = 0; i < bodyvos.length; i++) {
+ // 一行表体拣货后的行
+ ICBillBodyVO[] bodys = results.getPickBodys(i);
+ if (bodys == null || bodys.length <= 0) {
+ // 如果此行没有拣货数据,将此行直接放入新表体中
+ newBodyVOs.add(bodyvos[i]);
+ //zhengxinm 次行没有拣货数据 可能在预留时已经拣货 可能拣货成功但是表体备注有问题 这里检查下 如果没问题清空表体备注 2020-11-04
+ if ((bodyvos[i].getNassistnum() != null ? bodyvos[i].getNassistnum() : new UFDouble(0)).doubleValue()
+ ==(bodyvos[i].getNshouldassistnum() != null ? bodyvos[i].getNshouldassistnum() : new UFDouble(0)).doubleValue()) {
+ bodyvos[i].setVnotebody(null);
+ }
+ continue;
+ }
+ // 清空原始行号,用拣货结果设置行号,否则拆行后会行号重复
+ bodyvos[i].setCrowno(null);
+ // this.getEditorModel().getCardPanelWrapper().copyLine();
+ List rowBodyVOs = new ArrayList();
+ for (int k = 0; k < bodys.length; k++) {//不知道这块之前为啥反向遍历 导致行号逆序 改过来了 zhengxinm 2021-03-10
+ if (k == 0) {
+ this.setOnhandDataToBody(bodys[k], bodyvos[i]);
+ if (bodyvos[i].getStatus() != VOStatus.NEW) {
+ bodyvos[i].setStatus(VOStatus.UPDATED);
+ }
+ rowBodyVOs.add(bodyvos[i]);
+ } else {
+ ICBillBodyVO tempBodyvo = (ICBillBodyVO) bodyvos[i].clone();
+ this.processForNewVO(tempBodyvo);
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+ if(k==bodys.length-1){
+ this.setOnhandDataToBody_End(bodys[k], tempBodyvo,rowBodyVOs);
+ }else{
+ this.setOnhandDataToBody(bodys[k], tempBodyvo);
+ }
+ rowBodyVOs.add(tempBodyvo);
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+
+ }
+ }
+ newBodyVOs.addAll(rowBodyVOs);
+ }
+ // 查询出来的对应入库单交易类型为编码,需要转换成主键再走模板翻译
+ this.translateCcorres(newBodyVOs);
+ retBillvo.setChildren(bodyvos[0].getClass(),
+ CollectionUtils.listToArray(newBodyVOs));
+ this.setbodyNote(retBillvo, results);
+ // 同步表体批次辅助字段
+ new BatchSynchronizer(new ICBatchFields()).fillBatchVOtoBill(retBillvo
+ .getBodys());
+ //处理供应商 客户vid字段
+ fireCvendoridEvent(retBillvo.getBodys());
+
+ // 同步表体序列号辅助字段
+ new SnCodeSynchronizer(new ICSnFields()).fillBatchVOtoBill(retBillvo
+ .getBodys());
+ fireNumEditEvent(retBillvo, ICPubMetaNameConst.NNUM, newBodyVOs.get(0).getNnum(), -1, userObject);
+
+ } catch (BusinessException e) {
+ ExceptionUtils.wrappBusinessException(e.getMessage());
+ }
+ CircularlyAccessibleValueObject[] allChildrenVO = retBillvo.getAllChildrenVO();
+ CollectionUtils.addArrayToList(delbodys, (ICBillBodyVO[])allChildrenVO);
+ retBillvo.setChildrenVO(CollectionUtils.listToArray(delbodys));
+ return retBillvo;
+ }
+
+ private void setOnhandDataToBody_End(ICBillBodyVO bodyvo, ICBillBodyVO origin, List newBodyVOs) {
+ if (bodyvo == null) {
+ return;
+ }
+ // 表体主键复制,防止拣货拆行后,主键重复
+// origin
+// .setAttributeValue(MetaNameConst.CGENERALBID, bodyvo.getCgeneralbid());
+ // 行号设置,已经清空原始行号,用拣货结果设置
+ origin.setAttributeValue(ICPubMetaNameConst.CROWNO, bodyvo.getCrowno());
+ this.processOnhandDimInfo(bodyvo, origin);
+ // 货位管理仓,货位信息单独处理
+ this.resetBodyLocationID(bodyvo, origin);
+ this.processCcorrespondInfo(bodyvo, origin);
+
+ this.processNumInfo_End(bodyvo, origin,newBodyVOs);
+ this.setSNInfoToBody(bodyvo, origin);
+ }
+
+ private void processNumInfo_End(ICBillBodyVO bodyvo, ICBillBodyVO origin, List newBodyVOs) {
+ origin.setAttributeValue(ICPubMetaNameConst.NNUM, bodyvo.getNnum());
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM, bodyvo.getNassistnum());
+ origin.setAttributeValue(ICPubMetaNameConst.NGROSSNUM,
+ bodyvo.getNgrossnum());
+ //计算前几行的应发数量合
+ UFDouble sumShouldNum=UFDouble.ZERO_DBL;
+ UFDouble sumShouldAssistNum=UFDouble.ZERO_DBL;
+ for(ICBillBodyVO bodyVO:newBodyVOs){
+ UFDouble nShouldnum = bodyVO.getNshouldnum();
+ UFDouble nShouldAssistNum = bodyVO.getNshouldassistnum();
+ sumShouldNum= MathTool.add(sumShouldNum,nShouldnum);
+ sumShouldAssistNum= MathTool.add(sumShouldAssistNum,nShouldAssistNum);
+ }
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+ origin.setAttributeValue(ICPubMetaNameConst.NSHOULDNUM, MathTool.sub(bodyvo.getNshouldnum(),sumShouldNum) );
+ origin.setAttributeValue(ICPubMetaNameConst.NSHOULDASSISTNUM, MathTool.sub(bodyvo.getNshouldassistnum(),sumShouldAssistNum));
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+
+ UFDouble shouldnum = origin.getNshouldnum();
+ UFDouble shouldastnum = origin.getNshouldassistnum();
+ UFDouble num = origin.getNnum();
+ if (NCBaseTypeUtils.isNullOrZero(shouldnum)
+ && NCBaseTypeUtils.isNullOrZero(shouldastnum)
+ && NCBaseTypeUtils.isNullOrZero(num)) {
+ return;
+ }
+
+ InvCalBodyVO calbodyvo = invInfoMap.get(origin.getCmaterialvid())
+ .getInvcalbodyvo();
+
+ // 清空辅数量,避免辅数量是拣货前数量,影响联动计算
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM, null);
+ // v636版本 单品管理的处理改变
+ if (ValueCheckUtil.isTrue(calbodyvo.getSerialmanaflag())) {
+ origin.setAttributeValue(ICPubMetaNameConst.NNUM, bodyvo.getNnum());
+// this.caculateAfterNumEdit(bodyvo);
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM,
+ bodyvo.getNassistnum());
+ boolean isNullServialcode = StringUtil.isSEmptyOrNullForAll(VOEntityUtil
+ .getVOsValuesNotDel(bodyvo.getLocationVOs(),
+ ICLocationVO.VSERIALCODE, String.class));
+ if (bodyvo.getLocationVOs() != null && isNullServialcode) {
+ this.processLocAstNum(bodyvo);
+ }
+// origin.setLocationVOs(bodyvo.getLocationVOs());
+ ICLocationVO[] lvos = origin.getLocationVOs();
+ ICLocationVO[] lvos2 = bodyvo.getLocationVOs();
+ if(lvos2 != null) {
+ //这里获取的pks可能是[null,null,...] 这样的 增加过滤
+ String[] lpks = VOEntityUtil.getVOsValuesNotDel(lvos == null ? new ICLocationVO[] {} : lvos,
+ ICLocationVO.PK_SERIALCODE, String.class);
+ List lpkList = new ArrayList();
+ if (lpks != null && lpks.length > 0) {
+ for (String lpk : lpks) {
+ if (lpk != null) {
+ lpkList.add(lpk);
+ }
+ }
+ }
+
+ //这里获取的pks可能是[null,null,...] 这样的 增加过滤
+
+ if(lpkList.size() > 0) {
+ int needNum = shouldnum.intValue();
+
+ for (ICLocationVO lvo : lvos2) {
+ if(!lpkList.contains(lvo.getPk_serialcode()) && lvos.length < needNum) {
+ lvos = CollectionUtils.combineArrs(lvos, new ICLocationVO[] {lvo});
+// needNum--;
+ }
+ }
+ } else {
+ lvos = CollectionUtils.combineArrs(lvos, lvos2);
+ }
+ }
+ origin.setLocationVOs(lvos);
+ return;
+ }
+
+// this.caculateAfterNumEdit(bodyvo);
+ // 对于辅计量记结存的物料,计算辅数量之后,会导致界面展示和结存数据不一致,所以用结存数据设置
+ if (!ValueCheckUtil.isNullORZeroLength(this.isasunitstore)) {
+ if (ValueCheckUtil.isTrue(this.isasunitstore.get((String) origin
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID)
+ + (String) origin.getAttributeValue(ICPubMetaNameConst.CASTUNITID)))) {
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM,
+ bodyvo.getNassistnum());
+ } else {
+ bodyvo.setNassistnum(calc.calculateAstNum(bodyvo.getNnum(),
+ (String) origin.getAttributeValue(ICPubMetaNameConst.VCHANGERATE),
+ bodyvo.getCasscustid()));
+ }
+ }
+
+ if (bodyvo.getLocationVOs() != null) {
+ this.processLocAstNum(bodyvo);
+ origin.setLocationVOs(bodyvo.getLocationVOs());
+ }
+ }
+
+ /**
+ * 查询出来的对应入库单交易类型为编码,需要转换成主键再走模板翻译
+ * @param newBodyVOs
+ */
+ private void translateCcorres(List newBodyVOs) {
+ Set codeSet = new HashSet();
+ if(newBodyVOs != null && newBodyVOs.size() > 0) {
+ for(ICBillBodyVO bodyVO : newBodyVOs) {
+ codeSet.add(bodyVO.getCcorrespondtranstype());
+ }
+ }
+ Map idMap = new HashMap();
+ if(codeSet.size() > 0) {
+ String pk_group = InvocationInfoProxy.getInstance().getGroupId();
+ SqlBuilder sql = new SqlBuilder();
+ sql.append(" select pk_billtypecode, pk_billtypeid from bd_billtype where ");
+ sql.append(" pk_group ", pk_group);
+ sql.append(" and ");
+ sql.append( " pk_billtypecode ", codeSet.toArray(new String[codeSet.size()]));
+ IRowSet query = new DataAccessUtils().query(sql.toString());
+ while (query.next()) {
+ idMap.put(query.getString(0), query.getString(1));
+ }
+ }
+ if(MapUtils.isNotEmpty(idMap)) {
+ for(ICBillBodyVO bodyVO : newBodyVOs) {
+ bodyVO.setCcorrespondtranstype(idMap.get(bodyVO.getCcorrespondtranstype()));
+ }
+ }
+ }
+
+
+ private void fireCvendoridEvent(ICBillBodyVO[] bodys) {
+ if (bodys == null || bodys.length == 0) {
+ return;
+ }
+ HashSet cvendoridset = new HashSet();
+ HashSet casscustidset = new HashSet();
+ // 货主客户
+ HashSet ctplcustomeridset = new HashSet();
+ // 寄存供应商
+ HashSet cvmivenderidset = new HashSet();
+ for (ICBillBodyVO body : bodys) {
+ 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 cvendoridMap = new HashMap();
+ HashMap casscustidMap = new HashMap();
+ HashMap cvendoridAndDate= new HashMap();
+ HashMap casscustidAndDate= new HashMap();
+ HashMap ctplcustomeridMap = new HashMap();
+ HashMap cvmivenderidMap = new HashMap();
+ HashMap ctplcustomeridAndDate = new HashMap();
+ HashMap cvmivenderidAndDate = new HashMap();
+ UFDate busidate = AppContext.getInstance().getBusiDate();
+ if (cvendoridset != null && cvendoridset.size() > 0) {
+ for(String cvendorid : cvendoridset) {
+ cvendoridAndDate.put(cvendorid,busidate);
+ }
+ //根据供应商oid和业务日期查询vid
+ cvendoridMap = (HashMap) SupplierPubService.querySupplierVidsByOidAndDate(cvendoridAndDate);
+ }
+ if (casscustidset != null && casscustidset.size() > 0) {
+ for(String casscustid : casscustidset) {
+ casscustidAndDate.put(casscustid,busidate);
+ }
+ //根据客户oid和业务日期查询vid
+ casscustidMap = (HashMap) CustomerPubService.queryCustomerVidsByOidsAndDate(casscustidAndDate);
+ }
+ if (ctplcustomeridset != null && ctplcustomeridset.size() > 0) {
+ for (String ctplcustomerid : ctplcustomeridset) {
+ ctplcustomeridAndDate.put(ctplcustomerid, busidate);
+ }
+ // 根据货主客户oid和业务日期查询vid
+ ctplcustomeridMap = (HashMap) CustomerPubService
+ .queryCustomerVidsByOidsAndDate(ctplcustomeridAndDate);
+ }
+ if (cvmivenderidset != null && cvmivenderidset.size() > 0) {
+ for (String cvmivenderid : cvmivenderidset) {
+ cvmivenderidAndDate.put(cvmivenderid, busidate);
+ }
+ // 根据寄存供应商oid和业务日期查询vid
+ cvmivenderidMap = (HashMap) SupplierPubService
+ .querySupplierVidsByOidAndDate(cvmivenderidAndDate);
+ }
+ //根据客户 供应商oid对vid赋值
+ for (ICBillBodyVO body : bodys) {
+ 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()));
+ }
+ }
+ }
+
+ private List processDelBody(ICBillVO[] vos) {
+ ICBillBodyVO[] bodys = vos[0].getBodys();
+ List realbody = new ArrayList();
+ List delbodys = new ArrayList();
+ for (ICBillBodyVO body : bodys) {
+ if (body.getStatus() != 3) {
+ realbody.add(body);
+ } else {
+ delbodys.add(body);
+ }
+ }
+ vos[0].setChildrenVO(null);
+ vos[0].setChildrenVO(CollectionUtils.listToArray(realbody));
+ return delbodys;
+ }
+
+ /**
+ * 主数量编辑后处理
+ *
+ * @param row
+ * @param newnum
+ * @param oldnum
+ */
+ private void fireNumEditEvent(ICBillVO billvo, String numField,
+ UFDouble num, int index, Map userObject) {
+ //获取拣货后的billvo的实发数量存放到数量编辑后事件之后的新vo里
+ Map nassistnumMap = new HashMap<>();
+ Map nnumMap = new HashMap<>();
+ CircularlyAccessibleValueObject[] bodys = billvo.getAllChildrenVO();
+ int i = 0;
+ for (CircularlyAccessibleValueObject body : bodys) {
+ UFDouble nassistnum = (UFDouble) body.getAttributeValue(MetaNameConst.NASSISTNUM);
+ UFDouble nnum = (UFDouble) body.getAttributeValue(MetaNameConst.NNUM);
+ String crowno = (String) body.getAttributeValue(MetaNameConst.CROWNO);
+ if(crowno == null) {
+ i = i + 10;
+ crowno = i + "";
+ body.setAttributeValue(MetaNameConst.CROWNO, crowno);
+ }
+ nassistnumMap.put(crowno, nassistnum);
+ nnumMap.put(crowno, nnum);
+ }
+
+ BillCardBodyChangedRow changedRow = new BillCardBodyChangedRow(num,
+ null, null);
+ BillCardBodyEditEvent event = new BillCardBodyEditEvent(numField,
+ index, new BillCardBodyChangedRow[] { changedRow }, null);
+ new NumEventRule().afterEdit(billvo, event, userObject);
+
+ CircularlyAccessibleValueObject[] newBodys = billvo.getAllChildrenVO();
+ for (CircularlyAccessibleValueObject body : newBodys) {
+ if(nassistnumMap.get(body.getAttributeValue(MetaNameConst.CROWNO)) != null) {
+ body.setAttributeValue(MetaNameConst.NASSISTNUM, nassistnumMap.get(body.getAttributeValue(MetaNameConst.CROWNO)));
+ }
+ if(nnumMap.get(body.getAttributeValue(MetaNameConst.CROWNO)) != null) {
+ body.setAttributeValue(MetaNameConst.NNUM, nnumMap.get(body.getAttributeValue(MetaNameConst.CROWNO)));
+ }
+ }
+ }
+
+ /**
+ * 拣货结果不满足应发数量的备注设置成“现存量不足” 分批的场景,只设置第一行。 方法功能描述:
+ *
+ * 参数说明
+ *
+ * @param bodys
+ *
+ * @since 6.3
+ * @author zhaofeid
+ * @time 2013-7-31 下午04:45:39
+ */
+ private void setbodyNote(ICBillVO billvo, ICBillPickResults results) {
+ ICBillBodyVO[] uiBodys = billvo.getBodys();
+ String errMsg = OnhandRes.getOnhandErro();
+ Set origRowNo = new HashSet();
+
+
+ int realIndex = 0;
+ int pickIndex = 1;//拣货下标
+ for (int i = 0, loop = uiBodys.length; i < loop; i++) {
+ if(uiBodys[i].getNshouldassistnum() == null && uiBodys[i].getNshouldnum() == null) {
+ continue;
+ }
+
+ ICBillBodyVO[] bodys = results.getPickBodys(realIndex);
+ if (ValueCheckUtil.isNullORZeroLength(bodys)) {
+ continue;
+ }
+
+ ICBillBodyVO uibody = uiBodys[i];
+ UFDouble nshouldnum = uibody.getNshouldnum();
+ String crowno = uibody.getCrowno();
+ for (ICBillBodyVO body : bodys) {
+ //防止多次计算,添加货位判断,同一行表体拣货拆分行后,表体行和拣货行货位相同--sdlizheng start
+ if(body.getClocationid().equals(uibody.getClocationid())){
+ UFDouble nnum = body.getNnum();
+ nshouldnum = nshouldnum.sub(nnum);
+ }
+ //防止多次计算,添加货位判断,同一行表体拣货拆分行后,表体行和拣货行货位相同--sdlizheng start
+ }
+
+ if (nshouldnum!=null && UFDouble.ZERO_DBL.compareTo(nshouldnum) < 0) {
+ origRowNo.add(crowno);
+ }
+ //sdlizheng --因为拣货拆行,获取pickbodys时的下标row需要循环完此次已拣货的行数之后加1--start
+ if(pickIndex==bodys.length){
+ realIndex++;
+ pickIndex=1;
+ }else {
+ pickIndex++;
+ }
+ //sdlizheng --因为拣货拆行,获取pickbodys时的下标row需要循环完此次已拣货的行数之后加1--end
+ }
+ for (int i = 0; i < uiBodys.length; i++) {
+ String rowno = (String) uiBodys[i]
+ .getAttributeValue(ICPubMetaNameConst.CROWNO);
+ if (origRowNo.contains(rowno)) {
+ uiBodys[i].setAttributeValue(ICPubMetaNameConst.VNOTEBODY, errMsg);
+ }
+ }
+ }
+
+ private void processForNewVO(ICBillBodyVO tempBodyvo) {
+ // 由于粘贴行会把复制行的报价数量带过来,导致浮动换算率时计算报价换算率错误
+ tempBodyvo.setAttributeValue(MetaNameConst.NQTUNITNUM, null);
+ tempBodyvo.setAttributeValue(ICPubMetaNameConst.NSHOULDNUM, null);
+ tempBodyvo.setAttributeValue(ICPubMetaNameConst.NSHOULDASSISTNUM, null);
+ tempBodyvo.setAttributeValue(ICPubMetaNameConst.NNUM, null);
+ tempBodyvo.setAttributeValue(ICPubMetaNameConst.NASSISTNUM, null);
+ tempBodyvo.setAttributeValue(MetaNameConst.CGENERALBID, null);
+ tempBodyvo.setLocationVOs(null);
+ tempBodyvo.setAttributeValue("rowid", null);
+ tempBodyvo.setStatus(VOStatus.NEW);
+
+ //清除扩展表数据
+ clearExtendTableData(tempBodyvo);
+ }
+
+ private void clearExtendTableData(ICBillBodyVO tempBodyvo) {
+ String[] extendTableField = new String[] { "naccumvminum",
+ "ncorrespondgrsnum", "ncorrespondastnum", "ncorrespondnum",
+ "naccumoutsignnum", "naccumoutbacknum", "nrushnum", "nsignnum",
+ "ntotaltrannum", "btranendflag", "naccumwastnum", "csumid" };
+ for(String field : extendTableField) {
+ tempBodyvo.setAttributeValue(field, null);
+ }
+ }
+
+ private void setOnhandDataToBody(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ if (bodyvo == null) {
+ return;
+ }
+ // 表体主键复制,防止拣货拆行后,主键重复
+// origin
+// .setAttributeValue(MetaNameConst.CGENERALBID, bodyvo.getCgeneralbid());
+ // 行号设置,已经清空原始行号,用拣货结果设置
+ origin.setAttributeValue(ICPubMetaNameConst.CROWNO, bodyvo.getCrowno());
+ this.processOnhandDimInfo(bodyvo, origin);
+ // 货位管理仓,货位信息单独处理
+ this.resetBodyLocationID(bodyvo, origin);
+ this.processCcorrespondInfo(bodyvo, origin);
+
+ this.processNumInfo(bodyvo, origin);
+ this.setSNInfoToBody(bodyvo, origin);
+ }
+
+ private void setSNInfoToBody(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ // 处理表体序列号
+ if (!SysInitGroupQuery.isSNEnabled()) {
+ return;
+ }
+ UFDouble nassistnum = (UFDouble) origin
+ .getAttributeValue(ICPubMetaNameConst.NASSISTNUM);
+ // 只有表体数量为1时才设置表体值
+ if (!NCBaseTypeUtils.isEquals(nassistnum, UFDouble.ONE_DBL)) {
+ return;
+ }
+ ICLocationVO[] lvoes = origin.getLocationVOs();
+ //因为捡完第一次货删了实发数量重新拣货之后,孙表虽然不是一个,但没被删除的只有一个
+ if(lvoes != null && lvoes.length > 0) {
+ List lvoLists = new ArrayList<>();
+ for(ICLocationVO lvo : lvoes) {
+ if(VOStatus.DELETED != lvo.getStatus()) {
+ lvoLists.add(lvo);
+ }
+ }
+ ICLocationVO[] lvos = lvoLists.toArray(new ICLocationVO[] {});
+ if (ValueCheckUtil.isNullORZeroLength(lvos) || lvos.length != 1) {
+ return;
+ }
+ ICLocationVO lvo = lvos[0];
+ if (StringUtil.isNullStringOrNull(lvo.getVserialcode())
+ && StringUtil.isNullStringOrNull(lvo.getPk_serialcode())) {
+ return;
+ }
+ origin.setAttributeValue(ICPubMetaNameConst.VSERIALCODE,
+ lvos[0].getVserialcode());
+ origin.setAttributeValue(ICPubMetaNameConst.PK_SERIALCODE,
+ lvos[0].getPk_serialcode());
+ }
+ }
+
+ private void processNumInfo(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ origin.setAttributeValue(ICPubMetaNameConst.NNUM, bodyvo.getNnum());
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM, bodyvo.getNassistnum());
+ origin.setAttributeValue(ICPubMetaNameConst.NGROSSNUM,
+ bodyvo.getNgrossnum());
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+ origin.setAttributeValue(ICPubMetaNameConst.NSHOULDNUM, bodyvo.getNnum());
+ origin.setAttributeValue(ICPubMetaNameConst.NSHOULDASSISTNUM, bodyvo.getNassistnum());
+ //78--2025年4月9日19点11分--sdlizheng--实发传输到应发,最后一行做合计处理--start
+
+ UFDouble shouldnum = origin.getNshouldnum();
+ UFDouble shouldastnum = origin.getNshouldassistnum();
+ UFDouble num = origin.getNnum();
+ if (NCBaseTypeUtils.isNullOrZero(shouldnum)
+ && NCBaseTypeUtils.isNullOrZero(shouldastnum)
+ && NCBaseTypeUtils.isNullOrZero(num)) {
+ return;
+ }
+
+ InvCalBodyVO calbodyvo = invInfoMap.get(origin.getCmaterialvid())
+ .getInvcalbodyvo();
+
+ // 清空辅数量,避免辅数量是拣货前数量,影响联动计算
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM, null);
+ // v636版本 单品管理的处理改变
+ if (ValueCheckUtil.isTrue(calbodyvo.getSerialmanaflag())) {
+ origin.setAttributeValue(ICPubMetaNameConst.NNUM, bodyvo.getNnum());
+// this.caculateAfterNumEdit(bodyvo);
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM,
+ bodyvo.getNassistnum());
+ boolean isNullServialcode = StringUtil.isSEmptyOrNullForAll(VOEntityUtil
+ .getVOsValuesNotDel(bodyvo.getLocationVOs(),
+ ICLocationVO.VSERIALCODE, String.class));
+ if (bodyvo.getLocationVOs() != null && isNullServialcode) {
+ this.processLocAstNum(bodyvo);
+ }
+// origin.setLocationVOs(bodyvo.getLocationVOs());
+ ICLocationVO[] lvos = origin.getLocationVOs();
+ ICLocationVO[] lvos2 = bodyvo.getLocationVOs();
+ if(lvos2 != null) {
+ //这里获取的pks可能是[null,null,...] 这样的 增加过滤
+ String[] lpks = VOEntityUtil.getVOsValuesNotDel(lvos == null ? new ICLocationVO[] {} : lvos,
+ ICLocationVO.PK_SERIALCODE, String.class);
+ List lpkList = new ArrayList();
+ if (lpks != null && lpks.length > 0) {
+ for (String lpk : lpks) {
+ if (lpk != null) {
+ lpkList.add(lpk);
+ }
+ }
+ }
+
+ //这里获取的pks可能是[null,null,...] 这样的 增加过滤
+
+ if(lpkList.size() > 0) {
+ int needNum = shouldnum.intValue();
+
+ for (ICLocationVO lvo : lvos2) {
+ if(!lpkList.contains(lvo.getPk_serialcode()) && lvos.length < needNum) {
+ lvos = CollectionUtils.combineArrs(lvos, new ICLocationVO[] {lvo});
+// needNum--;
+ }
+ }
+ } else {
+ lvos = CollectionUtils.combineArrs(lvos, lvos2);
+ }
+ }
+ origin.setLocationVOs(lvos);
+ return;
+ }
+
+// this.caculateAfterNumEdit(bodyvo);
+ // 对于辅计量记结存的物料,计算辅数量之后,会导致界面展示和结存数据不一致,所以用结存数据设置
+ if (!ValueCheckUtil.isNullORZeroLength(this.isasunitstore)) {
+ if (ValueCheckUtil.isTrue(this.isasunitstore.get((String) origin
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID)
+ + (String) origin.getAttributeValue(ICPubMetaNameConst.CASTUNITID)))) {
+ origin.setAttributeValue(ICPubMetaNameConst.NASSISTNUM,
+ bodyvo.getNassistnum());
+ } else {
+ bodyvo.setNassistnum(calc.calculateAstNum(bodyvo.getNnum(),
+ (String) origin.getAttributeValue(ICPubMetaNameConst.VCHANGERATE),
+ bodyvo.getCasscustid()));
+ }
+ }
+
+ if (bodyvo.getLocationVOs() != null) {
+ this.processLocAstNum(bodyvo);
+ origin.setLocationVOs(bodyvo.getLocationVOs());
+ }
+ }
+
+
+
+ /**
+ * 处理货位信息的辅数量,进行重新计算,并处理尾差,解决存量不足时货位单品信息数量错误的问题。
+ *
+ * @param body
+ * @param cal
+ */
+ private void processLocAstNum(ICBillBodyVO body) {
+ ICLocationVO[] locs = body.getLocationVOs();
+ if (ValueCheckUtil.isNullORZeroLength(locs)) {
+ return;
+ }
+
+ UFDouble bodynum = body.getNassistnum();
+ UFDouble nsum = UFDouble.ZERO_DBL;
+ UFDouble nassistnum = UFDouble.ZERO_DBL;
+ for (int i = 0; i < locs.length - 1; i++) {
+ // 此处无论是否单品管理,都需要处理辅数量,否则有货位信息时,更新存量会有问题
+ nassistnum = calc.calculateAstNum(locs[i].getNnum(),
+ body.getVchangerate(), body.getCastunitid());
+
+ locs[i].setNassistnum(nassistnum);
+ nsum = NCBaseTypeUtils.add(nsum, nassistnum);
+ }
+ if (locs.length != 1) {
+ locs[locs.length - 1].setNassistnum(NCBaseTypeUtils.sub(bodynum, nsum));
+ } else if (locs.length == 1) {
+ locs[0].setNassistnum(bodynum);
+ }
+ }
+
+ private void processCcorrespondInfo(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ String[] corresponds = new String[] { MetaNameConst.CCORRESPONDTYPE,
+ MetaNameConst.CCORRESPONDTRANSTYPE, MetaNameConst.CCORRESPONDCODE,
+ MetaNameConst.CCORRESPONDHID, MetaNameConst.CCORRESPONDBID,
+ MetaNameConst.CCORRESPONDROWNO, ICPubMetaNameConst.CROWNO,
+ ICPubMetaNameConst.NCOSTMNY, ICPubMetaNameConst.NPLANNEDMNY,
+ MetaNameConst.DBIZDATE, ICPubMetaNameConst.VNOTEBODY };
+ String cmateiralvid = (String) origin
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID);
+ InvCalBodyVO invvo = this.invInfoMap.get(cmateiralvid).getInvcalbodyvo();
+ // 对于非出入库跟踪物料,不处理对应入库单信息,否则会把原始信息清掉(出库参照入库单拉单)
+ if (invvo == null || !ValueCheckUtil.isTrue(invvo.getOuttrackin())) {
+ return;
+ }
+ for (String field : corresponds) {
+ origin.setAttributeValue(field, bodyvo.getAttributeValue(field));
+ }
+ }
+
+ /**
+ * 重新设置表体货位ID,如果单品信息分布在多个货位,清空表体,否则,设置单品货位信息到表体
+ *
+ * @param bodyvo拣货结果
+ * @param row
+ * 当前行
+ */
+ private void resetBodyLocationID(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ ICLocationVO[] locs = bodyvo.getLocationVOs();
+
+ if (ValueCheckUtil.isNullORZeroLength(locs)) {
+ return;
+ }
+
+ List locids = VOEntityUtil.getVOsValueListNotDel(locs,
+ ICLocationVO.CLOCATIONID);
+ if (ValueCheckUtil.isNullORZeroLength(locids)) {
+ return;
+ }
+
+ String locid = locids.get(0);
+ for (String id : locids) {
+ if (!StringUtil.isStringEqual(locid, id)) {
+ locid = null;
+ break;
+ }
+ }
+ origin.setAttributeValue(ICPubMetaNameConst.CLOCATIONID, locid);
+ }
+
+ private void processOnhandDimInfo(ICBillBodyVO bodyvo, ICBillBodyVO origin) {
+ for (String field : OnhandDimVO.getDimContentFields()) {
+ if (field.equals(OnhandDimVO.VBATCHCODE)) {
+ origin.setAttributeValue(field, bodyvo.getAttributeValue(field));
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CLOCATIONID)) {
+ // V60,货位管理仓,货位信息单独处理
+ continue;
+ }
+ // 拣出的货非换算率记结存场合,不包含换算率信息
+ if (field.equals(OnhandDimVO.VCHANGERATE)
+ && StringUtil.isSEmptyOrNull(bodyvo.getVchangerate())) {
+ continue;
+ }
+ // 固定辅助属性(库存状态、项目、供应商、生产厂商、客户)
+ if (field.equals(OnhandDimVO.CSTATEID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCstateid())) {
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CPROJECTID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCprojectid())) {
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CVENDORID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCvendorid())) {
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CPRODUCTORID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCproductorid())) {
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CASSCUSTID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCasscustid())) {
+ continue;
+ }
+ if (field.equals(OnhandDimVO.CFFILEID)
+ && StringUtil.isSEmptyOrNull(bodyvo.getCffileid())) {
+ continue;
+ }
+ origin.setAttributeValue(field, bodyvo.getAttributeValue(field));
+ }
+ }
+
+ /**
+ * 拣货之前,清除旧的备注
+ *
+ * @param uiBodys
+ */
+ private void clearBodyNote(ICBillVO billvo) {
+ ICBillBodyVO[] bodyvos = billvo.getBodys();
+ for (int i = 0; i < bodyvos.length; i++) {
+ bodyvos[i].setAttributeValue(ICPubMetaNameConst.NNUM, null);
+ bodyvos[i].setAttributeValue(ICPubMetaNameConst.NASSISTNUM, null);
+// String vnote = (String) bodyvos[i]
+// .getAttributeValue(ICPubMetaNameConst.VNOTEBODY);
+// if (StringUtil.isSEmptyOrNull(vnote)
+// || vnote.indexOf(OnhandRes.getOnhandErro()) < 0) {
+// continue;
+// }
+ bodyvos[i].setAttributeValue(ICPubMetaNameConst.VNOTEBODY, null);
+ }
+ }
+
+ /**
+ * 拣货前预处理:清空实发数量、清空表体备注、格式化记结存的变动换算率
+ */
+ private void preprocess(ICBillVO billvo) {
+ // 清空单据表体数据
+// for (ICBillBodyVO body : billvo.getBodys()) {
+// ICLocationVO[] locationVOs = body.getLocationVOs();
+// if(locationVOs != null) {
+// for (ICLocationVO icLocationVO : locationVOs) {
+// icLocationVO.setStatus(3);
+// }
+// }
+// body.setLocationVOs(locationVOs);
+// }
+ 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(billvo);
+ }
+ } catch (BusinessException e) {
+ ExceptionUtils.wrappException(e);
+ }
+ // 统一处理变动换算率格式,否则与结存的换算率格式不匹配
+ new ICBillValueSetter().procChangeRateFormat(new ICBillVO[] { billvo },
+ new ICBSContext().getInvInfo());
+ }
+
+ /**
+ * 拣货前处理 物料启用了布尔类型自由辅助属性 导致存量维度不匹配
+ */
+ @SuppressWarnings("unchecked")
+ private void processFreeDef(ICBillVO billvo) {
+ Class extends ISuperVO> clazz = (Class extends ISuperVO>) billvo.getClass();
+ MapList checkvalue = check(ICPubMetaNameConst.CMATERIALVID, billvo.getChildren(clazz));
+ 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")) ) {
+ bodyvo.setAttributeValue(index, null);
+ }
+ }
+ } else {
+ Map> maplist = checkvalue.toMap();
+ List 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"))) {
+ if(list==null || !list.contains(index)) {
+ bodyvo.setAttributeValue(index, null);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public MapList check(String materialField,ISuperVO[] valueObjects) {
+ MapList materialMapList = new MapList();
+ Map materialMap = this.getMaterialMap(materialField, valueObjects);
+ if (materialMap == null || materialMap.size() == 0) {
+ return null;
+ }
+ Map> 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 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> getMarFrameMap(Map materialMap) {
+ Map> marFrameMap = null;
+ try {
+ Set marFramePkSet = new HashSet();
+ for (Entry 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 getMaterialMap(String materialField, ISuperVO[] valueObjects) {
+ Map materialMap = null;
+ try {
+ Set marPkSet = new HashSet();
+ 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;
+ }
+
+
+
+ /**
+ * 没有拣到存量的行,设置表体备注“现存量不足”
+ *
+ * @param uiBodys
+ * @param results
+ */
+ private void setBodyNoteOnhandErro(ICBillBodyVO[] uiBodys,
+ ICBillPickResults results) {
+ String errMsg = OnhandRes.getOnhandErro();
+ if (results == null) {
+ for (int i = 0, loop = uiBodys.length; i < loop; i++) {
+
+ if (null == uiBodys[i]
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID)) {
+ continue;
+ }
+ if (!NCBaseTypeUtils.isNullOrZero((UFDouble) uiBodys[i]
+ .getAttributeValue(ICPubMetaNameConst.NNUM))) {
+ continue;
+ }
+ uiBodys[i].setAttributeValue(ICPubMetaNameConst.VNOTEBODY, errMsg);
+// uiBodys[i].setAttributeValue(ICPubMetaNameConst.CROWNO, i);
+ }
+ return;
+ }
+
+ for (int i = 0, loop = uiBodys.length; i < loop; i++) {
+ ICBillBodyVO[] bodys = results.getPickBodys(i);
+ if (!ValueCheckUtil.isNullORZeroLength(bodys)) {
+ continue;
+ }
+
+ if (null == uiBodys[i].getAttributeValue(ICPubMetaNameConst.CMATERIALVID)) {
+ continue;
+ }
+ if (!NCBaseTypeUtils.isNullOrZero((UFDouble) uiBodys[i]
+ .getAttributeValue(ICPubMetaNameConst.NNUM))) {
+ continue;
+ }
+ uiBodys[i].setAttributeValue(ICPubMetaNameConst.VNOTEBODY, errMsg);
+ }
+
+ }
+
+ private void loadInvCalBodyInfo(ICBillVO billvo) {
+ String pk_org = (String) billvo.getHead().getAttributeValue(
+ ICPubMetaNameConst.PK_ORG);
+ ICBillBodyVO[] uiBodys = billvo.getBodys();
+ Set invpks = new HashSet();
+ for (int i = 0; i < uiBodys.length; i++) {
+ String cmaterialvid = (String) uiBodys[i]
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID);
+ if (StringUtil.isSEmptyOrNull(cmaterialvid)) {
+ continue;
+ }
+ invpks.add(cmaterialvid);
+ }
+
+ if (invpks.size() == 0) {
+ return;
+ }
+ InvBasAndCalInfo[] invInfos = new ICBSContext().getInvInfo()
+ .getInvBasAndCalInfo(pk_org, invpks.toArray(new String[0]));
+ if (invInfos == null || invInfos.length == 0) {
+ return;
+ }
+ // this.invcalbodysmap =
+ // CollectionUtils.hashVOArray(MaterialStockVO.PK_MATERIAL, invInfos);
+ this.invInfoMap = this.setInvBasInfosToMap(invInfos);
+ }
+
+ private Map setInvBasInfosToMap(
+ InvBasAndCalInfo[] invInfos) {
+ Map infoMap = new HashMap();
+ for (InvBasAndCalInfo info : invInfos) {
+ // BUG:如果没有分配到库存组织,就跳过,否则会报错
+ if (info == null || info.getInvcalbodyvo() == null) {
+ continue;
+ }
+ String key = info.getInvcalbodyvo().getPk_material();
+ infoMap.put(key, info);
+ }
+ return infoMap;
+ }
+
+ /**
+ * 得到界面的物料是否辅计量记结存
+ *
+ * @return
+ */
+ private void getBAstunitStorebalance(ICBillVO billvo) {
+ ICBillBodyVO[] bodyvos = billvo.getBodys();
+ this.isasunitstore = null;
+ Set invmeasPkSet = new HashSet();
+ List invpks = new ArrayList();
+ List measpks = new ArrayList();
+ for (int i = 0; i < bodyvos.length; i++) {
+ String invpk = (String) bodyvos[i]
+ .getAttributeValue(ICPubMetaNameConst.CMATERIALVID);
+ if (StringUtil.isSEmptyOrNull(invpk)) {
+ continue;
+ }
+ String measpk = (String) bodyvos[i]
+ .getAttributeValue(ICPubMetaNameConst.CASTUNITID);
+ ;
+ if (StringUtil.isSEmptyOrNull(measpk)) {
+ continue;
+ }
+ String key = invpk + measpk;
+ if (!invmeasPkSet.contains(key)) {
+ invmeasPkSet.add(key);
+ invpks.add(invpk);
+ measpks.add(measpk);
+ }
+
+ }
+ InvMeasVO[] invmeasvos = new ICBSContext().getInvInfo().getInvMeasVO(
+ invpks.toArray(new String[invpks.size()]),
+ measpks.toArray(new String[measpks.size()]));
+ Map bastunitstore = new HashMap();
+ if (invmeasvos != null) {
+ for (InvMeasVO invMeasVO : invmeasvos) {
+ if (invMeasVO == null) {
+ // 物料可能没有辅计量信息
+ continue;
+ }
+ bastunitstore.put(invMeasVO.getPk_material() + invMeasVO.getPk_measdoc(),
+ invMeasVO.getIsstorebalance());
+ }
+ }
+
+ this.isasunitstore = bastunitstore;
+ }
+
+ /**
+ * 同步序列号档案上信息到孙表
+ * @param billvo
+ * @param results
+ *
+ */
+ private void fillSNDocToLocation(ICBillVO billvo, ICBillPickResults results) {
+ List locs = new ArrayList();
+ for (int i = 0, loop = billvo.getBodys().length; i < loop; i++) {
+ ICBillBodyVO[] bodys = results.getPickBodys(i);
+ if (ValueCheckUtil.isNullORZeroLength(bodys)) {
+ continue;
+ }
+ for (ICBillBodyVO body : bodys) {
+ if (body == null) {
+ continue;
+ }
+ CollectionUtils.addArrayToList(locs, body.getLocationVOs());
+ }
+ }
+ // 同步序列号相关信息到孙表,ICSnForLocationFields继承了AbstractBatchFieldMap,父类的作用是同步批次信息
+ new SnCodeForLocationVOSynchronizer(new ICSnForLocationFields())
+ .fillBatchVOtoBill(locs.toArray(new ICLocationVO[0]));
+ }
+
+}
diff --git a/ic/src/public/nc/vo/ic/onhand/define/ICBillPickResults.java b/ic/src/public/nc/vo/ic/onhand/define/ICBillPickResults.java
new file mode 100644
index 0000000..14a2af4
--- /dev/null
+++ b/ic/src/public/nc/vo/ic/onhand/define/ICBillPickResults.java
@@ -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;
+
+/**
+ *
+ * 单据现存量捡货结果
+ *
+ * @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 mapbodyvos;
+
+ // 原始表体的自然序号与捡货结果的对应关系
+ private transient Map> maponhandbalanceresult;
+
+ // 捡货前的单据表体VO
+ private ICBillBodyVO[] originbillbodyvos;
+
+ // 捡货后结果
+ private List> 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> pickresults,
+ ICBillBodyVO[] originbodyvos) {
+ this.pickresults = pickresults;
+ this.originbillbodyvos = originbodyvos;
+ }
+
+ /**
+ * 获取捡货后的表体ICBillBodyVOs
+ */
+ public ICBillBodyVO[] getPickBodys() {
+ if (this.curbillbodyvos != null) {
+ return this.curbillbodyvos;
+ }
+ List retlist = new ArrayList();
+ 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 result =
+ this.getMapResults().get(String.valueOf(row));
+ if (result == null) {
+ return null;
+ }
+ List retlist = new ArrayList();
+ 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> mapgroup =
+ this.groupBalanceOnhandRes(result.getResults());
+ int rowCount = 0;
+ for (List 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 listlocs = new ArrayList