Acumatica custom field needs PXSelector for specific attribute Description values - acumatica

I have added a custom field to a screen and want to have a Selector to choose values from the Description of a specific attribute called BASEITEM.
[PXDBString(50, IsUnicode = true)]
[PXUIField(DisplayName = "Document Number", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<CSAttributeDetail.Description,
Where<CSAttributeDetail.AttributeID.StartsWith("BASEITEM")>,
OrderBy<Asc<CSAttributeDetail.Description>>>),
DescriptionField = typeof(CSAttributeDetail.Description)]
However, when I try to publish this I get errors.
Building directory '/WebSiteValidationDomain/App_RuntimeCode/'.
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1003: Syntax error, '>' expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1525: Invalid expression term ','
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1026: ) expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(27): error CS1003: Syntax error, ']' expected
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(28): error CS1519: Invalid token '>' in class, struct, or interface member declaration
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(29): error CS1519: Invalid token '=' in class, struct, or interface member declaration
/AcuDocCenterWebsite/App_RuntimeCode/PX_Objects_IN_InventoryItem_extensions.cs(29): error CS1519: Invalid token ')' in class, struct, or interface member declaration
Compiler time, seconds: 0.8243028
Validation failed.

There are a couple of strange things in your attributes, so let's try if fixing them will resolve your problem. Here is the complete snippet that should work :
[PXDBString(50, IsUnicode = true)]
[PXUIField(DisplayName = "Document Number", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<CSAttributeDetail.description,
Where<CSAttributeDetail.attributeID, Like<string_BASEITEMPCT>>,
OrderBy<Asc<CSAttributeDetail.description>>>),
DescriptionField = typeof(CSAttributeDetail.description))]
Here is the constant class used in the PXSelector attribute
public class string_BASEITEMPCT : Constant<string>
{
public string_BASEITEMPCT()
: base("BASEITEM%")
{
}
}
You were missing a parenthesis at the end of the PXSelector attribute which prevented build and publish.
You need to use the classes inheriting IBqlField instead of specific field i.e. use the lowercase class instead of the uppercase field when doing BQL.
To compare a field value to a string, use the Like<> operator and a string constant. To create that constant, create a class and specify the string value as the argument of the base constructor. The % at the end of "BASEITEM%" has the same purpose as the SQL wildcard %

Related

Why is my PXFormula with PXDBShorts Throwing Specified Cast Error?

I have a formula I am using the calculate a non-persisting field. I'm redefining a base DAC field: POVendorItem.VLeadTime. This is my new definition:
#region VLeadTime
[PXShort(MinValue = 0, MaxValue = 100000)]
[PXUIField(DisplayName = "Vendor Lead Time (Days)", Enabled = false)]
[PXFormula(typeof(Sub<Current<usrCFAvgLeadTime>, Current<POVendorInventory.addLeadTimeDays>>))]
public virtual short? VLeadTime { get; set; }
#endregionv
Both fields in the formula are defined as PXDBShorts, yet I keep getting a "Specified cast is not valid" error when trying to access the grid the field is on. Here is the trace:
I've also noticed that if I type out a statement such as short? = short? - short? I also get an error in VS stating I can't convert an int? to a short? which doesn't make sense. For me to correctly calculate it, VS auto corrects the formula to short? = (short?)((short)(short?) - (short)(short?)) adding in a ton of type casts.
To get around the formula, I would attach events to field defaulting for VLeadTime, as well as field updating for usrCFAvgLeadTime and addLeadTimeDays and then recalculate it and set the value. I know it is redundant, but as long as you can set the value to a short in visual studio in the code, it would set for VLeadTime.

Use HashSet with a user defined class in an Xtext validator

I'm writing a small DSL that stores a list of coordinates:
Model:
locations+=Coordinates*
;
Coordinates:
'(' x=INT ',' y=INT ')'
;
I'm working now on the validator, and one of the things I want to make sure is that the list does not contain the same location (set of coordinates) twice. For this, I've written the following validator check:
#Check
def checkLocation(Model model) {
val locationSet = newHashSet
for (location : model.locations) {
if (!locationSet.add(location)) {
error('Locations must be unique.', location, LOCATION)
}
}
}
So that the locations get added to a HashSet and an error occurs if the same locations gets added twice. However, this doesn't work (the error never gets triggered). I'm guessing because the class Coordinates does not define the hashCode and equals methods that are required for the HashSet to work.
Any ideas on how could I make the HashSet work? Is it possible to define the implementation of the hashCode and equals methods of the generated class?

Acumatica conditional update - Cannot implicitly convert type 'string' to 'bool'

We have written code to update Base Price on the non-stock item maintenance window when the MSRP field is changed with the following code:
protected void InventoryItem_RecPrice_FieldUpdated(PXCache cache, PXCommandPreparingEventArgs e)
{
var row = (InventoryItem)e.Row;
InventoryItemExt itemExt = row.GetExtension<InventoryItemExt>();
INPriceClass itemPriceClass = PXSelect<INPriceClass, Where<INPriceClass.priceClassID, Equal<Current<InventoryItem.priceClassID>>>>.Select(Base);
INPriceClassExt priceClassExt = row.GetExtension<INPriceClassExt>();
//FIXED, MSRP PLUS, MSRP PERCENTAGE
if (priceClassExt.UsrPricingCategoryID = "FIXED")
{
cache.SetValue<InventoryItem.basePrice>(row, row.RecPrice + priceClassExt.UsrPricingFixedAmount);
}
}
However, we get the following error:
\App_RuntimeCode\NonStockItemMaint.cs(49): error CS0029: Cannot implicitly convert type 'string' to 'bool'
\App_RuntimeCode\NonStockItemMaint.cs(49): error CS0029: Cannot implicitly convert type 'string' to 'bool'
Compiler time, in seconds: 6.0001164
This error happens because you are using the assignment operator (=) instead of the equality operator (==). To fix, simply change the if statement to:
if (priceClassExt.UsrPricingCategoryID == "FIXED")

BQL in PXSelector to filter by a Starts With

I've got a field in my DAC where I want to put a selector that looks up the SalesPersons. I know how to do this:
[PXSelector(typeof(SalesPerson.salesPersonCD)
,typeof(SalesPerson.salesPersonCD)
,typeof(SalesPerson.descr))]
My problem is that I want to filter this selector based on the first three characters of the SalesPerson CD, i.e., StartsWith "SSR" or something similar. I know you can use BQL in a selector using the Search<> command, and I know how to set up a constant class, but I'm not sure of the syntax to filter by beginning characters.
Short of creating a custom BQL operator, you can achieve "Starts with" by using the LIKE operator, with the % wildcard at the end. The BQL field you're filtering on could be a DAC property with custom code in the get accessor, which takes your user-entered field and adds the wildcard character at the end, like that:
public abstract class myFieldWildcard : PX.Data.IBqlField { };
[PXString(30, IsUnicode = true)]
public virtual String MyFieldWildcard
{
[PXDependsOnFields(typeof(myField)]
get
{
return MyField + PXDatabase.Provider.SqlDialect.WildcardAnything;
}
}
You'll then be able to use that field as part of your PXSelector attribute:
[PXSelector(typeof(Search<SomeTable.someField, Where<SomeTable.someField,Like<Current<MyFilter.myFieldWildcard>>>>))]

Set Cobol method attribute property

In Micro Focus managed Cobol, how can we set value of a method attribute?
Viz. In C# we do
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public override string[] Method
So in Cobol we declare the method as
method-id MethodName public
attribute OperationContractAttribute
attribute WebGetAttribute.
But how do we set ResponseFormat = WebMessageFormat.Json ?
Similar (but not identical) to C#. The biggest difference is that the keyword 'property' has to be used before the property name.
method-id MethodName public
attribute OperationContractAttribute
attribute WebGetAttribute(property ResponseFormat = type WebMessageFormat::Json).

Resources