有源单批号拣货仓库(数据权限)过滤原创
金蝶云社区-邱育华
邱育华
7人赞赏了该文章 2362次浏览 未经作者许可,禁止转载编辑于2022年09月15日 10:10:28

一、【业务需求】

1、销售出库不想拣货到生产仓库的库存,生产仓库拣货不想拣到销售仓库的库存

2、销售出库的时候自动拣货功能,想实现:考虑基础资料仓库设置数据权限。例如:A用户只有仓库A的权限,在下推出库单进行自动拣货的时候,拣货只考虑仓库A里物料的库存和批号信息。


类似的需求大同小异,总结起来可以简单理解为业务单据设置了仓库的基础资料权限,前台操作可以实现仓库录入控制,但是有源单单据转换批号拣货时无法实现仓库隔离控制。

标准产品中关于“单据转换批号拣货服务没有去支持数据隔离”的原因可能是:库存维度太多,每个维度针对不同单据都会涉及到不同的数据隔离规则,无法针对每个维度进行处理,数据规则一多,对性能也有很大影响。大多数的业务场景没有此类需求,特殊需求可以通过二开插件去处理。


二、【功能分析】

批号拣货插件 

批号捡货二次开发插件示例 


参考拣货组件预留的的抽象方法,结合基础资料数据权限的方案,做二次开发

1.编写插件继承批号拣货插件基类;

2.根据业务需要重载对应事件实现逻辑;

3.注册插件至对应服务配置界面。


using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.Permission.Objects;
using Kingdee.BOS.Util;
using Kingdee.K3.SCM.App.Core.ConvertBusinessService;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace Kingdee.K3.SCM.Stock.App.CustomizePlugIn
{
    /// <summary>
    /// 有源单批号拣货插件,仓库过滤
    /// </summary>
    public class LotPickStockFilter : AbstractLotPickPlugIn
    {
        public override void RegexUseableInvData(Dictionary<long, DataTable> dctinvDatas)
        {
            base.RegexUseableInvData(dctinvDatas);
            string formId = this.BillInfo.GetForm().Id;  // 下游单据
            List<long> dataRuleStockIds = new List<long>();  // 可拣货仓库集合
            // 根据下游单据,添加相应仓库,从而达到根据不同单据限定不同仓库拣货的设置,比如:销售出库不想拣货到生产仓库的库存,生产仓库拣货不想拣到销售仓库的库存
            
            // 获得基础资料根据数据规则构建的临时表
            List<BaseDataTempTable> lstBaseTempTable = Kingdee.BOS.ServiceHelper.PermissionServiceHelper.GetBaseDataTempTable(this.Ctx, formId);
            if (lstBaseTempTable != null && lstBaseTempTable.Count > 0)
            {
                string stockDataRuleTemp = (from p in lstBaseTempTable where p.BaseDataFormId.EqualsIgnoreCase("BD_STOCK") select p.TempTable).FirstOrDefault();
                if (!stockDataRuleTemp.IsNullOrEmptyOrWhiteSpace())
                {
                    string stockSql = string.Format(@"SELECT tmp.*, ST.FNUMBER, TL.FNAME FROM {0} tmp JOIN T_BD_STOCK ST
  ON tmp.fstockid = ST.FSTOCKID
  JOIN T_BD_STOCK_L TL ON ST.FSTOCKID = TL.FSTOCKID", stockDataRuleTemp);
                    using (IDataReader dataReader = DBUtils.ExecuteReader(this.Ctx, stockSql))
                    {
                        while (dataReader.Read())
                        {
                            dataRuleStockIds.Add(Convert.ToInt64(dataReader["FSTOCKID"]));
                        }
                        dataReader.Close();
                    }
                }
                
                // 根据仓库数据权限,从获取的即时库存中移除无权限的仓库库存明细
                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 (!dataRuleStockIds.Contains(stockId))
                        {
                            removeRows.Add(i);
                        }
                    }
                    foreach (var index in removeRows)
                    {
                        invTable.Rows.RemoveAt(index);
                    }
                }
            }
        }
    }
}



image.png

image.png



赞 7