You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica按公司/分支动态过滤仓库选择器实现方案咨询

实现方案

要实现多个页面的仓库选择器动态过滤,推荐通过自定义选择器特性实现,一次开发即可在所有目标页面复用,无需单独为每个页面写重复逻辑。

步骤1:编写自定义仓库选择器特性

新建继承自PXSiteAttribute(Acumatica原生仓库选择器特性)的自定义类,重写过滤逻辑:

public class FilteredSiteAttribute : PXSiteAttribute
{
    public FilteredSiteAttribute() : base() { }

    public override IEnumerable GetRecords()
    {
        // 先获取原生选择器的所有仓库结果
        var allSites = base.GetRecords().Cast<INSite>().ToList();
        // 读取库存参数配置
        INSetupExt setupExt = PXSelect<INSetup>.SelectSingleBound(Base, null).GetExtension<INSetupExt>();
        
        // 未开启过滤直接返回全部
        if (setupExt.UsrAllowBlockin != true) return allSites;

        // 获取当前上下文信息
        int? currentBranch = Base.Accessinfo.BranchID;
        // 优先取当前单据的分支,没有的话取登录用户默认分支
        if (Base is SOOrderEntry soEntry) currentBranch = soEntry.Document.Current?.BranchID ?? currentBranch;
        if (Base is POOrderEntry poEntry) currentBranch = poEntry.Document.Current?.BranchID ?? currentBranch;
        if (Base is CROpportunityMaint oppEntry) currentBranch = oppEntry.Document.Current?.BranchID ?? currentBranch;
        if (Base is CRQuoteMaint quoteEntry) currentBranch = quoteEntry.Document.Current?.BranchID ?? currentBranch;
        if (Base is RQRequisitionEntry reqEntry) currentBranch = reqEntry.Document.Current?.BranchID ?? currentBranch;
        
        int currentCompany = Base.Accessinfo.CompanyID;

        if (setupExt.UsrByBranch == true && currentBranch.HasValue)
        {
            // 按分支过滤:仅返回当前分支关联的仓库
            return allSites.Where(s => s.BranchID == currentBranch).ToList();
        }
        else if (setupExt.UsrByCompany == true)
        {
            // 按公司过滤:返回当前公司下所有分支关联的仓库
            var companyBranches = PXSelect<Branch, Where<Branch.companyID, Equal<Required<Branch.companyID>>>>
                .Select(Base, currentCompany).RowCast<Branch>().Select(b => b.BranchID).ToList();
            return allSites.Where(s => companyBranches.Contains(s.BranchID)).ToList();
        }

        return allSites;
    }
}

步骤2:替换所有目标页面DAC的仓库字段特性

通过DAC扩展替换对应字段的原生仓库选择器,以下是各页面需要修改的DAC:

  • 销售订单:SOOrder/SOLine的SiteID字段
  • 采购订单:POOrder/POLine的SiteID字段
  • 商机:CROpportunity的SiteID字段
  • 销售报价:CRQuote的SiteID字段
  • 申请单:RQRequisition/RQRequisitionLine的SiteID字段

以销售订单SOLine为例,扩展代码如下:

public class SOLineExt : PXCacheExtension<SOLine>
{
    [PXMergeAttributes(Method = MergeMethod.Replace)]
    [FilteredSite]
    public virtual int? SiteID { get; set; }
}

步骤3:补充分支变更触发刷新逻辑(可选)

如果需要切换单据分支后仓库选择器立即刷新结果,在对应Graph的扩展中添加分支字段更新事件,强制重置SiteID的选择器缓存:

protected void SOLine_BranchID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e, PXFieldUpdated InvokeBaseHandler)
{
    InvokeBaseHandler?.Invoke(cache, e);
    var row = e.Row as SOLine;
    if (row == null) return;
    // 强制清空SiteID的选择器缓存,下次打开时重新加载过滤后的结果
    PXUIFieldAttribute.SetEnabled<SOLine.siteID>(cache, row, false);
    PXUIFieldAttribute.SetEnabled<SOLine.siteID>(cache, row, true);
    // 如果需要清空原有不符合规则的仓库值,可以加以下逻辑
    // cache.SetDefaultExt<SOLine.siteID>(row);
}

注意事项

  1. 你现有的INSetupExt代码无需修改,直接沿用即可
  2. 所有DAC扩展的特性替换都要加[PXMergeAttributes(Method = MergeMethod.Replace)],否则会和原生特性冲突
  3. 如果需要支持多公司跨分支权限,可根据实际业务调整按公司过滤的逻辑,增加权限校验判断

内容的提问来源于stack exchange,提问作者Charl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:30:01