add field on vendor screen - acumatica

when I add a new field, in the payment configuration tab.
It adds the field in location to the database, but at the same time I create DAC addressExt, I don't understand why.
here is the DAC of each one that created me.
First.
the field is created in this table: Location
namespace PX.Objects.CR.Standalone
{
public class LocationExt : PXCacheExtension<PX.Objects.CR.Standalone.Location>
{
#region UsrTest
[PXDBBool]
[PXUIField(DisplayName="test")]
public virtual bool? UsrTest { get; set; }
public abstract class usrTest : PX.Data.BQL.BqlBool.Field<usrTest> { }
#endregion
}
}
second.
namespace PX.Objects.CR
{
public class AddressExt : PXCacheExtension<PX.Objects.CR.Address>
{
#region UsrTest
[PXDBBool]
[PXUIField(DisplayName = "test")]
public virtual bool? UsrTest { get; set; }
public abstract class usrTest : PX.Data.BQL.BqlBool.Field<usrTest> { }
#endregion
}
}
view image:
I hope you understand, I'm not good at English.

This is actually being done by design. The DAC you are editing is a Projection consisting of multiple DACs. Check this link out from Sergey Marenich
PXProjection uses 2 Data Access Classes for quotes:
One class represents the table – PX.Objects.CR.Standalone.CRQuote.
Another represents view as combination of DACs in select – PX.Objects.CR.CRQuote.
And to correctly work, custom field needs to be added in both of the places. And Projection field should be linked to table field using BqlField property of DBFieldAttributes.

Related

How to add a AutoGenerate riwnumber as Key column in PXProjection?

I want to add a AutoGenerate number column in PXProjection DAC?
What i want,
In PXProjection DAC, I wan to add a Field, which should generate a unique number for each row, It might be unique with the combinaion of Fields consider in Projection, How may i do it?
Since I'm not sure how well you understand projections, let me cover some basics as I understand them first. A PXProjection is the xRP Framework equivalent of a SQL view. It does not contain any actual database tables or fields but simply creates access to a "view" into the data. As such, it does not have the ability to have a sequence, or identity, field of its own. It does, however, require that you define the key field(s). Once defined, you would retrieve the records of the projection as if it was its own table using reference to all of those key fields.
Here is a sample (not all fields) of one of my projections.
[PXProjection(typeof(
SelectFrom<INTran>
.LeftJoin<INLocation>
.On<INLocation.locationID.IsEqual<INTran.locationID>>
.LeftJoin<SOShipLine>
.On<SOShipLine.shipmentNbr.IsEqual<INTran.sOShipmentNbr>
.And<SOShipLine.lineNbr.IsEqual<INTran.sOShipmentLineNbr>>>
.LeftJoin<SOLine>
.On<SOLine.orderNbr.IsEqual<SOShipLine.origOrderNbr>
.And<SOLine.orderType.IsEqual<SOShipLine.origOrderType>
.And<SOLine.lineNbr.IsEqual<SOShipLine.origLineNbr>>>>
.LeftJoin<SOOrder>
.On<SOOrder.orderNbr.IsEqual<SOShipLine.origOrderNbr>
.And<SOOrder.orderType.IsEqual<SOShipLine.origOrderType>>>
.LeftJoin<ContactBAccount>
.On<ContactBAccount.bAccountID.IsEqual<SOOrder.billContactID>>
.LeftJoin<POReceiptLine>
.On<POReceiptLine.receiptNbr.IsEqual<INTran.pOReceiptNbr>
.And<POReceiptLine.lineNbr.IsEqual<INTran.pOReceiptLineNbr>>>
.LeftJoin<POOrder>
.On<POOrder.orderNbr.IsEqual<POReceiptLine.pONbr>
.And<POOrder.orderType.IsEqual<POReceiptLine.pOType>>>
))]
[Serializable]
[PXCacheName("Transactions Projection")]
public partial class MYINTransactions : IBqlTable
{
#region DocType
public abstract class docType : PX.Data.BQL.BqlString.Field<docType> { }
[PXDBString(1, IsFixed = true, IsKey = true, BqlField = typeof(INTran.docType))]
[PXUIField(DisplayName = INRegister.docType.DisplayName)]
public virtual String DocType { get; set; }
#endregion
#region TranType
public abstract class tranType : PX.Data.BQL.BqlString.Field<tranType> { }
[PXDBString(3, IsFixed = true, BqlField = typeof(INTran.tranType))]
[INTranType.List()]
[PXUIField(DisplayName = "Tran. Type")]
public virtual String TranType { get; set; }
#endregion
#region RefNbr
public abstract class refNbr : PX.Data.BQL.BqlString.Field<refNbr> { }
[PXDBString(15, IsUnicode = true, IsKey = true, BqlField = typeof(INTran.refNbr))]
[PXUIField(DisplayName = INRegister.refNbr.DisplayName)]
public virtual String RefNbr { get; set; }
#endregion
#region LineNbr
public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
[PXDBInt(IsKey = true, BqlField = typeof(INTran.lineNbr))]
[PXUIField(DisplayName = "Line Number")]
public virtual Int32? LineNbr { get; set; }
#endregion
#region TranDate
public abstract class tranDate : PX.Data.BQL.BqlDateTime.Field<tranDate> { }
[PXDBDate(BqlField = typeof(INTran.tranDate))]
public virtual DateTime? TranDate { get; set; }
#endregion
#region InvtMult
public abstract class invtMult : PX.Data.BQL.BqlShort.Field<invtMult> { }
[PXDBShort(BqlField = typeof(INTran.invtMult))]
[PXUIField(DisplayName = "Multiplier")]
public virtual Int16? InvtMult { get; set; }
#endregion
#region BranchID
public abstract class branchID : PX.Data.BQL.BqlInt.Field<branchID> { }
[Branch(typeof(INTran.branchID), BqlField = typeof(INTran.branchID))]
public virtual Int32? BranchID { get; set; }
#endregion
#region InventoryID
public abstract class inventoryID : PX.Data.BQL.BqlInt.Field<inventoryID> { }
[PXDBInt(BqlField = typeof(INTran.inventoryID))]
public virtual Int32? InventoryID { get; set; }
#endregion
#region SubItemID
public abstract class subItemID : PX.Data.BQL.BqlInt.Field<subItemID> { }
[PXDBInt(BqlField = typeof(INTran.subItemID))]
public virtual Int32? SubItemID { get; set; }
#endregion
}
As you can see, it pulls data from many tables and then defines fields to be accessed via MYINTransactions and includes IsKey on the key fields and "BqlField =" to map to the related fields. Even though we use PXDB for the field attributes, these are not actual DB fields themselves. The PXProjectionAttribute overrides the behavior of the fields. I believe it is possible to set properties that will enable the projection to maintain data, at which point, the PXDB type attributes should convey the applicability to the database when the SQL commands are built from BQL. That's more advanced than I have had time to explore myself, so I won't go into any further detail there.
Now, more specifically to your question directly... Depending on how you intend to use the projection, you might define additional fields using PXDBScalar or PXFormula to populate the values, but in my attempts, this had unreliable results. The issue for me was that I needed the values at the time of the actual SQL call, and the fields, being unbound, did not exist at the database level. They would work on my screen, but some of my more complex BQL statements would fail because the values at the time of the SQL call were null due to being unbound.
The best recommendation that I can make is that you use a database field in one of the base DAC's to produce the desired field and map a field in your projection to that field. This will produce the most reliable results, should you try to use the projection in complex ways. Alternatively, if this is for use in a GI, you can use a formula in the GI's field definition to concatenate fields, if that is your goal.

How to work with Extension Table with projection INKitAssembly projection class?

Below is extension DAC and Graph code, INRegisterKitAssemblyExt is a DAC, i have created a database table for that. i want to save usrSiteID value in INRegisterKitAssemblyExt(separate) database table. Please check how may i initialize extension DAC with INKitRegister DAC and save the value and how to use usrSiteId in UI?
[PXTable(typeof(INKitRegister.refNbr), typeof(INKitRegister.KitRevisionId))]
public class INRegisterKitAssemblyExt: PXCacheExtension<INKitRegister> {
#region RefNbr
public abstract class refNbr:PX.Data.BQL.BqlString.Field<refNbr> {
}
protected String _RefNbr;
[PXDBDefault(typeof(INKitRegister.refNbr))]
[PXDBString()]
[PXParent(typeof(Select<INKitRegister, Where<INKitRegister.refNbr, Equal<Current<refNbr>>,And<INKitRegister.kitRevisionID, Equal<Current<kitRevisionID>>>>>))]
public virtual String RefNbr {
get {
return this._RefNbr;
}
set {
this._RefNbr = value;
}
}
#endregion
#region KitRevisionID
public abstract class kitRevisionID:PX.Data.BQL.BqlString.Field<kitRevisionID> {
}
protected String _KitRevisionID;
[PXDBDefault(typeof(INKitRegister.kitRevisionID))]
[PXDBString()]
public virtual String KitRevisionID {
get {
return this._KitRevisionID;
}
set {
this._KitRevisionID = value;
}
}
#endregion
// My Fields as well as refNbr and KitRevison is also here
public virtual int? UsrQCSiteID {
get; set;
}
public abstract class usrQCSiteID:PX.Data.BQL.BqlInt.Field<usrQCSiteID> {
}
}
// Extension Graph
public class KitAssemblyEntryExt:PXGraphExtension<KitAssemblyEntry> {
}
INRegisterKitAssemblyExt in your code example is not a DAC.
DAC inherits from the IBqlTable base class.
INRegisterKitAssemblyExt in your code example is a DAC extension.
DAC extensions inherits from the PXCacheExtension base class.
You should never create database table for DAC extensions.
Custom fields in DAC extension will be persisted to the base DAC table automatically.
The main issue here is that INKitRegister is not DAC bound to a database table.
It's a Projection DAC and the INKitRegister database table does not exist.
The INKitRegister DAC projection points to the INRegister DAC:
[PXPrimaryGraph(typeof(KitAssemblyEntry))]
[PXCacheName(Messages.INKit)]
[PXProjection(typeof(Select2<INRegister, InnerJoin<INTran, On<INRegister.FK.KitTran>>>), Persistent=true)]
[Serializable]
public partial class INKitRegister : IBqlTable, ILSPrimary
You should create an extension on the INRegister DAC instead of INKitRegister because INRegister is bounded to an actual database table of the same name:
public class INRegisterKitAssemblyExt: PXCacheExtension<INRegister>

Custom fields are not showing updated value when update in field updated event, Why?

I have added custom fields in customization form using the customization form, steps i have added:
1) Go to shipment form and select Transaction Grid.
2) Select Add fields.
3) Select custome and Add 4 fields and save and publish.
4) Add all 4 fields and select used and save.
5) and publish again and all 4 columns are visible.
6) I have added a user fields name Aloow (PXDBBool), UsrPClocation(Location) and UsrPCwarehouse(Site),
and i set the below attribute in warehour and location.
7) But on SOSHipLine_InventotyID_FieldUpdate event, i am setting Allow, location, warehouse all 3 values, but values are not showing in Grid, what is the resoon?
#region UsrQCSiteID
[PXUIField(DisplayName = "PC Warehouse")]
[SiteAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID))]
[PXUIRequired(typeof(Where<usrAllow, Equal<True>>))]
[PXUIEnabled(typeof(Where<usrAllow, Equal<True>>))]
[PXDefault()]
public virtual int? UsrPCSiteID {
get; set;
}
public abstract class usrPCSiteID:PX.Data.BQL.BqlInt.Field<usrPCSiteID> {
}
#endregion UsrPCSiteID
#region UsrPCLocationID
[PXUIField(DisplayName = "PC Location")]
[SOLocationAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID), typeof(SOShipLineExt.usrPCSiteID), typeof(SOLine.tranType), typeof(SOShipLine.invtMult))]
[PXUIRequired(typeof(Where<usrQCRequired, Equal<True>>))]
[PXUIEnabled(typeof(Where<usrQCRequired, Equal<True>>))]
[PXDefault()]
public virtual int? UsrPCLocationID {
get; set;
}
public abstract class usrPCLocationID:PX.Data.BQL.BqlInt.Field<usrPCLocationID> {
}
#endregion UsrPCLocationID
#region Allow
[PXDBBool]
[PXUIField(DisplayName = "Allow")]
public virtual bool? UsrAllow {
get; set;
}
public abstract class usrAllow:PX.Data.BQL.BqlBool.Field<usrAllow> {
}
#endregion
IS SOShipLine allow updating custom values?
The steps that you described look correct.
I recreated this scenario locally:
1 - My DAC extension looks as follows:
public class SOShipLineExt : PXCacheExtension<PX.Objects.SO.SOShipLine>
{
#region UsrPCSiteID
[PXUIField(DisplayName = "PC Warehouse")]
[SiteAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID))]
public virtual int? UsrPCSiteID {
get; set;
}
public abstract class usrPCSiteID:PX.Data.BQL.BqlInt.Field<usrPCSiteID> {
}
#endregion UsrPCSiteID
#region UsrPCLocationID
[PXUIField(DisplayName = "PC Location")]
[SOLocationAvail(typeof(SOShipLine.inventoryID), typeof(SOShipLine.subItemID), typeof(SOShipLineExt.usrPCSiteID), typeof(SOShipLine.tranType), typeof(SOShipLine.invtMult))]
public virtual int? UsrPCLocationID {
get; set;
}
public abstract class usrPCLocationID:PX.Data.BQL.BqlInt.Field<usrPCLocationID> {
}
#endregion UsrPCLocationID
#region Allow
[PXDBBool]
[PXUIField(DisplayName = "Allow")]
public virtual bool? UsrAllow {
get; set;
}
public abstract class usrAllow:PX.Data.BQL.BqlBool.Field<usrAllow> {
}
#endregion
}
Notes about the DAC Extension:
I removed references to PXUIEnabled and PXUIRequired. If you are looking to disable the Site and the Location based on the checkbox's value, I recommend you manage this logic in the RowSelected event. (it may be feasible with your approach but I have not used it before)
The PXDefault references were also removed, given that in most cases the Shipment is created directly from the Sales Order page. As you have it right now, the field is mandatory but no default value is being assigned which will cause an error. You have 2 options: 1) indicate the value in the PXDefault() attribute, or 2) Set the property PXPersistingCheck.Nothing.
Note that your SOLocationAvail attribute has an error in the 4th parameter. You should use typeof(SOShipLine.tranType) instead of typeof(SOLine.tranType). This was generating an error when the shipment was created from the SO.
2 - My FieldUpdated event looks as follows:
public class SOShipmentEntry_Extension : PXGraphExtension<SOShipmentEntry>
{
protected virtual void SOShipLine_InventoryID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
if (e.Row == null) return;
SOShipLine line = (SOShipLine)e.Row;
SOShipLineExt lineExt = cache.GetExtension<SOShipLineExt>(line);
if (lineExt != null)
{
lineExt.UsrAllow = true;
lineExt.UsrPCSiteID=154;
lineExt.UsrPCLocationID=155;
}
}
}
Notes about the Graph extension:
I hard-coded the Warehouse and Location values. I recommend you do the same on your end while testing is being done, just make sure that the IDs exist in your DB, or that you query the CD value and then use its corresponding ID value.
Results:
When the Shipment is created from a SO, the values are being correctly assigned:

how to add a field on the Project Quotes screen PQ000025

Good morning, I want to add a new field on this screen Project Quotes but in doing so I get this message, that the table does not exist.
How should or what is the way to achieve it.
Thanks in advance
Imagen 01
The added field in the database
enter image description here
He added the field in the database and then I generated my extension.
namespace PX.Objects.CR
{
public class PMQuoteExt : PXCacheExtension<PX.Objects.CR.CRQuote>
{
#region UsrNota
[PXDBString(-1, InputMask = "", BqlField = typeof(PMQuoteStandaloneExt.usrNotaText))]
[PXUIField(DisplayName = "Nota ")]
public virtual string UsrNotaText { get; set; }
public abstract class usrNotaText : IBqlField { }
#endregion
}
public class PMQuoteStandaloneExt : PXCacheExtension<PX.Objects.CR.Standalone.CRQuote>
{
#region UsrNota
[PXDBString(-1, InputMask = "")]
[PXUIField(DisplayName = "Nota ")]
public virtual string UsrNotaText { get; set; }
public abstract class usrNotaText : IBqlField { }
#endregion
}
}
public class PMQuoteMaint_Extension : PXGraphExtension<PMQuoteMaint>
{
public PXSelect<PX.Objects.CR.Standalone.CRQuote> Test;
}
However, when I record, it does not fill the field.
that I am making a mistake or doing wrong.
Can you tell me please.
Thank you
PMQuote is not an actual DB table, but a BQL projection between tables:
CR.Standalone.CRQuote
CROpportunityRevision
CR.Standalone.CROpportunity
The way that I would tackle this is:
Add the field in table CRQuote
Extend the graph and override the Projection with the inclusion of the new CRQuote field.
UPDATE:
Based on #HB_Acumatica suggestion, step 2 would get simplified to a DAC extension (no need for the Graph extension). Much simpler to maintain in subsequent Acumatica versions!
UPDATE 2:
The extended DACs do not look correct in your question. Keep in mind that you should extend the original table (CRQuote), and the projection in order to have the value persisted.
The following definition worked correctly on my end:
//Projection extension
public class PMQuoteExt : PXCacheExtension<PMQuote>
{
#region UsrCustomField
[PXDBString(100, BqlField = typeof(CRQuoteExt.usrCustomField))]
[PXUIField(DisplayName="Custom Field")]
public virtual string UsrCustomField { get; set; }
public abstract class usrCustomField : IBqlField { }
#endregion
}
//Actual Table extension
public class CRQuoteExt : PXCacheExtension<PX.Objects.CR.Standalone.CRQuote>
{
#region UsrCustomField
[PXDBString(100)]
[PXUIField(DisplayName="Custom Field")]
public virtual string UsrCustomField { get; set; }
public abstract class usrCustomField : IBqlField { }
#endregion
}

Custom field on CROpportunity doesn't display saved value since upgrading from 6.10 or 2017R2 to 2018R1

I made a DAC extension on CROpportunity in my customization project which was working well in 6.10 and 2017R2. Now I upgraded my site to 2018R1 and my custom fields don't work anymore. As soon as I save my record, the customized field goes blank even if the database saved the value correctly.
Why is this happening ?
In version 2018R1, PX.Objects.CR.CROpportunity became a projection of PX.Objects.CR.Standalone.CROpportunity.
In order for the projection to get its customized fields values correctly, you need to also customize the Standalone DAC and set the BQL Field of PX.Objects.CR.CROpportunity point to PX.Objects.CR.Standalone.CROpportunity.
Here is an example :
public class CROpportunityExt : PXCacheExtension<PX.Objects.CR.CROpportunity>
{
#region UsrTest
[PXDBDecimal(BqlField = typeof(CROpportunityStandaloneExt.usrTest))]
[PXUIField(DisplayName="Test Field")]
public virtual Decimal? UsrTest { get; set; }
public abstract class usrTest : IBqlField { }
#endregion
}
public class CROpportunityStandaloneExt : PXCacheExtension<PX.Objects.CR.Standalone.CROpportunity>
{
#region UsrTest
[PXDBDecimal]
[PXUIField(DisplayName="Test Field")]
public virtual Decimal? UsrTest { get; set; }
public abstract class usrTest : IBqlField { }
#endregion
}

Resources