SumCalc attribute not working when trying to summarize usr Field from PMTask to PMProject - acumatica

First, created a custom field in the PM.PMTask DAC called usrNumberofPanel
Second, created a custom field in the PM.PMProject DAC usrTotalPanels.
Want each of the lines from task to update the total number of panels on the project, so modified the attribute for PM.PMTask.userNumberofPanel and added a PXFormula as shown below to add the SumCalc.
[PXDBDecimal]
[PXUIField(DisplayName="Number of Panels")]
[PXFormula(null, typeof(SumCalc<PX.Objects.CT.ContractExt.usrTotalPanels>))]
Made sure the attributes for the Total Panel and set as follows to make sure no one types into the field.
[PXDBDecimal]
[PXUIField(DisplayName="Total Panels", Enabled = false)]
Any thoughts would be appreciated.

It's a known issue that SumCalc doesn't work properly across DACs that are linked with PXParent relationships.
I can only recommend to use a RowSelected or FieldSelecting graph event handlers to compute the sum instead of a solution involving DAC attributes. You can add a comment explaining the limitation of DAC attributes in the event handler if you are seeking Acumatica ISV Certification for your solution.

Related

Pull Attributes from Stock Item to SO Line custom field

I'm relatively new to customization programming in Acumatica and I have a question about the best way to pull in attribute values from the stock item screen to a custom field on the SO Line in the sales order screen.
I have done something similar on another screen using a FieldSelecting event and a PXSelect statement to pull data from another screen and update my custom field.
Needing to pull the values from the attribute value is what's stumping me, should I just join to the CSAnswers table in the pxselect?
I also wanted to ask if there is a better overall approach for pulling data from another screen into a custom field in an Acumatica customization.
*update *
I'm attempting to use the PXDBScalar attribute, but I cannot figure out how to join multiple tables. Here's what I've tried.
[PXDBScalar(typeof(
Search2<CSAnswers.value,
InnerJoin<InventoryItem,
On<SOLine.inventoryID, Equal<InventoryItem.inventoryID>>>,
InnerJoin<CSAnswers,
On<InventoryItem.noteID, Equal<CSAnswers.refNoteID>>>,
Where<CSAnswers.attributeID, Like<QHOLDAttr>>
>))]
Thanks
Scott
Since you asked for "a better overall approach" then I'll share my preferred way of handling this. Not to say it is "better" but perhaps just "different".
I try to keep my data tied to the object where it is related directly. In the case of an attribute of an InventoryItem, I would elevate that attribute value to InventoryItem in a DAC extension so that it can be leveraged anywhere the InventoryItem is used. You seem to want to use it in conjunction with the SOLine record, but since the attribute is not tied to the SOLine, I would not extend SOLine to add it. There is nothing wrong with adding it there if your business requirement mandates it, but it keeps me more sane to know that an InventoryItem's related data comes from InventoryItem rather than trying to remember where I put it and possibly duplicate the effort elsewhere (like on a POLine) later.
Here is an example of how I've done it, pulled straight from my project but changing the Attribute references to be more generic.
public sealed class InventoryItemExt : PXCacheExtension<PX.Objects.IN.InventoryItem>
{
#region MyAttribute
[PXString]
[PXUIField(DisplayName = Messages.MyAttribDisplayName)]
[PXDBScalar(typeof(Search<CSAnswers.value,
Where<CSAnswers.refNoteID, Equal<InventoryItem.noteID>,
And<CSAnswers.attributeID, Equal<MyAttribute>>>>))]
public string MyAttribute { get; set; }
public abstract class myAttribute : PX.Data.BQL.BqlString.Field<myAttribute> { }
#endregion
public class MyAttribute : PX.Data.BQL.BqlString.Constant<MyAttribute>
{
public MyAttribute() : base("MYATTRIB") { }
}
}
Notice the constant defined to access the AttributeID "MYATTRIB" which is attached to the Item Class of the InventoryItem record.
Now that the attribute is pulled into the DAC extension on InventoryItem, I can use it on any screen related to an InventoryItem with ease as long as InventoryItem (and the associated DAC extension) have been made available to that screen.
Without testing, I may be off on this but with regards to your attempt to join 2 tables in the PXDBScalar...
When you say Search2<CSAnswers.value..., you have indicated that you want to search the CSAnswers DAC and retrieve the value field. By subsequently trying to InnerJoin back to CSAnswers, I believe you effectively have said:
Select CSAnswers.Value From CSAnswers
Inner Join InventoryItem On SOLine.InventoryID = InventoryItem.InventoryID
Inner Join CSAnswers...
I'm not sure if the SOLine reference is valid here, but it may be if you are defining this directly in the SOLine DAC extension. However, you have tried to query CSAnswers Inner Join CSAnswers. Not sure if this will fix your PXDBScalar, but if you really want to use your method to attach this to SOLine, try:
Search2<CSAnswers.value,
InnerJoin<InventoryItem,
On<InventoryItem.inventoryID, Equal<SOLine.inventoryID>>>,
Where<InventoryItem.noteID, Equal<CSAnswers.refNoteID>,
And<CSAnswers.attributeID, Equal<QHOLDAttr>>>
>))]
(Notice that I swapped the order of the relations in On clauses.)

Is it possible to create my own custom KvExt table to fully implement and manage User Defined Fields for my custom table and page?

I have a custom table in SQL Server called AnimalBreed and maintenance page.
I wish to add User Defined Field support via the KvExt approach instead of
traditional practices involving either CSAnswers or a CacheExtension of the
DAC and underlying "Usr" fields.
Is this possible?
Can it be done for line-level (child) DACs, such as
existing INLocation and INLocationKvExt?
Thanks!
UPDATE:
It appears the feature needs at least:
ensure your table has the NoteID column as uniqueidentifier datatype and the DAC has the corresponding field: Guid? NoteID and [PXNote()] attribute.
In the ASPX, if not ListView, add the following to the PXDataSource tag:
EnableAttributes="true"
By making these changes, I can Manage User Defined Fields, choose Attributes to include, and I can store values to the KvExt table.
I am using Version = 19.205.0023
Sales Order page observation: if I add two UDFs on SO Order Entry page, one is combobox and one is checkbox, setting their values saves just fine, but then updating the combobox and save leads to loss of the checkbox (from true to false), unless you uncheck and recheck prior to the save. Is this a bug?
Maybe technically possible but definitely not recommended to use undocumented feature like KvExt.
If you need to deploy User Defined Fields on a page which already contains them. Configure them manually and then add them in a customization package in the user defined fields section for deployment as described here:
https://help-2019r2.acumatica.com/Help?ScreenId=ShowWiki&pageid=e01f29d3-b6b1-40f4-a2d1-45c9d01bdde3
Example:

Graph CacheAttached method

I want to make the SOLine Qty field to 1.0 by default, so I have changed at DAC level, by doing this it will be applied to the entire application?
Next, I can do same by writing Graph CacheAttached method also, I think this will apply only to that particular graph and if the same field is used in another graph or a custom new screen this will not affect in that graph.
Please suggest.
You are correct, adding an attribute to SOLine DAC extension will apply this attribute system wide. To limit its scope to a graph, use a CacheAttached.
Here are good reads on this subject :
DAC : https://help.acumatica.com/(W(12))/Wiki/ShowWiki.aspx?pageid=b3d24079-bda4-4f82-9fbd-c444a8bcb733
Append and replace of dacs attributes : http://asiablog.acumatica.com/2017/01/append-and-replace-of-dacs-attributes.html
These concepts are well explained in the T200 certification, which I suggest you do if you haven't already.

Acumatica Pass custom field vales into Cash Transaction detail table

I have added two custom fields in the Screens: Payment and Application(AR302000), Cash Transactions(CA304000), Funds Transfers(301000) and Back Deposits(305000), and I pretend to add those fields also in the Table CATran
I have a Generic Inquiry that mimic the Report Cash Account Detail (CA633500) where I can see that the Field ExtReference and Description are copied from the Original Ducument (AR302000,CA304000,etc) to the CATran records.
If I would like to pass the value of my custom field to the CATran Table, to get the same behavior that the External Reference and Description does.
Does anybody know what is the action'name to override the Insertion of CATran Detail?
Form AR302000 uses following class: PX.Objects.AP.APPaymentEntry. It means that you should create extension for this class in way similar to this:
public class APPaymentEntryExt : PXGraphExtension<APPaymentEntryExt>
{
}
Then you can use extending with help of CATran_RowInserting for initial values configuration and CATran_RowInserted for modification of inserted values

Acumatica Requisition Total Cost Custom Calculation

I've added three custom decimal? field on Requisition master (RQ302000) and need to prorate the total value of those three fields to the each Requisition line using line base total cost/master total cost ratio and displayed the result as Additional Cost (also custom decimal? field) of each line.
This calculation should be triggered when those three new field are updated.
What I don't understand are:
1. What events should be modify related to this needs
2. If it is event on master field, how to get value from line extension field
3. If it is event on line field, how to get value from master extension field
Requisition Custom Screen
1. "What events should be modify related to this needs?"
In a scenario, like yours, one should use combination of RowInserted, RowUpdated and RowDeleted handlers:
The RowInserted event handler is used to implement the business logic for:
Inserting the detail data records in a one-to-many relationship.
Updating the master data record in a many-to-one relationship.
Inserting or updating the related data record in a one-to-one relationship.
The RowUpdated event handler is used to implement the business logic of:
Updating the master data record in a many-to-one relationship.
Inserting or updating the detail data records in a one-to-many relationship.
Updating the related data record in a one-to-one relationship.
The RowDeleted event handler is used to implement the business logic of:
Deleting the detail data records in a one-to-many relationship.
Updating the master data record in a many-to-one relationship.
Deleting or updating the related data record in a one-to-one relationship.
Also FieldUpdated handlers be considered for your scenario:
The FieldUpdated event handler is used to implement the business logic associated with changes to the value of the DAC field in the following cases:
Assigning the related fields of the data record containing the modified field their default values or updating them
Updating any of the following:
The detail data records in a one-to-many relationship
The related data records in a one-to-one relationship
The master data records in a many-to-one relationship
Refer to API Reference in Help -> Acumatica Framework -> API Reference -> Event Model and T200 developer class for additional information and examples on Acumatica Framework event model.
2. "If it is event on master field, how to get value from line extension field?"
In Acumatica custom fields are declared via DAC extensions. To access the DAC extension object, you can use the following methods:
The GetExtension() generic method available for each DAC instance:
ContactExt contactExt = curLead.GetExtension<ContactExt>();
The GetExtension(object) generic method declared within the non-generic PXCache class
ContactExt contactExt = Base.LeadCurrent.Cache.GetExtension<ContactExt>(curLead);
or
ContactExt contactExt = Base.Caches[typeof(Contact)].GetExtension<ContactExt>(curLead);
The GetExtension(object) static generic method of the PXCache generic class
ContactExt contactExt = PXCache<Contact>.GetExtension<ContactExt>(curLead);
To get value from line extension field, you should first select records from the Lines data view, then use one of the methods described above to access instance of DAC extension class, for instance:
foreach(RQRequisitionLine line in Base.Lines.Select())
{
RQRequisitionLineExt lineExt = line.GetExtension<RQRequisitionLineExt>();
}
3. "If it is event on line field, how to get value from master extension field"
That's an easy one: same 3 approaches described above, this time applied to Current property of the primary Document data view, for instance:
Base.Document.Current.GetExtension<RQRequisitionExt>();

Resources