I want to change the display name of PXSelector Description Field for a specific page. I try as below but it is not working:
PXUIFieldAttribute.SetDisplayName(sender, "DistributorID_description", "ABC-XYZ");
try using the initialize() instead of row selected to set the same using the below syntax
PXUIFieldAttribute.SetDisplayName<DACName.fieldName>(CacheRelatedToYourDAC, "newValue");
OR
you can use the CacheAttached Event to change the displayname of your field. Dont forget to copy all your existing attributes here
[DAC_Field_Attribute_1]
...
[DAC_Field_Attribute_N]
protected virtual void DACName_FieldName_CacheAttached(PXCache sender)
{
...
}
Related
Multi-part identifier error
I newly created one extension field in Contacts screen (UsrLocationCD int field). After creatimg that field I added that field into the view query and I got the above error.
The concept is the "Customer and Location ID" (Customer Location screen) should match in Contacts screen "Business Account and Location ID" (Location ID, newly added). After this condition is satisfied that related Contact ID should display in Customer Location screen under the Contacts Tab.
Full concept
This the query what I wrote:
[PXViewName(Messages.Contacts)]
[PXFilterable]
[PXViewSavedDetailsButton(typeof(Location))]
public PXSelectJoin<Contact,
LeftJoin<Address, On<Address.addressID, Equal<Contact.defAddressID>>>,
Where<Contact.bAccountID, Equal<Current<Location.bAccountID>>,
And<Where<ContactExt.usrLocationCD, Equal<Location.locationID>,
And<Where<Contact.contactType, Equal<ContactTypesAttribute.person>,
Or<Contact.contactType, Equal<ContactTypesAttribute.lead>>>>>>>> Contacts;
here is the newly created extension field:
public class ContactExt : PXCacheExtension<PX.Objects.CR.Contact> /*, IBqlTable*/
{
#region UsrLocationCD
[PXDBInt()]
[PXUIField(DisplayName = "Location ID")]
[PXSelector(
typeof(Search<Location.locationID, Where<Location.bAccountID,
Equal<Current<Contact.bAccountID>>>>),
SubstituteKey = typeof(Location.locationCD), ValidateValue = false)]
public virtual int? UsrLocationCD { get; set; }
public abstract class usrLocationCD : PX.Data.BQL.BqlInt.Field<usrLocationCD> { }
#endregion
}
I'm sharing one point here that newly created extension field is not creating any problem in the Contacts screen, successfully I'm able to saving the record you can see the below imgs.
Before saving the record
After saving the record
In the contacts screen location id field is "Int".
Where is the mistake and how to overcome this issue?
Your PXSelect is missing a Current<> on where you added in your usrLocationCD.
Original line with missing Current<>:
And<Where<ContactExt.usrLocationCD, Equal<Location.locationID>,
After adding the missing Current<> back in:
[PXViewName(Messages.Contacts)]
[PXFilterable]
[PXViewSavedDetailsButton(typeof(Location))]
public PXSelectJoin<Contact,
LeftJoin<Address, On<Address.addressID, Equal<Contact.defAddressID>>>,
Where<Contact.bAccountID, Equal<Current<Location.bAccountID>>,
And<Where<ContactExt.usrLocationCD, Equal<Current<Location.locationID>>,
And<Where<Contact.contactType, Equal<ContactTypesAttribute.person>,
Or<Contact.contactType, Equal<ContactTypesAttribute.lead>>>>>>>> Contacts;
When selecting data, you always must connect the referenced DAC's in some way... either by joining directly to another table selected in the join, by joining the field to a Current value (such as a field in a parent view), or by supplying a parameter that you pass in.
Also, for consistency, I'd recommend changing the name of your new field from usrLocationCD to usrLocationID. ID means "identifier" and CD means "code". LocationID (the identifier) is the integer field used to identify the Location record, in this case. LocationCD is the field of the Location record that contains the Location Code that we normally see in the display. When another Acumatica developer looks at the code above, the first impression is that you are trying to relate a string field to an integer field. Technically, as long as your field type matches on both sides of the equals then it will work, but consistency is important in coding standards.
In the above code, join is missed for location DAC. I hope this may help you.
[PXViewName(PX.Objects.CR.Messages.Contacts)]
[PXFilterable]
[PXViewSavedDetailsButton(typeof(Location))]
public PXSelectJoin<Contact,
LeftJoin<Address, On<Address.addressID, Equal<Contact.defAddressID>>,
LeftJoin<Location, On <Location.bAccountID,Equal<Contact.bAccountID>>>>,
Where<Contact.bAccountID, Equal<Current<Location.bAccountID>>,
And<Where<ContactExt.usrLocationCD, Equal<Location.locationID>,
And<Where<Contact.contactType, Equal<ContactTypesAttribute.person>,
Or<Contact.contactType, Equal<ContactTypesAttribute.lead>>>>>>>> Contacts;
I'm creating a new screen with one new table (AMClockItem) where the key field is the employee ID. I want it to default to the logged in user employee ID. If there isn't an AMClockItem record for the employee it will treat it as a new record, but if there is an existing record for the employee I want it to retrieve the existing record. This all works perfectly EXCEPT the very first time the screen is loaded. The logged in user defaults properly but it doesn't retrieve the existing record. If I click Cancel or change another field it will retrieve the record properly.
My Graph
public PXSelect<AMClockItem, Where<AMClockItem.employeeID, Equal<Optional<AMClockItem.employeeID>>>> header;
DAC:
public abstract class employeeID : PX.Data.BQL.BqlInt.Field<employeeID> { }
protected Int32? _EmployeeID;
[PXDBInt(IsKey = true)]
[ProductionEmployeeSelector]
[PXDefault(typeof(Search<EPEmployee.bAccountID,
Where<EPEmployee.userID, Equal<Current<AccessInfo.userID>>>>), PersistingCheck = PXPersistingCheck.Null)]
[PXUIField(DisplayName = "Employee ID")]
public virtual Int32? EmployeeID
{
get
{
return this._EmployeeID;
}
set
{
this._EmployeeID = value;
}
}
#endregion
On first load, it defaults in the correct logged in user, but the rest of the fields are blank, treating it as a new record.
I hit the cancel button and the existing record loads correctly.
I tried looking for a similar Acumatica screen but can't find an example where a key value is defaulted in on load. Is there a way to force the existing record to load the first time you visit the screen?
I'm not sure this is allowed, there's no mechanism that selects record like that to my knowledge as well.
I suspect the formulas do not execute in order too.
Make sure all key fields have proper value. Record can't be selected if one of the key fields resolve to null on load.
If some key fields initialization are dependent on other key fields initialization decorate them with the PXDependsOnFields attribute:
[PXDependsOnFields(typeof(employeeID))]
You can use the PageLoadBehavior property of "DataSource". Select "SearchSavedKeys". This will help.
I am trying to add a selector to a field on a DAC Extension (PMChangeOrder), and I need to get a value from the base record to put in a where statement on the PXSelector search.
The selector will give the user the ability to put in a new value, or select from the values that have been previously entered, based on the current Project ID. Do I use Current<>? Do I override cache attached? I cant seem to have the selector filter by the current value of projectID.
public abstract class usrPCONo : PX.Data.BQL.BqlInt.Field<usrPCONo> { }
[PXDBInt()]
[PXUIField(DisplayName = "PCO No.", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search4<usrPCONo, Where<PMChangeOrder.projectID, Equal<Current<PMChangeOrder.projectID>>>,
Aggregate<GroupBy<usrPCONo>>>), typeof(usrPCONo), typeof(PMChangeOrder.description), ValidateValue = false )]
public virtual int? UsrPCONo
{
get;
set;
}
Thanks
The code you provided in your question seems to work correctly. Make sure you have AutoRefresh set to true in the aspx file. This will make it so the records in the selector are automatically refreshed when you open the selector popup to reflect the current ProjectID that the user selected. Without this, if the user opened up the selector popup, changed the ProjectID, then reopened the selector popup the records would still reflect the old value unless the user manually pressed the refresh button in the popup. My guess is that this is what you are experiencing.
<px:PXSelector runat="server" ID="edUsrPCONo" DataField="UsrPCONo" AutoRefresh="True" CommitChanges="True" />
I have a customization to the Employee Timecard Entry screen (EP305000) which enables the Excel upload functionality into the Details tab grid. I did this by adding the attribute [PXImport(typeof(EPTimeCard))] to the 'Activities' view re-declaration in a TimeCardMaint BLC extension as follows:
[PXImport(typeof(EPTimeCard))]
[PXViewName(PX.Objects.EP.Messages.TimeCardDetail)]
public PXSelectJoin<EPTimecardDetail,
InnerJoin<CREmployee,
On<CREmployee.userID, Equal<EPTimecardDetail.ownerID>>,
LeftJoin<CRActivityLink,
On<CRActivityLink.noteID, Equal<EPTimecardDetail.refNoteID>>,
LeftJoin<CRCase,
On<CRCase.noteID, Equal<CRActivityLink.refNoteID>>,
LeftJoin<PX.Objects.AR.Customer,
On<PX.Objects.AR.Customer.bAccountID, Equal<CRCase.customerID>>,
LeftJoin<PX.Objects.EP.TimeCardMaint.ContractEx,
On<PX.Objects.EP.TimeCardMaint.ContractEx.contractID, Equal<CRCase.contractID>>,
LeftJoin<PMProject,
On<PMProject.contractID, Equal<EPTimecardDetail.projectID>>>>>>>>,
Where<CREmployee.bAccountID, Equal<Current<EPTimeCard.employeeID>>,
And<EPTimecardDetail.weekID, Equal<Current<EPTimeCard.weekId>>,
And<EPTimecardDetail.trackTime, Equal<True>,
And<EPTimecardDetail.approvalStatus, NotEqual<ActivityStatusListAttribute.canceled>,
And<Where<EPTimecardDetail.timeCardCD, IsNull, Or<EPTimecardDetail.timeCardCD, Equal<Current<EPTimeCard.timeCardCD>>>>>>>>>,
OrderBy<Asc<EPTimecardDetail.date>>> Activities;
I also set the 'AllowImport' property of the grid to 'True'. This seems to work ok, except that the 'ProjectTask' field of the upload does not allow mapping - i.e., if you go through the import process, when you get to the field mapping part, you can't map the Excel field for ProjectTask to the grid's ProjectTask. It just doesn't show up.
Would this be because the source BLC has as delegate method for 'activities' that I didn't reproduce in my extension?
What could be the reason for not allowing mapping to the ProjectTask field?
Since the ProjectTask field is disabled by default, this was solved by adding a parameter to the [ProjectTask] attribute, called "AlwaysEnabled" via the CacheAttached event, as shown below:
public class TimeCardMaint_Extension : PXGraphExtension<TimeCardMaint>
{
[PXDefault(typeof(Search<PMTask.taskID, Where<PMTask.projectID, Equal<Current<TimeCardMaint.EPTimecardDetail.projectID>>, And<PMTask.isDefault, Equal<True>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
[ProjectTask(typeof(TimeCardMaint.EPTimecardDetail.projectID),
BatchModule.TA,
DisplayName = "Project Task",
BqlField = typeof(PMTimeActivity.projectTaskID),
AlwaysEnabled = true)]
protected virtual void EPTimecardDetail_ProjectTaskID_CacheAttached(PXCache cache)
{
}
I've noticed that whenever an AR Invoice gets saved, a record gets created in the Note table with the new invoice's note ID. Can you tell me how that is being accomplished? I'd like to get one of my screens to do the same thing. I guess there must be some kind of attribute on the either the DAC or the graph but I can't find it. I have the PXNote attribute on the NoteID column in my DAC but it does not cause a Note record to be automatically created.
Thanks for your help.
To have Note record automatically created when a new parent record gets saved, one should invoke the static PXNoteAttribute.GetNoteID<Field>(PXCache cache, object data) method when the parent record is inserted in the cache.
For example, to have Note record automatically created when a new Stock Item gets saved, you should subscribe to RowInserted handler for the InventoryItem DAC and call PXNoteAttribute.GetNoteID<Field>(...):
public class InventoryItemMaintExt : PXGraphExtension<InventoryItemMaint>
{
public void InventoryItem_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
var noteCache = Base.Caches[typeof(Note)];
var oldDirty = noteCache.IsDirty;
PXNoteAttribute.GetNoteID<InventoryItem.noteID>(sender, e.Row);
noteCache.IsDirty = oldDirty;
}
}
The code snippet above can be incorporated into almost any custom BLC with a couple simple changes to replace InventoryItem with a custom DAC.