How to default an employeeid field to the current logged in user - acumatica

I have a custom inquiry screen which uses an employeeid as the header filter field. What I'd like to do is default that employeeid field to the current logged in user, if possible. I've tried the following, but both give me a cast error (version 5.3.2562):
1.) [PXDBDefault(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.bAccountID, Equal<Current<AccessInfo.userID>>>>))]
2.) [PXDBDefault(typeof(AccessInfo.userID))]
Here's the entire DAC code for the filter field:
#region EmployeeID
public abstract class employeeID : IBqlField
{
}
[PXInt]
[PXDBDefault(typeof(AccessInfo.userID))]
[PXUIField(DisplayName = "Employee ID")]
[PXSelector(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.status, Equal<SetupTypes.active>>>),
typeof(EPEmployee.acctCD),
typeof(EPEmployee.acctName),
SubstituteKey = typeof(EPEmployee.acctCD),
DescriptionField = typeof(EPEmployee.acctName))]
public virtual int? EmployeeID { get; set; }
#endregion
What's the correct way to obtain this?
Update 6/30/2017:
After implementing the solution (using PXDefault instead of PXDBDefault) as follows:
[PXDefault(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.bAccountID, Equal<Current<AccessInfo.userID>>>>))]
I get the following error:

We have a non filter field in a transaction able that defaults to the current employee.
This should work:
[PXDefault(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.bAccountID, Equal<Current<AccessInfo.userID>>>>))]
Note that you do not want to use PXDBDefault for default values unless they are values coming from a parent DAC when linked with PXParent. Use PXDefault for defaults.
If this does not work in your filter, try PXUnboundDefault in place of PXDefault.
Edit 6/30/2017: new error might be on your selector. There is an employee selector already available. Remove your PXSelector and use [PXEPEmployeeSelector] on your field and see if this solves your error between uniqueidentifier and int

AccessInfo.userID seems to be a GUID. In order to avoid the casting error you need to relate AccessInfo.userID to EPEmployee.userID while searching for EPEmployee.bAccountID. Final code should look like this:
#region EmployeeID
public abstract class usrEmployeeID : IBqlField
{
}
[PXEPEmployeeSelector]
[PXUnboundDefault(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.userID, Equal<Current<AccessInfo.userID>>>>))]
[PXUIField(DisplayName = "Employee ID")]
public virtual int? UsrEmployeeID { get; set; }
#endregion

Related

PXSelector attribute suppress Error on form

Good day
I have created a custom Location field for warehouse locations:
#region UsrTOLocation
[PXString]
[PXUIField(DisplayName = "To Location")]
[PXSelector(typeof(Search<
INLocation.locationCD,
Where<INLocation.siteID, Equal<Current<INRegister.toSiteID>>>>))]
public virtual string UsrTOLocation { get; set; }
public abstract class usrTOLocation : PX.Data.BQL.BqlString.Field<usrTOLocation> { }
#endregion
When the location does not exist I create it using code in a button.
Since I have added the PXSelector to the above field I keep getting an error when it doesn't find the locations. This is correct because I still need to create it
Is there a way to suppress the error that it is not finding the location?
You can use ValidateValue property of the PXSelector attribute.
For instance:
[PXSelector(..., ValidateValue = false)]
It disables validation and therefore error appearing in PXSelector attribute

Show unbound field with PXFormula

I'm trying to show a value calculated with PXFormula but the field doesn't show the value.
I have my CustomDAC named EDITran
public class EDITran : IBqlTable
{
#region Doctype
[PXDBString(50, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Doctype")]
[PXStringList
(new string[]
{"SO", "SHI", "INV" },
new string[]
{"Sales Order", "Shipment", "Invoice"}
)]
public virtual string Doctype { get; set; }
public abstract class doctype : PX.Data.BQL.BqlString.Field<doctype> { }
#endregion
#region Erprefnbr
[PXDBString(30, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "ERP RefNbr")]
public virtual string Erprefnbr { get; set; }
public abstract class erprefnbr : PX.Data.BQL.BqlString.Field<erprefnbr> { }
#endregion
#region Sync
[PXDBBool()]
[PXUIField(DisplayName = "Sync")]
public virtual bool? Sync { get; set; }
public abstract class sync : PX.Data.BQL.BqlBool.Field<sync> { }
#endregion
}
}
so I what to show the value of sync field on the Sales Order screen. The key is the ERP RefNbr (which would be SOOrder.OrderNbr)
I have added the custom non persisted field on the SOOrderExt DAC with this attributes
using PX.Objects.SO;
[PXBool]
[PXUIField(DisplayName="EDI Sync" , Enabled = false)]
[PXFormula(typeof(Selector<SOOrder.orderNbr,
Selector<EDITran.erprefnbr,
EDITran.sync>>))]
But when I added a record in EDITran and try to visualize it in SOOrder Form and I checked that EDITran.Sync = 1, it doesn't show the saved value.
Sales Order Screen
What I'm I doing wrong? Is the PXFormula correctly used?
PXFormula used incorrectly. PXFormula attribute works only with current DAC (which is SOOrder) or foreign DAC, existing in PXSelector join condition (you can use Selector keyword to get it).
For example, here is the SOOrder.OrderNbr selector declaration
[SO.RefNbr(typeof(Search2<SOOrder.orderNbr,
LeftJoinSingleTable<Customer, On<SOOrder.customerID, Equal<Customer.bAccountID>,
And<Where<Match<Customer, Current<AccessInfo.userName>>>>>>,
Where<SOOrder.orderType, Equal<Optional<SOOrder.orderType>>,
And<Where<Customer.bAccountID, IsNotNull,
Or<Exists<Select<SOOrderType,
Where<SOOrderType.orderType, Equal<SOOrder.orderType>,
And<SOOrderType.aRDocType, Equal<ARDocType.noUpdate>,
And<SOOrderType.behavior, Equal<SOBehavior.sO>>>>>>>>>>,
OrderBy<Desc<SOOrder.orderNbr>>>), Filterable = true)]
public virtual String OrderNbr
you can get some fields from the related Customer record, using Selector keyword
[PXFormula(typeof(Selector<
SOOrder.orderNbr,
Customer.consolidateStatements>))]
As a result, there are two possible solutions:
1) Rewrite SOOrder.OrderNbr selector declaration with your EDITran DAC
...
[SO.RefNbr(typeof(Search2<SOOrder.orderNbr,
LeftJoinSingleTable<Customer, On<SOOrder.customerID, Equal<Customer.bAccountID>,
And<Where<Match<Customer, Current<AccessInfo.userName>>>>>,
LeftJoin<EDITran, On<EDITran.doctype, Equal<SOOrder.orderType>,
And<EDITran.erprefnbr, Equal<SOOrder.orderNbr>>>>>,
Where<SOOrder.orderType, Equal<Optional<SOOrder.orderType>>,
And<Where<Customer.bAccountID, IsNotNull,
Or<Exists<Select<SOOrderType,
Where<SOOrderType.orderType, Equal<SOOrder.orderType>,
And<SOOrderType.aRDocType, Equal<ARDocType.noUpdate>,
And<SOOrderType.behavior, Equal<SOBehavior.sO>>>>>>>>>>,
OrderBy<Desc<SOOrder.orderNbr>>>), Filterable = true)]
public virtual String OrderNbr
Then it will be possible to get you field from there
[PXFormula(typeof(Selector<
SOOrder.orderNbr,
EDITran.sync>))]
2) Use PXDBScalar attribute to just get what you need. Note this will be a separate request to the database!!
...
[PXBool]
[PXDBScalar(typeof(Search<EDITran.sync,
Where<EDITran.doctype, Equal<SOOrder.orderType>,
And<EDITran.erprefnbr, Equal<SOOrder.orderNbr>>>>))]
public virtual bool? Sync
I'm not sure that's the right use of PXFormula. Here's the reference I normally use when I need to use PXFormula. See if it helps you simplify your PXFormula. You may need to simplify to a single Selector and define a foreign key to be able to complete your lookup.
Also, are you sure that the database contains the values that you expect? I often find that my problem is not where I think, and your issue may lie in setting the values or writing them to the database in your business logic.
It appears that you need the PXFormula to look to your EDITran table to find the record identified by the key (1st field specified in Selector) to then return back the value of the second field specified, which would reside in EDITran.
From Acumatica Developers Blog (AsiaBlog):
Selector
Selector does following:
Fetches a PXSelectorAttribute defined on the foreign key field (KeyField) of the current DAC.
Fetches the foreign data record currently referenced by the selector.
Using calculates and returns an expression on that data record as defined by ForeignOperand.
public class APVendorPrice : IBqlTable
{
// Inventory attribute is an aggregate containing a PXSelectorAttribute
// inside, which is also valid for Selector<>.
[Inventory(DisplayName = "Inventory ID")]
public virtual int? InventoryID
[PXFormula(typeof(Selector<
APVendorPrice.inventoryID,
InventoryItem.purchaseUnit>))]
public virtual string UOM { get; set; }
}
From that, I'd expect your PXFormula to look more like:
[PXFormula(typeof(Selector<
SOOrder.orderNbr,
EDITran.sync>))]
... assuming you have enough defined to tell Acumatica how to relate SOOrder.orderNbr to EDITran.erprefnbr.

Acumatica how to make a Custom Branch field not mandatory or be able to select branch from a lookup

I'm facing the following issue:
I have created a user field "UsrBranch".
Using the Branch lookup from the SO Financial Settings, I'm able to select and save into my new "UsrBranch" field, but it makes the field mandatory, even when I set the field as "Required = false".
Example 1:
[PXUIField(DisplayName = "Branch")]
[Branch(typeof(Coalesce<Search<Location.cBranchID,
Where<Location.bAccountID, Equal<Current<SOOrder.customerID>>,
And<Location.locationID, Equal<Current<SOOrder.customerLocationID>>>>>,
Search<Branch.branchID, Where<Branch.branchID,
Equal<Current<AccessInfo.branchID>>>>>), Required = false)]
public virtual Int32? UsrBranch { get; set; }
public abstract class usrBranch : PX.Data.BQL.BqlString.Field<usrBranch> { }
If I change the lookup to a PXSelector it displays the Branches, but I'm not able to select any.
Example 2:
[PXUIField(DisplayName = "Branch")]
[PXSelector(typeof(Branch.branchID),
SubstituteKey = typeof(Branch.branchCD))]
public virtual Int32? UsrBranch { get; set; }
public abstract class usrBranch : PX.Data.BQL.BqlString.Field<usrBranch> { }
Any Help will be gratefully appreciated.
The "Required" Property controls whether or not the star will show up on the field in the UI. The "PersistingCheck" property on the PXDefaultAttribute controls whether or not a value is mandatory.
The constructor of the BranchAttribute adds a PXDefaultAttribute to the field, and the default value for the "PersistingCheck" property is PXPersistingCheck.Null. This disallows the field from being null when saved. Since BranchAttribute derives from the AcctSubAttribute/PXAggregateAttribute you can set the "PersistingCheck" property on the BranchAttribute and it will set the "PersistingCheck" property on the added PXDefaultAttribute. To make it so the field can be null, set the "PersistingCheck" property to PXPersistingCheck.Nothing on the BranchAttribute:
[Branch(typeof(Coalesce<
Search<Location.cBranchID,
Where<Location.bAccountID, Equal<Current<SOOrder.customerID>>,
And<Location.locationID, Equal<Current<SOOrder.customerLocationID>>>>>,
Search<Branch.branchID,
Where<Branch.branchID, Equal<Current<AccessInfo.branchID>>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual int? UsrBranch { get; set; }
Additionally, there is a PXUIFieldAttribute on the BranchAttribute so adding another one onto the field is redundant.

Acumatica Numbering Sequence - cant default to the new symbol

I've got a custom table storing serviceable components within fixed assets. The list is accessed using a grid on the AssetMaint screen.
I've set up an ID field to populate using a numbering sequence. I'm unsure how to set the default so this field populates with "<NEW>" by default, which is then updated by the numbering sequence when the component is saved.
It's sort of working, but there are a few issues. When I click the add button, the ID field is blank, but when I click add again, it populates with the "<NEW>" symbol. However if I add a third record before hitting save, the second record does not populate with "<NEW>". The second record is also not saved, unless I manually put "<NEW>" in the ID field.
This is part of the DAC for the component table:
[Serializable]
public class FAServiceComponent : IBqlTable
{
#region AssetID
public abstract class assetID : IBqlField { }
[PXDBInt(IsKey = true)]
[PXDBDefault(typeof(FixedAsset.assetID), DefaultForUpdate = false)]
[PXParent(typeof(Select<FixedAsset, Where<FixedAsset.assetID, Equal<Current<FAServiceComponent.assetID>>>>))]
[PXUIField(DisplayName = "Asset ID", Visible = false, Enabled = false)]
public virtual int? AssetID { get; set; }
#endregion
#region serviceComponentID
public abstract class serviceComponentID : IBqlField { }
[PXDBString(30, IsKey = true, IsUnicode = true)]
[PXUIField(DisplayName = "Component ID")]
[PXDefault(typeof(Search2<Numbering.newSymbol,
InnerJoin<FixedAsset, On<FixedAssetExt.usrServiceComponentNumberingSeq, Equal<Numbering.numberingID>, And<FixedAsset.assetID, Equal<Current<FixedAsset.classID>>>>>>))]
[Numbering]
public virtual string ServiceComponentID { get; set; }
#endregion
#region serviceComponentDescription
public abstract class description : IBqlField { }
[PXDBString(255)]
[PXUIField(DisplayName = "Description")]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
public virtual string Description { get; set; }
#endregion
public class NumberingAttribute : AutoNumberAttribute
{
public NumberingAttribute():
base(typeof(Search<FixedAssetExt.usrServiceComponentNumberingSeq, Where<FixedAsset.assetID, Equal<Current<FixedAsset.classID>>>>),
typeof(AccessInfo.businessDate)) {; }
}
}
Check out T200 course available at Acumatica Open University. Part 4 Lesson 8 show you how to use the AutoNumberAttribute.
I would first suggest to remove the following code, as it is not required to make the < New > symbol work.
[PXDefault(typeof(Search2<Numbering.newSymbol,
InnerJoin<FixedAsset, On<FixedAssetExt.usrServiceComponentNumberingSeq, Equal<Numbering.numberingID>, And<FixedAsset.assetID, Equal<Current<FixedAsset.classID>>>>>>))]
You should have a setup screen where you choose the numbering sequence you want to use. As an example, the Sales Orders Preferences screen (SO101000) has the Shipment Numbering Sequence field, bound to SOSetup.ShipmentNumberingID.
In your graph, make sure you have the setup data view, something like public PXSetup<Setup> AutoNumSetup;. The PXSetup DAC should match with your setup screen, e.g. PXSetup<SOSetup> ShipmentSetup
In your DAC, the numbered field should have the AutoNumberAttribute referencing the setup table. e.g.
[AutoNumber(typeof(SOSetup.ShipmentNumberingID), typeof(SOShipment.shipDate))]
In Numbering Sequence screen (CS201010), make sure that Manual Numbering is unchecked and that you have a New Number Symbol set for the numbering sequence you are using.

Adding Owner Name in the Purchase Order Lookup screen

I would like to add the Owner Name (on the PO Screen) in the Purchase Order>Order Nbr. field lookup screen. I tried to manually add the following in the Data Class for OrdNbr but it didn't bring the Employee name in the lookup screen. Can you please help or let me know if i am missing something.
Here is the full code i am trying(screenshot attached)
[PXCustomizeSelectorColumns(
typeof(PX.Objects.PO.POOrder.orderType),
typeof(PX.Objects.PO.POOrder.orderNbr),
typeof(PX.Objects.PO.POOrder.vendorRefNbr),
typeof(PX.Objects.PO.POOrder.orderDate),
typeof(PX.Objects.PO.POOrder.status),
typeof(PX.Objects.PO.POOrder.vendorID),
typeof(PX.Objects.PO.POOrder.vendorID_Vendor_acctName),
typeof(PX.Objects.PO.POOrder.vendorLocationID),
typeof(PX.Objects.PO.POOrder.curyID),
typeof(PX.Objects.PO.POOrder.curyOrderTotal),
typeof(PX.Objects.PO.POOrder.sOOrderType),
typeof(PX.Objects.PO.POOrder.sOOrderNbr),
typeof(PX.Objects.PO.POOrder.orderDesc),
typeof(PX.Objects.CR.CREmployee.acctCD),
typeof(PX.Objects.CR.CREmployee.bAccountID),
typeof(PX.Objects.CR.CREmployee.acctName))]
Many Thanksenter image description here
Since POOrder.employeeID has a PXSelector attribute on its definition:
And this Selector has a DescriptionField assigned:
On this case you can add Owner name by adding this line of code to your CacheExtension file(This will obtain that DescriptionField for the EmployeeID field):
public abstract class employeeID_CREmployee_acctName : PX.Data.IBqlField { }
See Snippet below:
namespace PX.Objects.PO
{
[PXNonInstantiatedExtension]
public class PO_POOrder_ExistingColumn : PXCacheExtension<PX.Objects.PO.POOrder>
{
#region OwnerName
public abstract class employeeID_CREmployee_acctName : PX.Data.IBqlField
{ }
#endregion
#region OrderNbr
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXCustomizeSelectorColumns(
typeof(PX.Objects.PO.POOrder.orderType),
typeof(PX.Objects.PO.POOrder.orderNbr),
typeof(PX.Objects.PO.POOrder.vendorRefNbr),
typeof(PX.Objects.PO.POOrder.orderDate),
typeof(PX.Objects.PO.POOrder.status),
typeof(PX.Objects.PO.POOrder.employeeID),
typeof(PX.Objects.PO.PO_POOrder_ExistingColumn.employeeID_CREmployee_acctName),
typeof(PX.Objects.PO.POOrder.vendorID),
typeof(PX.Objects.PO.POOrder.vendorID_Vendor_acctName),
typeof(PX.Objects.PO.POOrder.vendorLocationID),
typeof(PX.Objects.PO.POOrder.curyID),
typeof(PX.Objects.PO.POOrder.curyOrderTotal),
typeof(PX.Objects.PO.POOrder.sOOrderType),
typeof(PX.Objects.PO.POOrder.sOOrderNbr))]
public string OrderNbr { get; set; }
#endregion
}
}
Please notice that in case the POOrder.EmployeeID field would not have the "DescriptionField" set on the PXSelector Definition, you would have to modify the PXSelector of the OrderNbr to add a LeftJoin on the Desired Table(CREmployee on this case) so you could use the desired fields and add them to the PXCustomizeSelectorColumns attribute.

Resources