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.
Related
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.
I wanted to add an extension in backoffice, so that it is possible for non-programming people to add new objects (of defined types) to the database.
I've almost done it:
I defined two items: offer and tile (their relation is one to many)
What i achieved is there is a possibility to add a new offer in the backoffice.
When you add it, and click to edit, you can also add a tile to this offer - either form drop-down list (if any tiles exist) or create a new tile, which will automatically be added to its table and realted to edited offer.
However, the representation of the drop-down list is unacceptable, see below:
screenshot from backoffice
as you can see, the identifier of an existing tile (within []) is its PK - which clearly is not a good identifier. I would like to inject there instead a value form one of tile's other attributes (which also is unique) so that someone could easily identify which tile to add.
Where is the mechanism responsible for it? How to override it. I tried to override toString method in the tile class, unfortunately to no avail
You need to customize the backoffice-config.xml for your custom Model. For your Tile model, you can use something like:
<context merge-by="type" type="Tile" component="base">
<y:base xmlns:y="http://www.hybris.com/cockpit/config/hybris">
<y:labels>
<y:label>nameOfTile</y:label>
</y:labels>
</y:base>
</context>
I noticed that graph.Caches[typeof(MyDac)] is quite useful in Acumatica to manipulate values in other DACs. What would be the proper way to use it, for example when I update a value in another DAC? Do I have to persist right after it, or will it be saved to DB when I run graph.Action.PressSave(), even if I am not using this DAC in any of the view in the graph?
The PXGraph.Caches collections contains DAC objects loaded in memory on the server. In a graph it is accessed directly as this.Caches and in an extension it is accessed through Base.Caches. While not technically acurate it can be thought of as a global DAC cache. The DAC objects contained in DataView.Cache is a subset of the DAC objects in PXGraph.Caches.
The usual pattern for persisting records is by using graph DataViews. The PXGraph.Action.PressSave() will persist the records when the current record of the primary DataView of the graph is properly set.
The primary DataView of the graph is declared in the ASPX PrimaryView property of the PXDataSource element:
<px:PXDataSource ID="ds" runat="server" PrimaryView="Document" TypeName="PX.Objects.SO.SOOrderEntry" >
Setting PrimaryView.Current record in the BLC graph is required for the Save action to persist the DataViews records.
It is also possible to persist DAC objects in DataViews without invoking the Save action. To do so you would perform a CRUD operation and then Persist the DAC objects in the DataView using:
DataView.Insert(DAC)
DataView.Update(DAC)
DataView.Delete(DAC)
DataView.Cache.Persist(PXDBOperation.Insert)
DataView.Cache.Persist(PXDBOperation.Update)
DataView.Cache.Persist(PXDBOperation.Delete)
While it is possible to do the same operations on PXGraph.Caches there are few situation where this is required in user code because using DataView is the preferred method of persisting DAC objects and access to DataViews is available when you have the BLC.
Where PXGraph.Caches is especially useful is when working with PXGraph instead of a BLC, often found in the context of generic code. You can access DataViews of the BLC like SOOrderEntry.Document with a reference pointing to the SOOrderEntry BLC. However if all you got is a reference to the PXGraph base class of the BLC you don't have access to the DataViews. In that case you can still access the DAC objects in PXGraph.Caches. By knowing the type of the DataView DAC objects for example SOOrderEntry.Document is of SOOrder type and will be in PXGraph.Caches[typeof(SOOrder)]. For user code this pattern is more common in custom attributes that have access to the PXGraph object but not the BLC. In BLC it's more common to work on the DataView.Cache instead of PXGraph.Cache.
Another possible scenario where accessing PXGraph.Caches could be useful is when you have many DataViews of the same type. If you want to query all updated DAC objects of a same type that are in multiple DataViews you can itereate on Caches[typeof(DAC)].Updated. It's also quite common to simply fetch a reference to a Cache object using Caches[typeof(DAC)] that will then be passed to another Acumatica framework method by input parameter. In this case it's often a matter of convenience because the same Cache reference could be obtain through DataView.Cache.
Newbie to Acumatica here. I've performed a small amount of customization to our system, and am now diving into adding custom data fields.
My goal is to synchronize hardware shipment information from Acumatica into our legacy (outdated and proprietary) hardware management system, as we will need to continue using this system for the time being for warranty calculations. I plan to eventually build this into Acumatica.
My current issue is that I need a method of associating Customer Locations to the customer locations in our legacy system. Adding the field DCL_ID was easy enough to accomplish following the To Add a Custom Data Field documentation. I made the column be required by setting
[PXDefault]
[PXUIField(DisplayName="DCL Account ID", Required = true)]
to the attributes section of the Data Access class as outlined here. I then added the field to my form using the Layout Editor.
At this point all seemed well. The field shows an asterisk in the UI and also validates that a value is provided. Then I realized that Customer Locations is not the only place that uses CR.Location -- it is also used by Account Locations. Doing some digging I've found that Account Locations can include many more account types than Customer Locations. I only need this attribute to be required for Customer Locations. Thus, I have opted to use the To Make a Field Mandatory on the Graph Level.
Here is my CustomerLocationMaint code:
using System;
using PX.Data;
using PX.Objects.CR;
using System.Collections.Generic;
using PX.Objects;
using PX.Objects.AR;
namespace PX.Objects.AR
{
public class CustomerLocationMaint_Extension : PXGraphExtension<CustomerLocationMaint>
{
#region Event Handlers
[PXDefault]
[PXCustomizeBaseAttribute(typeof(PXUIFieldAttribute), "Required", true)]
protected virtual void SelectedCustomerLocation_UsrDCL_ID_CacheAttached(PXCache cache)
{
}
#endregion
}
}
After I save and publish the customization, the field does not function as a required field, as it did when I defined the requirements at the DAC level.
So, what have I done wrong? I've read and re-read the documentation multiple times, but cannot find my mistake.
Setup:
My thought is the underscore in the field name causing the cache attached to not properly register the graph level attribute change. Using a field name without the underscore is the preferred naming convention for tables and columns.
The Acumatica documentation mentions this should be avoided as listed here:
Database Design Guidelines
Found under Table and Column Naming Conventions:
Do not use the underscore symbol (_) in table or column names, because
it is a reserved symbol in Acumatica Framework. For example,
CompanyType is a valid column name, while Company_Type is invalid.
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