PXDefault 在 OrderType 中添加的字段上的空引用

PXDefault Null reference on field added in OrderType

我已经在屏幕 SO201000 的 OrderType 上添加了一个新字段 UsrUserRole :

 [PXDBString(64)]
 [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
 [PXSelector(typeof(Search<PX.SM.Roles.rolename>))]
 [PXUIField(DisplayName="User Role", Visibility = PXUIVisibility.SelectorVisible)]

我收到错误:

Object reference not set to an instance of an object

当它为空时。那么如何设置默认值选择器订单类型呢?这是我为 OrderType

所做的 SOOrder 定制
[PXDefault(typeof(Search2<SOOrderType.orderType,
                    InnerJoin<PX.SM.UsersInRoles, 
                        On<PX.SM.UsersInRoles.rolename, 
                            Equal<SOOrderTypeExt.usrUserRole>>>,
                    Where<PX.SM.UsersInRoles.username, 
                        Equal<Current<AccessInfo.userName>>>>), 
                        PersistingCheck = PXPersistingCheck.Nothing)]
[PXSelector(typeof(Search5<SOOrderType.orderType,
        InnerJoin<SOOrderTypeOperation, 
            On<SOOrderTypeOperation.orderType, 
                Equal<SOOrderType.orderType>, 
            And<SOOrderTypeOperation.operation, 
                Equal<SOOrderType.defaultOperation>>>,
        LeftJoin<SOSetupApproval, 
            On<SOOrderType.orderType, 
                Equal<SOSetupApproval.orderType>>,
        InnerJoin<PX.SM.UsersInRoles, 
            On<PX.SM.UsersInRoles.rolename, 
                Equal<SOOrderTypeExt.usrUserRole>>>>>,
        Aggregate<GroupBy<SOOrderType.orderType>>>),DescriptionField = typeof(SOOrderTypeT.descr))]
[PXRestrictor(typeof(Where<PX.SM.UsersInRoles.username, 
                        Equal<Current<AccessInfo.userName>>>), null)]

我希望在 SOOrderEntry 中声明的属性之一(如 IsCreditMemoOrder 或 IsTransferOrder)会抛出 "Object reference not set to an instance of an object" 错误。

销售订单屏幕的当前设计始终期望当前用户至少可以访问一种订单类型,而您的 SOOrder 自定义并未完全遵循这一点。

可能的解决方案是覆盖 SOOrder SalesOrder 字段的属性,如下所示:

[PXDBString(2, IsKey = true, IsFixed = true, InputMask=">aa")]
[PXDefault(SOOrderTypeConstants.SalesOrder, typeof(SOSetup.defaultOrderType))]
[PXSelector(typeof(Search5<SOOrderType.orderType,
        InnerJoin<SOOrderTypeOperation, 
            On<SOOrderTypeOperation.orderType, 
                Equal<SOOrderType.orderType>, 
            And<SOOrderTypeOperation.operation, 
                Equal<SOOrderType.defaultOperation>>>,
        LeftJoin<SOSetupApproval, 
            On<SOOrderType.orderType, 
                Equal<SOSetupApproval.orderType>>,
        InnerJoin<PX.SM.UsersInRoles, 
            On<PX.SM.UsersInRoles.rolename, 
                Equal<SOOrderTypeExt.usrUserRole>>>>>,
        Aggregate<GroupBy<SOOrderType.orderType>>>),DescriptionField = typeof(SOOrderTypeT.descr))]
[PXRestrictor(typeof(Where<PX.SM.UsersInRoles.username, 
                        Equal<Current<AccessInfo.userName>>>), "Access not granted")]
[PXRestrictor(typeof(Where<SOOrderTypeOperation.iNDocType, NotEqual<INTranType.transfer>, Or<FeatureInstalled<FeaturesSet.warehouse>>>), ErrorMessages.ElementDoesntExist, typeof(SOOrderType.orderType))]
[PXRestrictor(typeof(Where<SOOrderType.requireAllocation, NotEqual<True>, Or<AllocationAllowed>>), ErrorMessages.ElementDoesntExist, typeof(SOOrderType.orderType))]
[PXRestrictor(typeof(Where<SOOrderType.active,Equal<True>>), null)]
[PXUIField(DisplayName = "Order Type", Visibility = PXUIVisibility.SelectorVisible)]
[PX.Data.EP.PXFieldDescription]

并使用以下 SOOrderEntry 扩展来完成:

public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
    public void SOOrder_OrderType_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
    {
        var query = new PXSelectJoin<SOOrderType,
                InnerJoin<PX.SM.UsersInRoles,
                    On<PX.SM.UsersInRoles.rolename,
                        Equal<SOOrderTypeExt.usrUserRole>>>,
                Where<PX.SM.UsersInRoles.username,
                    Equal<Current<AccessInfo.userName>>>>(Base);
        var orderType = query.SelectSingle();
        if (orderType != null)
        {
            e.NewValue = orderType.OrderType;
            e.Cancel = true;
        }
    }

    public void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
    {
        SOOrder order = e.Row as SOOrder;

        bool disabled = Base.soordertype.Current == null;
        if (!disabled)
        {
            string userRole = Base.soordertype.Current.GetExtension<SOOrderTypeExt>().UsrUserRole;
            if (string.IsNullOrEmpty(userRole) || !PXContext.PXIdentity.User.IsInRole(userRole))
            {
                disabled = true;
            }
        }

        if (disabled)
        {
            SetReadOnly(true);
            sender.AllowInsert = true;
            sender.RaiseExceptionHandling<SOOrder.orderType>(order, order.OrderType, 
                new PXSetPropertyException("Access not granted for current user", PXErrorLevel.Warning));
        }
    }

    protected void SetReadOnly(bool isReadOnly)
    {
        foreach (PXCache cache in Base.Caches.Values)
        {
            cache.AllowDelete = !isReadOnly;
            cache.AllowUpdate = !isReadOnly;
            cache.AllowInsert = !isReadOnly;
        }
    }
}

BLC 扩展将确保首先根据您的自定义用户角色字段设置默认订单类型。如果订单类型的用户角色为空,系统将使用 SOSetup.defaultOrderType,如在 PXDefaultAttibute 的原始声明中设置的那样。如果当前用户不属于为订单类型指定的角色,用户将收到 "Access not granted for current user" 警告并且将无法创建、修改或删除所选类型的任何订单。