销售出库批号拣货按仓库过滤,自定义条件过滤批号原创
金蝶云社区-湖南吴双得
湖南吴双得
23人赞赏了该文章 94次浏览 未经作者许可,禁止转载编辑于2024年09月29日 18:09:40
summary-icon摘要由AI智能服务提供

本文讨论了在一个业务场景中,即同一组织下的同一物料在多个仓库有不同批号,且不同制单人需要拣选不同仓库的物料,同时要求按照销售订单对应的生产订单批号进行发货的解决方案。解决方案包括两部分:一是通过用户与仓库映射表实现不同制单人拣选不同仓库的功能;二是通过单据转换插件,在销售出库单中根据销售订单找到对应的生产订单批号,并在拣货过程中增加过滤条件来实现。文中还提供了代码示例,包括如何继承标准插件代码、重写特定方法以实现仓库过滤,以及在单据转换插件中更新销售出库单并添加过滤条件的具体实现。


业务场景:同一组织下同一物料在很多仓库有批号,但不同制单人要拣货不同仓库,且要按销售订单对应的生产订单批号发货。

解决方案:1、不同制单人要拣货不同仓库:可二开一个用户与仓库映射表,在批号批货中做过滤。
                 2、按销售订单对应的生产订单批号发货,单据转换插件中根据销售订单找生产订单批号,更新到销售出库单,再批号拣货中增加过滤条件

实现代码参考:

一、继承标准插件代码:

public class LotPickStockFilter : Kingdee.K3.SCM.App.Sal.ServicePlugIn.LotPickingExtendForSale

注册时,用二开插件代替标准插件


二、不同制单人要拣货不同仓库:重写 RegexUseableInvData 方法。但要记得优先执行标准方法 base.RegexUseableInvData(dctinvDatas);

        public override void RegexUseableInvData(Dictionary<long, DataTable> dctinvDatas)
        {
            base.RegexUseableInvData(dctinvDatas);

            //是SS、SR组织才过滤
            if (!isSSSR)
            { return; }

            //根据当前用户过滤仓库映射
            long userID = this.Ctx.UserId;
            string strSql = $@"select t1.FSALEOUTUSERID,t2.FSTOCKID
  from t_ora_UserAndStockMap t1 inner join t_ora_UserAndStockMapEntry t2 on t1.FID = t2.FID 
 where t1.FDOCUMENTSTATUS = 'C' and FORGID = {orgID} and t1.FSALEOUTUSERID = {userID} ";
            DynamicObjectCollection docStocks = DBUtils.ExecuteDynamicObject(Ctx, strSql);
            List<long> lstStocks = (from d in docStocks
                                          where !d["FSTOCKID"].IsNullOrEmptyOrWhiteSpace()
                                          select Convert.ToInt64(d["FSTOCKID"])).ToList();
            //未配置用户与仓库映射表则不过滤
            if (lstStocks == null || lstStocks.Count() <= 0)
            {
                return;
            }
            //dataRuleStockIds.AddRange(lstStocks);
            // 根据仓库数据权限,从获取的即时库存中移除无权限的仓库库存明细
            foreach (var item in dctinvDatas)
            {
                int count = item.Value.Rows.Count;
                var invTable = item.Value;
                List<int> removeRows = new List<int>();
                for (var i = count - 1; i >= 0; i--)
                {
                    DataRow row = invTable.Rows[i];
                    long stockId = Convert.ToInt64(row["FSTOCKID"]);
                    if (!lstStocks.Contains(stockId))
                    {
                        removeRows.Add(i);
                    }
                }
                foreach (var index in removeRows)
                {
                    invTable.Rows.RemoveAt(index);
                }
            }
       }


三、按销售订单对应的生产订单批号发货

       单据转换插件

        public override void OnAfterCreateLink(CreateLinkEventArgs e)
        {
            base.OnAfterCreateLink(e);

            // 目标单单据体元数据
            Entity entity = e.TargetBusinessInfo.GetEntity("FEntity");
            // 读取已经生成的发货通知单
            ExtendedDataEntity[] bills = e.TargetExtendedDataEntities.FindByEntityKey("FBillHead");

            // 定义一个集合,存储新拆分出来的单据体行
            List<ExtendedDataEntity> newRows = new List<ExtendedDataEntity>();
            // 对目标单据进行循环
            foreach (var bill in bills)
            {
				string stockOrgID = bill["StockOrgId_Id"].ToString();
				if(!stockOrgID.EqualsIgnoreCase("107301") && !stockOrgID.EqualsIgnoreCase("107302"))
				{
					continue;
				}
				// 取单据体集合
				DynamicObjectCollection docEntrys = entity.DynamicProperty.GetValue(bill.DataEntity) as DynamicObjectCollection;

                //int rowCount = docEntrys.Count;
                //int newRowCount = 1;

                List<long> lstEntrysID = (from d in docEntrys
                                              where !d["SOEntryId"].IsNullOrEmptyOrWhiteSpace() && d["F_PYBU_phbz"].IsNullOrEmptyOrWhiteSpace()
										  select Convert.ToInt64(d["SOEntryId"])).ToList();
                //无需要签收的调拨申请单,结束
                if (lstEntrysID == null || lstEntrysID.Count() <= 0)
                {
                    return;
                }
                string strOrderEntryID = string.Join(",", lstEntrysID.ToArray());
                DynamicObjectCollection docOrderBatch = getOrderBatch(strOrderEntryID);
                for (int i = 0; i < docEntrys.Count() ; i++)
                {
                    DynamicObject rowObj = docEntrys[i];
					string SOEntryId = Convert.ToString(rowObj["SOEntryId"]);
					var varBatchs = docOrderBatch.Where(o => o["FSALEORDERENTRYID"].ToString().Equals(SOEntryId)).ToList();
					if(null == varBatchs || varBatchs.Count() <= 0)
                    {
						continue;
                    }
					rowObj["F_PYBU_phbz"] = varBatchs[0]["FLOT_TEXTS"].ToString();
				}

            }
        }


 批号拣货过滤插件:

public override string RegexCurRowPickFilterString(RegexCurRowPickFilterStringArgs e)
        {
            //是SS、SR组织才过滤
            if (isSSSR)
            {
                // 当前行实体
                ExtendedDataEntity entity = e.Entity;
                var materialInfo = e.MatInfo;

                //按批号备注来过滤批号, 不在批号备注的批号不拣货
                string strOrgID = this.Ctx.CurrentOrganizationInfo.ID.ToString();
                string phbz = entity["F_PYBU_phbz"] == null ? "" : entity["F_PYBU_phbz"].ToString();
                string[] arrPhbz = phbz.Split(',');
                //&& (strOrgID.EqualsIgnoreCase("107301") || strOrgID.EqualsIgnoreCase("107302"))
                if (arrPhbz.Length > 0 && !phbz.IsNullOrEmptyOrWhiteSpace())
                {
                    e.FilterString += string.Format(" AND FLOT_NU in ('{0}') ", string.Join("','", arrPhbz.ToArray()));
                }
            }

            return e.FilterString;
        }


感谢社区知识指导,批号拣货参考社区知识:

库存管理:https://vip.kingdee.com/link/s/l5F0T

批号拣货插件:https://vip.kingdee.com/link/s/liq8v


赞 23