Add a column to a dac with langage - acumatica

I would like to add the column "Description Family" taking into account the language of the connected user. I try the function "PXLocalizableDefault", But I don't know how to use this function.
public class InventoryItemExt : PXCacheExtension<PX.Objects.IN.InventoryItem>
{
#region UsrDescription
[PXUIField(DisplayName="Famille description")]
[PXLocalizableDefault(typeof(Search<INItemClass.descr,
Where<INItemClass.itemClassID,
Equal<InventoryItem.itemClassID>>>),typeof(User.languageName????)
,PersistingCheck=PXPersistingCheck.Nothing)]
#endregion
}
Description screen:

I believe you can use PXDBLocalizableString as a replacement for PXDBString and it will provide the functionality you are looking for.
public class InventoryItemExt : PXCacheExtension<PX.Objects.IN.InventoryItem>
{
#region UsrDescription
[PXUIField(DisplayName="Famille description")]
[PXDBLocalizableString(15, IsUnicode = true)]
public string UsrDescription { get; set; }
public class usrDescription : BqlString.Field<usrDescription > {}
#endregion
}

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 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
}

Enabling "AllowAddNew" and/or "AllowEdit" on selector for custom DAC

I have created a custom DAC, Graph, and Screen to manage tracking of new entity for client, called "Management Company." New screen is simple Grid with CRUD controls. Selector on Customer screen allows me to choose from list of "Management Company" entries. I also added new field to Contact DAC and DB table to track which "Management Company" is assigned to a given contact. This field is where the selector is configured.
I am trying to enable the "AllowAddNew" and/or "AllowEdit" properties of this selector. When I set to "True," the buttons show up but they don't do anything.
I can create and save new entries to this DB table via the new screen and I can retrieve them with the Selector just fine. I just can't create new from selector.
I have tried looking this up and I'm not finding much information.
How can I achieve this?
Sample of DAC:
namespace PX.Objects.CR
{
[Serializable]
public class UsrCustomerManagementCompany : IBqlTable
{
#region MancompID
[PXDBString(16, IsUnicode = true, InputMask = ">LLLLLLLLLLLLLLLL", IsKey = true)]
[PXUIField(DisplayName = "Company ID")]
[PXDefault]
public virtual string MancompID { get; set; }
public abstract class mancompID : IBqlField { }
#endregion
#region MancompName
[PXDBString(60, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Company Name")]
[PXDefault]
public virtual string MancompName { get; set; }
public abstract class mancompName : IBqlField { }
#endregion
#region MancompDescr
[PXDBString(4000, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public virtual string MancompDescr { get; set; }
public abstract class mancompDescr : IBqlField { }
#endregion
}
}
Graph:
using System;
using PX.Data;
using PX.Objects.CR;
namespace ClientCode
{
public class ManagementCompanyMaint : PXGraph<ManagementCompanyMaint, UsrCustomerManagementCompany>
{
public PXSelect<UsrCustomerManagementCompany> ManagementCompanies;
}
}
Contact DAC Extension and Selector:
namespace PX.Objects.CR
{
public class ContactExt : PXCacheExtension<PX.Objects.CR.Contact>
{
#region UsrManagementCompany
[PXDBString]
[PXUIField(DisplayName = "Management Company")]
[PXSelector(
typeof(Search<UsrCustomerManagementCompany.mancompID>),
new Type[]
{
typeof(UsrCustomerManagementCompany.mancompID),
typeof(UsrCustomerManagementCompany.mancompName)
},
SubstituteKey = typeof(UsrCustomerManagementCompany.mancompName)
)]
public virtual string UsrManagementCompany { get; set; }
public abstract class usrManagementCompany : IBqlField { }
#endregion
}
}
I think all you are missing is the PXPrimaryGraph attribute on your DAC to indicate for that record type what is the main graph to refer to.
In your case try adding...
[PXPrimaryGraph(typeof(ClientCode.ManagementCompanyMaint))]
[Serializable]
public class UsrCustomerManagementCompany : IBqlTable
{
//...
}
Here are some related questions that might also help:
How to create a hyperlink user field
how to use AllowEdit in Acumatica

Acumatica - PXDBScalar uniqueidentifier is incompatible with int

I'm trying to populate this field with the value of a customer attribute.
public class CustomerExt : PXCacheExtension<Customer>
{
#region OtherID
[PXString]
[PXUIField(DisplayName = "Other ID")]
[PXDBScalar(typeof(Search<CSAnswers.value,
Where<CSAnswers.refNoteID, Equal<Current<Customer.noteID>>,
And<CSAnswers.attributeID, Like<OtherIDAttr>>>>))]
public virtual string UsrOtherID { get; set; }
public abstract class usrOtherID : IBqlField { }
#endregion
public class OtherIDAttr: Constant<string>
{
public OtherIDAttr() : base("OTHERID") { }
}
}
It causes the above error when the field is added to a screen. If I remove the second condition from the Search<>, the field populates, so I'm sure its the comparison between the CSAnswers AttributeID and the constant string.
If someone could point me in the right direction, that would be awesome.
Looks like you get this error due to the Current operator (Equal<Current<Customer.noteID>>) used within PXDBScalarAttribute.
Attempt to simply remove the Current operator led to a different error Invalid column name 'NoteID'., which can be resolved by the replacement of Customer.noteID with PX.Objects.CR.BAccount.noteID:
public class CustomerExt : PXCacheExtension<Customer>
{
#region OtherID
public abstract class usrOtherID : IBqlField { }
[PXString]
[PXUIField(DisplayName = "Other ID")]
[PXDBScalar(typeof(Search<CSAnswers.value,
Where<CSAnswers.refNoteID, Equal<BAccount.noteID>,
And<CSAnswers.attributeID, Like<OtherIDAttr>>>>))]
public virtual string UsrOtherID { get; set; }
#endregion
public class OtherIDAttr : Constant<string>
{
public OtherIDAttr() : base("OTHERID") { }
}
}

Acumatica PXselector, how to type new value into selector control

My DAC DMSRouteSetting.CS
#region RouteCD
public abstract class routeCD : IBqlField { }
[PXDBString(15)]
[PXDefault, PXUIField(DisplayName = "Route ID", Required = true)]
[PXSelector(typeof(Search4<DMSRouteSetting.routeCD, Aggregate<GroupBy<DMSRouteSetting.routeCD>>>))]
public virtual string RouteCD { get; set; }
#endregion
I want to select a exist value in selector or typing a new value.
Current. I just select a exist value but can't typing a new value
Can you help me?
Thanks
Try adding ValidateValue = false in your selector attribute
public abstract class routeCD : IBqlField { }
[PXDBString(15)]
[PXDefault, PXUIField(DisplayName = "Route ID", Required = true)]
[PXSelector(typeof(Search4<DMSRouteSetting.routeCD, Aggregate<GroupBy<DMSRouteSetting.routeCD>>>), ValidateValue = false)]
public virtual string RouteCD { get; set; }
If i am not wrong, you cant directly add new values to selector, but you can set a property to show an icon next to selector which helps to open the Master Page and user can add it there.
Look for the property
AllowAddNew="True" AllowEdit="True"

Resources