Acumatica 如何在搜索中包含DAC扩展未绑定字段<&燃气轮机;PX选择器的参数?

Acumatica 如何在搜索中包含DAC扩展未绑定字段<&燃气轮机;PX选择器的参数?,acumatica,Acumatica,我对INLocation.LocationCD进行了分段,需要根据输入位置的屏幕限制PXSelector包含或排除特定的分段。我已经能够访问PXSelector的显示列中的DAC扩展字段,但是在PXSelector的搜索参数期间,该字段被计算为null 我试过: 直接引用InLocationText.myField 生成继承的DAC以直接定义自定义字段 并创建一个PXProjection,希望附加层将导致检索未绑定字段以填充PXSelector,以防字段未及时加载以进行搜索 要点: 这是D

我对INLocation.LocationCD进行了分段,需要根据输入位置的屏幕限制PXSelector包含或排除特定的分段。我已经能够访问PXSelector的显示列中的DAC扩展字段,但是在PXSelector的搜索参数期间,该字段被计算为null

我试过:

  • 直接引用InLocationText.myField
  • 生成继承的DAC以直接定义自定义字段
  • 并创建一个PXProjection,希望附加层将导致检索未绑定字段以填充PXSelector,以防字段未及时加载以进行搜索
要点:

  • 这是DAC扩展中的未绑定字段
  • 它返回一个基于计算INLocation.LocationCD最后一段的值
  • 常规查询正确显示此值
  • 当我引用未绑定字段时,我无法使PXSelector返回任何值,除非我简单地检查并
在我的DAC扩展中定义的字段:

[PXString(1)]
[PXUIField(DisplayName = "Condition")]
[ConditionType.List]
public String UsrSSCondition
{ 
    get
    {
        if (LocationCD == null || LocationCD.Length == 0) return ConditionType.Undefined;

        switch (LocationCD.Substring(LocationCD.Length - 1, 1))
        {
            case "N":
                return ConditionType.New;
            case "R":
                return ConditionType.Repair;
            case "C":
                return ConditionType.Core;
            case "U":
                return ConditionType.Used;
            default:
                return ConditionType.Undefined;
        }
    }
}
public abstract class usrSSCondition : PX.Data.BQL.BqlString.Field<usrSSCondition> { }

永远不要在getter中使用代码,它在BQL表达式中无法正常工作

如果您想在BQL中的某个地方检查
Loc.Substring(Loc.Length-1,1)
,只需编写您自己的BQL函数

public class ConditionTypeBySegment<Source> : BqlFunction, IBqlOperand, IBqlCreator
    where Source : IBqlOperand
{
    private IBqlCreator _source;

    public void Verify(PXCache cache, object item, List<object> pars, ref bool? result, ref object value)
    {
        if (!getValue<Source>(ref _source, cache, item, pars, ref result, out value) || value == null)
            return;

        if (value is string strValue)
        {
            switch (strValue.Substring(strValue.Length - 1, 1))
            {
                case "N":
                    value = ConditionType.New;
                    break;
                case "R":
                    value = ConditionType.Repair;
                    break;
                case "C":
                    value = ConditionType.Core;
                    break;
                case "U":
                    value = ConditionType.Used;
                    break;
                default:
                    value = ConditionType.Undefined;
                    break;
            }

            return;
        }

        value = ConditionType.Undefined;
    }

    public bool AppendExpression(ref SQLExpression exp, PXGraph graph, BqlCommandInfo info, BqlCommand.Selection selection)
    {
        ...
        return true;
    }
}
公共类ConditionTypeBySegment:BqlFunction、ibqlOperator、IBqlCreator
其中来源:ibql操作数
{
私有IBqlCreator_源;
公共无效验证(PXCache缓存、对象项、列表PAR、ref bool?结果、ref对象值)
{
如果(!getValue(引用源、缓存、项、PAR、引用结果、输出值)|值==null)
返回;
if(值为字符串strValue)
{
开关(strValue.Substring(strValue.Length-1,1))
{
案例“N”:
value=ConditionType.New;
打破
案例“R”:
值=条件类型。修复;
打破
案例“C”:
value=ConditionType.Core;
打破
案例“U”:
值=条件类型。已使用;
打破
违约:
值=条件类型。未定义;
打破
}
返回;
}
值=条件类型。未定义;
}
公共bool AppendExpression(ref-SQLExpression,PXGraph-graph,BqlCommandInfo-info,BqlCommand.Selection)
{
...
返回true;
}
}
或者使用现有功能的组合。例如:

[PXSelector(typeof(Search<INLocation.locationID,
    Where<INLocation.receiptsValid, Equal<True>,
        And<Substring<FABookBalance.deprToPeriod, Sub<StrLen<FABookBalance.deprToPeriod>, int1>, int1>, NotEqual<ConditionTypes.tCore>>>>),
    typeof(INLocation.locationCD),
    typeof(INLocation.active),
    typeof(INLocation.primaryItemID),
    typeof(INLocation.primaryItemClassID),
    typeof(INLocationExt.usrSSCondition),
    typeof(INLocation.receiptsValid),
    SubstituteKey = typeof(INLocation.locationCD))]

public static class ConditionTypes
{
    public class tNew : PX.Data.BQL.BqlString.Constant<tNew> { public tNew() : base("N") { } }
    public class tRepair : PX.Data.BQL.BqlString.Constant<tRepair> { public tRepair() : base("R") { } }
    public class tCore : PX.Data.BQL.BqlString.Constant<tCore> { public tCore() : base("C") { } }
    public class tUsed : PX.Data.BQL.BqlString.Constant<tUsed> { public tUsed() : base("U") { } }
}
[PXSelector(类型)(搜索),
类型(INLocation.location CD),
类型(INLocation.active),
typeof(INLocation.primaryItemID),
类型(包括location.primaryItemClassID),
类型(包括LocationText.usrSSCondition),
类型(包括位置、接收验证),
SubstituteKey=typeof(INLocation.locationCD))]
公共静态类条件类型
{
公共类tNew:PX.Data.BQL.BqlString.Constant{public tNew():base(“N”){}
公共类树对:PX.Data.BQL.BqlString.Constant{public tRepair():base(“R”){}
公共类tCore:PX.Data.BQL.BqlString.Constant{public tCore():base(“C”){}
公共类tUsed:PX.Data.BQL.BqlString.Constant{public tUsed():base(“U”){}
}

永远不要在getter中使用代码,它在BQL表达式中无法正常工作

如果您想在BQL中的某个地方检查
Loc.Substring(Loc.Length-1,1)
,只需编写您自己的BQL函数

public class ConditionTypeBySegment<Source> : BqlFunction, IBqlOperand, IBqlCreator
    where Source : IBqlOperand
{
    private IBqlCreator _source;

    public void Verify(PXCache cache, object item, List<object> pars, ref bool? result, ref object value)
    {
        if (!getValue<Source>(ref _source, cache, item, pars, ref result, out value) || value == null)
            return;

        if (value is string strValue)
        {
            switch (strValue.Substring(strValue.Length - 1, 1))
            {
                case "N":
                    value = ConditionType.New;
                    break;
                case "R":
                    value = ConditionType.Repair;
                    break;
                case "C":
                    value = ConditionType.Core;
                    break;
                case "U":
                    value = ConditionType.Used;
                    break;
                default:
                    value = ConditionType.Undefined;
                    break;
            }

            return;
        }

        value = ConditionType.Undefined;
    }

    public bool AppendExpression(ref SQLExpression exp, PXGraph graph, BqlCommandInfo info, BqlCommand.Selection selection)
    {
        ...
        return true;
    }
}
公共类ConditionTypeBySegment:BqlFunction、ibqlOperator、IBqlCreator
其中来源:ibql操作数
{
私有IBqlCreator_源;
公共无效验证(PXCache缓存、对象项、列表PAR、ref bool?结果、ref对象值)
{
如果(!getValue(引用源、缓存、项、PAR、引用结果、输出值)|值==null)
返回;
if(值为字符串strValue)
{
开关(strValue.Substring(strValue.Length-1,1))
{
案例“N”:
value=ConditionType.New;
打破
案例“R”:
值=条件类型。修复;
打破
案例“C”:
value=ConditionType.Core;
打破
案例“U”:
值=条件类型。已使用;
打破
违约:
值=条件类型。未定义;
打破
}
返回;
}
值=条件类型。未定义;
}
公共bool AppendExpression(ref-SQLExpression,PXGraph-graph,BqlCommandInfo-info,BqlCommand.Selection)
{
...
返回true;
}
}
或者使用现有功能的组合。例如:

[PXSelector(typeof(Search<INLocation.locationID,
    Where<INLocation.receiptsValid, Equal<True>,
        And<Substring<FABookBalance.deprToPeriod, Sub<StrLen<FABookBalance.deprToPeriod>, int1>, int1>, NotEqual<ConditionTypes.tCore>>>>),
    typeof(INLocation.locationCD),
    typeof(INLocation.active),
    typeof(INLocation.primaryItemID),
    typeof(INLocation.primaryItemClassID),
    typeof(INLocationExt.usrSSCondition),
    typeof(INLocation.receiptsValid),
    SubstituteKey = typeof(INLocation.locationCD))]

public static class ConditionTypes
{
    public class tNew : PX.Data.BQL.BqlString.Constant<tNew> { public tNew() : base("N") { } }
    public class tRepair : PX.Data.BQL.BqlString.Constant<tRepair> { public tRepair() : base("R") { } }
    public class tCore : PX.Data.BQL.BqlString.Constant<tCore> { public tCore() : base("C") { } }
    public class tUsed : PX.Data.BQL.BqlString.Constant<tUsed> { public tUsed() : base("U") { } }
}
[PXSelector(类型)(搜索),
类型(INLocation.location CD),
类型(INLocation.active),
typeof(INLocation.primaryItemID),
类型(包括location.primaryItemClassID),
类型(包括LocationText.usrSSCondition),
类型(包括位置、接收验证),
SubstituteKey=typeof(INLocation.locationCD))]
公共静态类条件类型
{
公共类tNew:PX.Data.BQL.BqlString.Constant{public tNew():base(“N”){}
公共类树对:PX.Data.BQL.BqlString.Constant{public tRepair():base(“R”){}
公共类tCore:PX.Data.BQL.BqlString.Constant{public tCore():base(“C”){}
公共类tUsed:PX.Data.BQL.BqlString.Constant{public tUsed():base(“U”){}
}

简单解决方案-简化。将字段更改为仅保留该值,然后在设置locaitonCD值时让BLC设置该值。创建记录时,locationCD字段为emp
[PXSelector(typeof(Search<INLocation.locationID,
    Where<INLocation.receiptsValid, Equal<True>,
        And<Substring<FABookBalance.deprToPeriod, Sub<StrLen<FABookBalance.deprToPeriod>, int1>, int1>, NotEqual<ConditionTypes.tCore>>>>),
    typeof(INLocation.locationCD),
    typeof(INLocation.active),
    typeof(INLocation.primaryItemID),
    typeof(INLocation.primaryItemClassID),
    typeof(INLocationExt.usrSSCondition),
    typeof(INLocation.receiptsValid),
    SubstituteKey = typeof(INLocation.locationCD))]

public static class ConditionTypes
{
    public class tNew : PX.Data.BQL.BqlString.Constant<tNew> { public tNew() : base("N") { } }
    public class tRepair : PX.Data.BQL.BqlString.Constant<tRepair> { public tRepair() : base("R") { } }
    public class tCore : PX.Data.BQL.BqlString.Constant<tCore> { public tCore() : base("C") { } }
    public class tUsed : PX.Data.BQL.BqlString.Constant<tUsed> { public tUsed() : base("U") { } }
}
#region usrSSCondition
[PXDBString]
[PXUIField(DisplayName = "Condition")]
[ConditionType.List]
public String UsrSSCondition { get; set; }
public abstract class usrSSCondition : PX.Data.BQL.BqlString.Field<usrSSCondition> { }
#endregion
#region INLocationExt_UsrSSCondition_FieldDefaulting
protected void INLocation_UsrSSCondition_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
    INLocation row = (INLocation)e.Row;

    string Loc = row?.LocationCD;
    if (Loc == null || Loc.Length == 0)
    {
        e.NewValue = ConditionType.Undefined;
    }
    else
    {
        e.NewValue = (Loc.Substring(Loc.Length - 1, 1)) switch
        {
            ConditionType.New => ConditionType.New,
            ConditionType.Repair => ConditionType.Repair,
            ConditionType.Core => ConditionType.Core,
            ConditionType.Used => ConditionType.Used,
            _ => ConditionType.Undefined,
        };
    }

}
#endregion

#region INLocation_LocationCD_FieldUpdated
protected void _(Events.FieldUpdated<INLocation.locationCD> e)
{
    INLocation row = (INLocation)e.Row;
    e.Cache.SetDefaultExt<INLocationExt.usrSSCondition>(row);
}
#endregion
#region INTran_LocationID_CachedAttached
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXRestrictor(typeof(Where<INLocationExt.usrSSCondition, NotEqual<ConditionType.core>,
     Or<Current<AccessInfo.screenID>, Equal<SSCS.Constants.NcmTagScreenID>>>), "")]
#endregion
#region INLocation_RowSelected
protected void _(Events.RowSelected<INLocation> e)
{
    INLocation row = e.Row;
    if(row?.SiteID != null)
    {
        INLocationExt rowExt = row.GetExtension<INLocationExt>();
        PXUIFieldAttribute.SetEnabled<INLocation.locationCD>(e.Cache, row, 
            !DisableLocationRename(row?.LocationID));
    }
}
#endregion

#region DisableLocationRename
protected virtual bool DisableLocationRename(int? locationID)
{
    int counter = PXSelect<SSINNcmTag,
        Where<SSINNcmTag.locationID, Equal<Required<SSINNcmTag.locationID>>,
          And<SSINNcmTag.tranRefNbr, IsNull>>>
        .SelectSingleBound(Base, null, locationID).Count;
    if (counter > 0) return true;
    counter = PXSelect<INLocationStatus,
        Where <INLocationStatus.locationID, Equal<Required<INLocationStatus.locationID>>,
          And<INLocationStatus.qtyOnHand, Greater<DecimalZero>>>>
        .SelectSingleBound(Base, null, locationID).Count;
    if (counter > 0) return true;
    return false;
}
#endregion