acumatica - 如何在 PXSelector 的 Search<> 参数中包含 DAC 扩展未绑定字段?
问题描述
我已经对 INLocation.LocationCD 进行了分段,并且需要限制 PXSelector 以根据输入位置的屏幕包含或排除特定段。我已经能够访问 PXSelector 显示列中的 DAC 扩展字段,但在 PXSelector 的 Search<> 参数期间该字段被评估为空。
我努力了:
- 直接引用 INLocationExt.myField,
- 制作继承的 DAC 以直接定义自定义字段,
- 并创建一个 PXProjection,希望附加层会导致检索未绑定的字段以填充 PXSelector,以防该字段没有及时加载以进行 Search<>。
关键点:
- 这是 DAC 扩展中的未绑定字段
- 它返回一个基于评估 INLocation.LocationCD 的最后一段的值
- 通用查询正确显示此值
- 当我引用未绑定字段时,我无法让 PXSelector 返回任何值,除非我简单地检查 And
我的 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> { }
PX 选择器:
[PXSelector(typeof(Search<INLocation.locationID, Where<INLocation.receiptsValid, Equal<True>,
And<INLocationExt.usrSSCondition, NotEqual<ConditionType.core>>>>),
typeof(INLocation.locationCD),
typeof(INLocation.active),
typeof(INLocation.primaryItemID),
typeof(INLocation.primaryItemClassID),
typeof(INLocationExt.usrSSCondition),
typeof(INLocation.receiptsValid),
SubstituteKey = typeof(INLocation.locationCD))]
PX投影:
[Serializable]
[PXCacheName("SSCS INLocation")]
[PXProjection(typeof(Select<INLocation>))]
public partial class SSINLocation : IBqlTable
{
#region LocationID
[PXDBInt(IsKey = true, BqlField = typeof(INLocation.locationID))]
public int? LocationID { get; set; }
public abstract class locationID : PX.Data.BQL.BqlInt.Field<locationID> { }
#endregion
#region LocationCD
[PXDBString(BqlField = typeof(INLocation.locationCD))]
public String LocationCD { get; set; }
public abstract class locationCD : PX.Data.BQL.BqlString.Field<locationCD> { }
#endregion
#region UsrSSCondition
[PXDBString(BqlField = typeof(INLocationExt.usrSSCondition))]
public String UsrSSCondition { get; set; }
public abstract class usrSSCondition : PX.Data.BQL.BqlString.Field<usrSSCondition> { }
#endregion
#region ReceiptsValid
[PXDBBool(BqlField = typeof(INLocation.receiptsValid))]
public bool? ReceiptsValid { get; set; }
public abstract class receiptsValid : PX.Data.BQL.BqlBool.Field<receiptsValid> { }
#endregion
#region Active
[PXDBBool(BqlField = typeof(INLocation.active))]
public bool? Active { get; set; }
public abstract class active : PX.Data.BQL.BqlBool.Field<active> { }
#endregion
#region PrimaryItemID
[PXDBInt(BqlField = typeof(INLocation.primaryItemID))]
public int? PrimaryItemID { get; set; }
public abstract class primaryItemID : PX.Data.BQL.BqlInt.Field<primaryItemID> { }
#endregion
#region PrimaryItemClassID
[PXDBInt(BqlField = typeof(INLocation.primaryItemClassID))]
public int? PrimaryItemClassID { get; set; }
public abstract class primaryItemClassID : PX.Data.BQL.BqlInt.Field<primaryItemClassID> { }
#endregion
}
我试过简单的版本和各种组合都无济于事。如何在 PXSelector 的 Search<> 子句中利用我的“条件”?
编辑 1: PXSelector 作为列返回值的图片 - 不能用作 PXRestrictor 或 Select<> 中的 where 子句。
编辑 2:更多信息
我已简化 DAC 扩展以使用 PXFormula 并选择 PXFormula 检索到的 LocationCD 的最后一个字符来设置值。
我们需要使用 LocationCD 的最后一段来管理 bin 中零件的状况。这将使我们能够将成本分开并管理 MRO 备件以进行维护,如新的、使用的、已修复的和需要维修的,同时还允许稍后指定其他条件(如收到损坏的 NCM 等)(如果需要)。虽然某些材料可以在全球范围内使用,但某些条件下的材料需要在某些用例下可用。我的预期策略是将规则应用于位置 CD 的最后一段,以允许 PXSelector 控制用户输入,如果需要,可以作为 INLocation 上的 DAC 扩展或作为相关图表中的 Cache_Attached。
我在 INLocation 上为 usrSSCondition 创建了一个 DAC 扩展作为 PXString。我最近的尝试是使用 PXFormula 来提取 LocationCD 值,然后在 set{} 上使用自定义代码来挑选最后一段并为相关条件设置代码。(这种技术对我来说实际上是新的,stackoverflow 帖子中的回应引导我想到了这个想法。)
在 PXSelector 中用作显示列时,我可以看到该值。但是, Select<> 不允许我进入用于显示该条件的那个段或自定义 PXString 字段。我希望一些“幕后魔术”会评估我的 PXString 字段以限制结果,但似乎该字段在 Select 期间返回为 null,然后在 DAC 处理的后续步骤中进行处理。当我考虑 Select 正在做什么时,没有存储在数据库中的数据不能用于过滤结果是有道理的。PXRestrictor 也不影响它。
1) 有没有办法让我的 DAC 在 PXSelector 应用 where 子句之前处理 PXString 值?2)这是我需要对属性进行后处理的东西吗?(如果是这样,关于在哪里寻找一个简单的例子有什么建议吗?)
更新的 DAC:
#region usrSSCondition
private String _condition;
[PXString]
[PXUIField(DisplayName = "Condition")]
[PXFormula(typeof(INLocation.locationCD))]
[ConditionType.List]
public String UsrSSCondition
{
get { return _condition; }
set
{
string Loc = value;
if (Loc == null || Loc.Length == 0)
{
_condition = ConditionType.Undefined;
}
else
{
_condition = (Loc.Substring(Loc.Length - 1, 1)) switch
{
"N" => ConditionType.New,
"R" => ConditionType.Repair,
"C" => ConditionType.Core,
"U" => ConditionType.Used,
_ => ConditionType.Undefined,
};
}
}
}
解决方案
永远不要在 getter 中使用代码,它不会在 BQL 表达式中正常工作!
如果你想检查Loc.Substring(Loc.Length - 1, 1)
BQL 中的某个地方,只需编写你自己的 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;
}
}
或使用现有功能的组合。例如:
[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") { } }
}
推荐阅读
- divio - 如何调试 Divio 应用程序的问题?
- python - 将浮点数转换为字符串并通过命名管道从 C 代码发送到 Python
- r - 使用 geom_col barplot 对多个条进行排序或排序
- php - 如何解决过多的重定向?
- java - Java 读取 CSR V3 扩展
- ios - 是否有可能让 UITableView 始终处于编辑模式,显示其插入或删除控件?如果是这样,怎么做?
- javascript - 通过仅重要的一个功能而不是整个包在后端“采摘”node.js 导入有什么好处?
- magento - 如何在 Google Cloud Platform GCP 上安装和配置 Magento 2.3.1
- postgresql - 如何针对 PostgreSQL 的多列搜索进行优化
- python - 传递元素以高效运行