Acumatica 自定义复合钥匙管理屏幕上的导航(下一个/上一个)按钮

Acumatica 自定义复合钥匙管理屏幕上的导航(下一个/上一个)按钮,acumatica,Acumatica,物料仓库详细信息由库存ID+站点ID的复合键组成。管理>物料仓库详细信息屏幕上的导航按钮在键的后半部分仓库之间移动 是否可以对它们进行自定义,以便在库存ID之间导航?什么事件/方法允许这样做?为了定制Acumatica中的导航按钮,您应该在适当的BLC扩展中重新声明部分或所有导航按钮。下面是一个示例,显示了如何仅通过库存ID在“物料仓库详细信息”屏幕上实施导航: using PX.Data; using System; using System.Collections; using System

物料仓库详细信息由库存ID+站点ID的复合键组成。管理>物料仓库详细信息屏幕上的导航按钮在键的后半部分仓库之间移动


是否可以对它们进行自定义,以便在库存ID之间导航?什么事件/方法允许这样做?

为了定制Acumatica中的导航按钮,您应该在适当的BLC扩展中重新声明部分或所有导航按钮。下面是一个示例,显示了如何仅通过库存ID在“物料仓库详细信息”屏幕上实施导航:

using PX.Data;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace PX.Objects.IN
{
    public class INItemSiteMaintExt : PXGraphExtension<INItemSiteMaint>
    {
        public PXFirstCst<INItemSite> First;
        public PXPreviousCst<INItemSite> Previous;
        public PXNextCst<INItemSite> Next;
        public PXLastCst<INItemSite> Last;

        public class PXFirstCst<TNode> : PXFirst<TNode>
            where TNode : class, IBqlTable, new()
        {
            public PXFirstCst(PXGraph graph, string name)
                : base(graph, name)
            {
            }
            public PXFirstCst(PXGraph graph, Delegate handler)
                : base(graph, handler)
            {
            }
            [PXUIField(DisplayName = ActionsMessages.First, MapEnableRights = PXCacheRights.Select)]
            [PXFirstButton]
            protected override IEnumerable Handler(PXAdapter adapter)
            {
                var graph = _Graph as INItemSiteMaint;
                if (graph == null) return base.Handler(adapter);

                InjectCustomWhereClause(ref adapter, graph, typeof(Where<True, Equal<True>>));
                return base.Handler(adapter);
            }
        }

        public class PXPreviousCst<TNode> : PXPrevious<TNode>
            where TNode : class, IBqlTable, new()
        {
            public PXPreviousCst(PXGraph graph, string name)
            : base(graph, name)
            {
            }
            public PXPreviousCst(PXGraph graph, Delegate handler)
                : base(graph, handler)
            {
            }

            [PXUIField(DisplayName = ActionsMessages.Previous, MapEnableRights = PXCacheRights.Select)]
            [PXPreviousButton]
            protected override IEnumerable Handler(PXAdapter adapter)
            {
                var graph = _Graph as INItemSiteMaint;
                if (graph == null) return base.Handler(adapter);

                InjectCustomWhereClause(ref adapter, graph,
                    typeof(Where<InventoryItem.inventoryCD, Less<Required<InventoryItem.inventoryCD>>>));
                return base.Handler(adapter);
            }

            protected override void Insert(PXAdapter adapter)
            {
                adapter.Searches = null;
                base.Insert(adapter);
            }
        }

        public class PXNextCst<TNode> : PXNext<TNode>
            where TNode : class, IBqlTable, new()
        {
            public PXNextCst(PXGraph graph, string name)
                : base(graph, name)
            {
            }
            public PXNextCst(PXGraph graph, Delegate handler)
                : base(graph, handler)
            {
            }

            [PXUIField(DisplayName = ActionsMessages.Next, MapEnableRights = PXCacheRights.Select)]
            [PXNextButton]
            protected override IEnumerable Handler(PXAdapter adapter)
            {
                var graph = _Graph as INItemSiteMaint;
                if (graph == null) return base.Handler(adapter);

                InjectCustomWhereClause(ref adapter, graph,
                    typeof(Where<InventoryItem.inventoryCD, Greater<Required<InventoryItem.inventoryCD>>>));
                return base.Handler(adapter);
            }

            protected override void Insert(PXAdapter adapter)
            {
                adapter.Searches = null;
                base.Insert(adapter);
            }
        }

        public class PXLastCst<TNode> : PXLast<TNode>
            where TNode : class, IBqlTable, new()
        {
            public PXLastCst(PXGraph graph, string name)
                : base(graph, name)
            {
            }
            public PXLastCst(PXGraph graph, Delegate handler)
                : base(graph, handler)
            {
            }
            [PXUIField(DisplayName = ActionsMessages.Last, MapEnableRights = PXCacheRights.Select)]
            [PXLastButton]
            protected override IEnumerable Handler(PXAdapter adapter)
            {
                var graph = _Graph as INItemSiteMaint;
                if (graph == null) return base.Handler(adapter);

                InjectCustomWhereClause(ref adapter, graph, typeof(Where<True, Equal<True>>));
                return base.Handler(adapter);
            }
        }

        private static void InjectCustomWhereClause(ref PXAdapter adapter, INItemSiteMaint graph,
            Type conditionToInjectCommand)
        {
            var bqlCommand = adapter.View.BqlSelect;
            var newCommand = new List<Type>(BqlCommand.Decompose(bqlCommand.GetType()));
            var newCommandCopy = new List<Type>(newCommand);

            var conditionToReplaceCommand = typeof(Where<INItemSite.inventoryID, Equal<Optional<INItemSite.inventoryID>>>);
            var conditionToReplace = new List<Type>(BqlCommand.Decompose(conditionToReplaceCommand).Skip(1));
            var conditionToInject = new List<Type>(BqlCommand.Decompose(conditionToInjectCommand).Skip(1));

            bool whereClause = false;
            for (int i = 0; i < newCommand.Count - 1; i++)
            {
                whereClause = whereClause || typeof(IBqlWhere).IsAssignableFrom(newCommand[i]);
                if (!whereClause) continue;

                if (newCommand[i] == conditionToReplace.First())
                {
                    bool found = true;
                    for (int index = 0; index < conditionToReplace.Count; index++)
                    {
                        if (newCommand[i + index] != conditionToReplace[index])
                        {
                            found = false;
                            break;
                        }
                    }
                    if (found)
                    {
                        newCommandCopy.RemoveRange(i, conditionToReplace.Count);
                        newCommandCopy.InsertRange(i, conditionToInject);
                        break;
                    }
                }
            }

            var cmd = BqlCommand.CreateInstance(BqlCommand.Compose(newCommandCopy.ToArray()));
            var newAdapter = new PXAdapter(new PXView(graph, false, cmd));
            PXAdapter.Copy(adapter, newAdapter);

            var inventoryState = graph.itemsiterecord.Cache.
                GetValueExt<INItemSite.inventoryID>(graph.itemsiterecord.Current) as PXSegmentedState;
            if (inventoryState != null && inventoryState.Value != null)
                newAdapter.Parameters = new object[] { inventoryState.Value };
            else
                newAdapter.Parameters = new object[] { string.Empty };

            newAdapter.SortColumns = null;
            newAdapter.Descendings = null;

            adapter = newAdapter;
        }
    }
}
使用PX.Data;
使用制度;
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
命名空间PX.Objects.IN
{
公共类INItemSiteMaintExt:pXgrapherExtension
{
公共服务优先于CST优先;
公共PX先前CST先前;
公共PXNEXTST Next;
公共PXLastCst Last;
公共类PXFirstCst:PXFirst
其中TNode:class,IBqlTable,new()
{
公共PXFirstCst(PXGraph图形,字符串名称)
:base(图形、名称)
{
}
公共PXFirstCst(PXGraph图形,委托处理程序)
:base(图形、处理程序)
{
}
[PXUIField(DisplayName=ActionsMessages.First,MapEnableRights=PXCacheRights.Select)]
[按钮]
受保护的重写IEnumerable处理程序(PXAdapter适配器)
{
var-graph=\作为INItemSiteMaint的图;
if(graph==null)返回base.Handler(适配器);
插入CustomWhere子句(参考适配器、图形、类型(其中));
返回base.Handler(适配器);
}
}
公共类PXPreviousCst:PXPrevious
其中TNode:class,IBqlTable,new()
{
公共PXPreviousCst(PXGraph图形,字符串名称)
:base(图形、名称)
{
}
公共PXPreviousCst(PXGraph图形,委托处理程序)
:base(图形、处理程序)
{
}
[PXUIField(DisplayName=ActionsMessages.Previous,MapEnableRights=PXCacheRights.Select)]
[PXPreviousButton]
受保护的重写IEnumerable处理程序(PXAdapter适配器)
{
var-graph=\作为INItemSiteMaint的图;
if(graph==null)返回base.Handler(适配器);
插入CustomWhere子句(参考适配器、图形、,
类型(若有);
返回base.Handler(适配器);
}
受保护的覆盖无效插入(PXAdapter适配器)
{
adapter.Searches=null;
底座。插入件(适配器);
}
}
公共类PXNEXTST:PXNext
其中TNode:class,IBqlTable,new()
{
公共PXNEXTST(PXGraph图形,字符串名称)
:base(图形、名称)
{
}
公共PXNEXTST(PXGraph图形,委托处理程序)
:base(图形、处理程序)
{
}
[PXUIField(DisplayName=ActionsMessages.Next,MapEnableRights=PXCacheRights.Select)]
[PXNextButton]
受保护的重写IEnumerable处理程序(PXAdapter适配器)
{
var-graph=\作为INItemSiteMaint的图;
if(graph==null)返回base.Handler(适配器);
插入CustomWhere子句(参考适配器、图形、,
类型(若有);
返回base.Handler(适配器);
}
受保护的覆盖无效插入(PXAdapter适配器)
{
adapter.Searches=null;
底座。插入件(适配器);
}
}
公共类PXLastCst:PXLast
其中TNode:class,IBqlTable,new()
{
公共PXLastCst(PXGraph图形,字符串名称)
:base(图形、名称)
{
}
公共PXLastCst(PXGraph图形,委托处理程序)
:base(图形、处理程序)
{
}
[PXUIField(DisplayName=ActionsMessages.Last,MapEnableRights=PXCacheRights.Select)]
[按钮]
受保护的重写IEnumerable处理程序(PXAdapter适配器)
{
var-graph=\作为INItemSiteMaint的图;
if(graph==null)返回base.Handler(适配器);
插入CustomWhere子句(参考适配器、图形、类型(其中));
返回base.Handler(适配器);
}
}
私有静态void injectCustomWhere子句(参考PXAdapter adapter,INItemSiteMaint图,
键入conditionToInjectCommand)
{
var bqlCommand=adapter.View.BqlSelect;
var newCommand=newlist(BqlCommand.Decompose(BqlCommand.GetType());
var newcommmandcopy=新列表(newcommmand);
var conditionToReplaceCommand=typeof(其中);
var conditionoreplace=新列表(BqlCommand.Decompose(conditionoreplacecommand.Skip(1));
var conditionToInject=新列表(BqlCommand.Decompose(conditionToInjectCommand.Skip(1));
bool where子句=false;
for(int i=0;i