How to make sure specific line from PXSelector is chosen - acumatica

I've got a PXSelector that selects several fields, the first one being a field whose value may be repeated (as follows):
Field1 Field2 Field3
1234 LL description1
1234 PS description2
1234 CC description3
4321 BB description4
PXSelector code:
[PXSelector(typeof(myTable.field1)
,typeof(myTable.field1)
,typeof(myTable.field2)
,typeof(myTable.field3)
,DescriptionField = typeof(myTable.field3))]
The DAC for the selected table has Field1 and Field2 as keys.
If I select row two or three above, I'll get the row one's Field3 description every time. Is there a way to ensure that I only get the description of the row that I've selected, instead of always getting the first occurrence?

You have to make the selector operate on a single key because the selected value is the key field not the whole DAC record.
One possible approach is to add a unique record number column to the database table, make the selector operate on that column and set a different 'TextField' property for the selector so it doesn't show the record number.
Here's how I did it to make a selector on SerialNumber/InventoryItem which is not a unique value (contains duplicate).
Database scripts will vary with database systems. I'm using this script for MSSQL to add the unique record number to the table:
--[mysql: Skip]
--[IfNotExists(Column = SOShipLineSplit.UsrUniqueID)]
BEGIN
alter table SOShipLineSplit add UsrUniqueID int identity(1,1)
END
GO
This is the DAC declaration. I use PXDBIdentity to match the DB identity field type that tag the column as a record number field:
[Serializable]
public class SOShipLineSplit_Extension : PXCacheExtension<SOShipLineSplit>
{
#region UsrUniqueID
public abstract class usrUniqueID : IBqlField { }
[PXDBIdentity(IsKey = false)]
[PXUIField(DisplayName = "ID")]
public virtual int? UsrUniqueID { get; set; }
#endregion
}
I use another DAC field for the selector which uses this unique id key and I set the description to the real field I want to appear in the selector:
#region SerialUniqueID
public abstract class serialUniqueID : IBqlField { }
[PXSelector(typeof(Search5<SOShipLineSplit_Extension.usrUniqueID,
InnerJoin<SOShipment, On<SOShipment.customerID, Equal<Current<customerID>>,
And<SOShipment.shipmentNbr, Equal<SOShipLineSplit.shipmentNbr>>>,
InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<SOShipLineSplit.inventoryID>>>>,
Where<SOShipLineSplit.lotSerialNbr, NotEqual<StringEmpty>>,
Aggregate<GroupBy<SOShipLineSplit.lotSerialNbr,
GroupBy<SOShipLineSplit.inventoryID>>>>),
typeof(SOShipLineSplit.lotSerialNbr),,
typeof(SOShipLineSplit.inventoryID),
typeof(InventoryItem.descr),
CacheGlobal = true,
DescriptionField = typeof(SOShipLineSplit.lotSerialNbr))]
[PXDBInt]
[PXUIField(DisplayName = "Serial Number")]
public virtual int? SerialUniqueID { get; set; }
#endregion
For this selector I want to display LotSerialNbr in the textbox instead of the unique id. Because the selector displays it's key by default I need to use the TextField property:
<px:PXSelector ID="edSerialUniqueID"
runat="server"
DataField="SerialUniqueID"
TextField="LotSerialNbr"
AutoGenerateColumns="True">
The selector value will contain the selected unique id field. To get the record you can issue another request to the database using that key.

Related

For acumatica, how can I sum the values of two grid columns within a FormTab and assign that value to a field that's above the FormTabs area?

In the image below, the three fields in the first red square are the ones that I want a calculated value to be. For example, Actual Income would hold the sum of the two columns at the bottom with the red square (I'm not trying to necessarily grab those two fields for the sum, but they just serve as an example).
So what I'm wondering is how would I go about summing up all the values within those two columns and adding the result to one of the three fields (e.g. Actual Income)?
Any help on this issue would be greatly appreciated :D
The image below shows the details for the column 'Original Budgeted Amount'
The image below shows the details for the field 'Actual Income'
#WARNING# After a review of the base code it appears those three header fields are used in the calculation of accumulative table ( financial history ) PMTaskTotal as such I would highly suggest not modifying values.
As an alternative :
One method is to add another field to the child record to hold the summary amount of the two fields wanted, I would then add an additional field to the header to hold the calculated value.
Child record field:
#region CuryAmount
/// <summary>
/// The amount that is a summary of your two fields
/// </summary>
public abstract class curyAmount : BqlDecimal.Field<curyAmount>
{
}
[PXDefault(TypeCode.Decimal, "0.0")]
[PXFormula(typeof(Sum<field1, field2>))] //Calculates sum of fields
[PXUIField(DisplayName = "Summary Field", Required = true)]
[PXUnboundFormula(typeof(curyAmount), typeof(SumCalc<Header.sumfield>))] //Assigns values to header field
public virtual decimal? CuryAmount { get; set; }
#endregion
Parent record field :
#region CuryTotalAmount
/// <summary>
/// The total amount in the from the summed childrecords.
/// </summary>
public abstract class curyTotalAmount : BqlDecimal.Field<curyTotalAmount>
{
}
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Total Amount", Enabled = false)]
public virtual decimal? CuryTotalAmount { get; set; }
#endregion

Dynamically changing field's DisplayName affests web service

The field in the DAC is defined like this.
#region NextMonthHours
[PXDBDecimal(2, MinValue = 0.0, MaxValue = 280.0)]
[PXUIField(DisplayName = "Next Month Hours")]
[PXDefault(TypeCode.Decimal, "0.0")]
public virtual Decimal? NextMonthHours { get; set; }
public abstract class nextMonthHours : PX.Data.BQL.BqlDecimal.Field<nextMonthHours> { }
#endregion
I change the display name of the field in RowSelected event.
PXUIFieldAttribute.SetDisplayName<EVEPPlannedHoursDetails.nextMonthHours>(sender, nextMonth+"Hours");
where nextMonth is "February".
I need to add this field to Acumatica Mobile Screen. When I go to web service schema the field name is "FebruaryHours"
<s:element minOccurs="0" maxOccurs="1" name="FebruaryHours" type="tns:Field"/>
I cannot use the name "FebruaryHours" because it changes every month but I also when I use field name NextMonthHours it is not added in the mobile screen.
Any idea how to solve this issue?
Thanks
There's quite a few ways to workaround this depending on the use case and whether the label value is static or dynamic.
If all you want to do is to change a static label in UI without having to change the display name property you can add a separate label and merge group.
Here's an example to change Billable in UI without changing DisplayName property using that technique.
Set SuppressLabel property to true to hide the original label bounded to DisplayName on UI.
Use ADD CONTROLS tab to add a Layout Rule with Merge property set to true.
Use ADD CONTROLS tab to add a label control in the merged group.
Put the original field in the merge group so they show up together on the same line in UI.
End result, label is now a UI control and wouldn't interfere with DisplayName property.

Hiding Column for all the users in the Column Configuration

i would like to Hide the column(except Inventory ID and Description) in the "Expense Item" Lookup screen on the Expense Receipt screen(EP301020) for all the users.
How can i set that some columns (which are not needed) in the "Available column" section in "Column Configuration" by default for all the users and only the required ones are available in the lookup screen.By default, all the columns are included in the selected column list in the Column Configuration.
Please advise.
Thanks
Below is code to hide the columns from Available and Selected list box. If all you need is to initialize the columns in Available and Selected list box consider using Acumatica Default Table Layout feature. Note that column configuration is a user configuration so you can initialize the columns but you can't override the user choices after initialization.
To completely remove the columns from the selector you need to redefine the InventoryID selector and explicitly declare the columns you want to see in the second parameter of PXSelector.
You can do so by creating a graph extension on ExpenseClaimDetailEntry and using CacheAttached method to redefine the selector:
using PX.Data;
using PX.Objects.IN;
namespace PX.Objects.EP
{
public class ExpenseClaimDetailEntry_Extension : PXGraphExtension<ExpenseClaimDetailEntry>
{
[PXMergeAttributes(Method = MergeMethod.Replace)]
[PXDefault]
[PXUIField(DisplayName = "Expense Item")]
[PXSelector(typeof(InventoryItem.inventoryID),
/* List of available/visible columns go here */
new Type[] { typeof(InventoryItem.inventoryCD),
typeof(InventoryItem.descr) },
SubstituteKey = typeof(InventoryItem.inventoryCD),
DescriptionField = typeof(InventoryItem.descr))]
[PXRestrictor(typeof(Where<InventoryItem.itemType, Equal<INItemTypes.expenseItem>>), Messages.InventoryItemIsNotAnExpenseType)]
protected virtual void EPExpenseClaimDetails_InventoryID_CacheAttached(PXCache sender)
{
}
}
}

PXDBCreatedDateTime doesn't work in Extension Table

I have a User Defined Table that I link to the BAccount table in Acumatica. What I'm trying to do is use the PXDBCreatedDateTime attribute to save the CreateDateTime when the UDFs are set. Is this posssible? It doesn't seem to work right now.
[PXTable(typeof(BAccount.bAccountID),IsOptional=true)]
public class CustomerExtension : PXCacheExtension<BAccount>
{
[PXDBCreatedDateTime()]
[PXUIField(DisplayName = "Date")]
public DateTime? CreatedDateTime { get; set; }
public class createdDateTime : IBqlField { }
}
I would assume it would not work as the BAccount table already contains a field with the same name 'CreatedDateTime'. I would first use a different field name for table extension fields as this could create some conflicts to those fields that already exist with the same name. Also, extension tables are inserted when the base table is either inserted or updated (first time after extension table is added) which may or may not occur from changes to your extension fields. This would also cause some issues for getting a good date from your PXDBCreatedDateTime field. You might be better off using a standard date time field and use some type of formula to update the date when your fields change. I would have to research the formula. You could use logic inside the setter of your user fields and add the PXDependsOnFields attribute to your date field and set your date field if null. I have not tried PXDependsOnFields in an extension - but the logic could be promising.

Filtering of RefNbr PXSelector on Expense Claim

I need to customize the Expense Claim screen (EP301000) to do the following:
Add user field as a checkbox to header section (Done)
Use that checkbox value to filter the RefNbr PXSelector lookup to only show results for the Employee ID shown on the 'Claimed By' field.
Looking at the DAC for RefNbr, I don't see any normal PXSelector lookup that I'm used to seeing.
Is there a way to do this?
You can see the DACField is using an attribute [EPExpenceClaimSelector]
The definition of that is as below
public class EPExpenceClaimSelectorAttribute : PXSelectorAttribute
{
public EPExpenceClaimSelectorAttribute()
: base(typeof(Search2<EPExpenseClaim.refNbr,
InnerJoin<EPEmployee, On<EPEmployee.bAccountID, Equal<EPExpenseClaim.employeeID>>>,
Where<EPExpenseClaim.createdByID, Equal<Current<AccessInfo.userID>>,
Or<EPEmployee.userID, Equal<Current<AccessInfo.userID>>,
Or<EPEmployee.userID, OwnedUser<Current<AccessInfo.userID>>,
Or<EPExpenseClaim.noteID, Approver<Current<AccessInfo.userID>>,
Or<EPExpenseClaim.employeeID, WingmanUser<Current<AccessInfo.userID>>>>>>>, OrderBy<Desc<EPExpenseClaim.refNbr>>>)
, typeof(EPExpenseClaim.docDate)
, typeof(EPExpenseClaim.refNbr)
, typeof(EPExpenseClaim.status)
, typeof(EPExpenseClaim.docDesc)
, typeof(EPExpenseClaim.curyDocBal)
, typeof(EPExpenseClaim.curyID)
, typeof(EPEmployee.acctName)
, typeof(EPExpenseClaim.departmentID)
)
{
}
}
You can use the same approach to create an attribute of your own with additional condition and use it in your cache attached method to replace the default selector.

Resources