在复合键管理屏幕上自定义导航(下一个/上一个)按钮

时间:2018-01-16 14:57:49

标签: acumatica

项目仓库详细信息由库存ID +站点ID的复合键组成。 Manage>上的导航按钮; Item Warehouse Details屏幕在键的后半部分Warehouse之间移动。

是否可以自定义它们以在库存ID之间导航?哪些事件/方法可以实现?

1 个答案:

答案 0 :(得分:2)

要在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;
        }
    }
}