Solved

Issue with adding the grid on Projects screen

  • 29 November 2023
  • 12 replies
  • 92 views

Userlevel 2
Badge

I am trying to add a grid to store values to my custom DAC on Projects screen. But I am not able to add a new row. When I try to add new row the row is added momentarily and then just vanishes. I checked the trace and it is showing this exception. ComplianceDocuments view is available in the Acumatica code.

 

 

My Custom DAC code

using System;
using PX.Data;

namespace MyCust
{
[Serializable]
[PXCacheName("MyDAC")]
public class MyDAC : IBqlTable
{
#region ProjectID
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Project ID")]
public virtual int? ProjectID { get; set; }
public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { }
#endregion

#region Id
[PXDBIdentity(IsKey = true)]
public virtual int? Id { get; set; }
public abstract class id : PX.Data.BQL.BqlInt.Field<id> { }
#endregion

#region CreatedDateTime
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
#endregion

#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
#endregion

#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
#endregion

#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
#endregion

#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
#endregion

#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
#endregion

#region Tstamp
[PXDBTimestamp()]
[PXUIField(DisplayName = "Tstamp")]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
#endregion

#region Noteid
[PXNote()]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }
#endregion

#region Description
[PXDBString(500, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Description")]
public virtual string Description { get; set; }
public abstract class description : PX.Data.BQL.BqlString.Field<description> { }
#endregion

#region Percentage
[PXDBDecimal()]
[PXUIField(DisplayName = "Percentage")]
public virtual Decimal? Percentage { get; set; }
public abstract class percentage : PX.Data.BQL.BqlDecimal.Field<percentage> { }
#endregion

#region CalculatePrice
[PXDBDecimal()]
[PXUIField(DisplayName = "Calculate Price")]
public virtual Decimal? CalculatePrice { get; set; }
public abstract class calculatePrice : PX.Data.BQL.BqlDecimal.Field<calculatePrice> { }
#endregion
}
}

 

And this is the declared view in GraphExt 

public PXSelect<MyDAC, Where<MyDAC.projectID, Equal<Current<PMProject.contractID>>>> MyView;

ASPX Code for the grid added to Summary tab in screen (PM301000) 

<px:PXGrid runat="server" ID="CstPXGrid3" SkinID="Details">
<Levels>
<px:PXGridLevel DataMember="MyView">
<Columns>
<px:PXGridColumn DataField="Percentage" Width="100" />
<px:PXGridColumn DataField="Description" Width="280" />
<px:PXGridColumn DataField="CalculatePrice" Width="100" /></Columns></px:PXGridLevel></Levels></px:PXGrid>

 

icon

Best answer by darylbowman 30 November 2023, 19:49

View original

12 replies

Badge +11

I could be wrong, but I'm pretty sure ProjectID should not be part of your table's primary key and therefore also not IsKey = true

Userlevel 2
Badge

@darylbowman I have added ProjectID and Id as the primary key in DB. Do you think that is causing the issue ?

 

Badge +11

I would guess. I would make ID the only key. ProjectID would be a foreign key, but you probably don't need to specify that in the database.

Userlevel 2
Badge

@darylbowman I removed ProjectID from the primary key and still facing the same issue same error in the trace. I have only kept Id as the primary key made changes to the DB and DAC both. 

Badge +11

In the database, is ProjectID nullable?

Badge +11

Oh, I know what the problem is. Nowhere is the detail record getting the ProjectID populated, which means as soon as it is inserted, it will disappear because your data view is only showing the current ProjectID.

 

You need to specify a PXParent attribute and a PXDBDefault to PMProject.contractID on the ID DAC field.

Userlevel 2
Badge
#region ProjectID
[PXDBInt]
[PXDefault(typeof(Current<PMProject.contractID>))]
[PXUIField(DisplayName = "Project ID")]
public virtual int? ProjectID { get; set; }
public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { }
#endregion

#region Id
[PXParent(typeof(Select<PMProject, Where<PMProject.contractID, Equal<MyDAC.projectID.FromCurrent>>>))]
[PXDBIdentity(IsKey = true)]
public virtual int? Id { get; set; }
public abstract class id : PX.Data.BQL.BqlInt.Field<id> { }
#endregion

@darylbowman  Are you suggesting something like this ? This is also not working out. The row still disappears as I try to add new row. Originally this was my first code with the composite primary key but I removed everything to make it simple.

Badge +11

The attribute for defaulting from a parent ID is PXDBDefault

Badge +11

After a brief refresh of master-detail records, I believe having the ProjectID as a key is correct after all as well.

Badge +11

I don’t believe this is part of your problem, but in thinking about this a bit more, I think you’re confusing two different key types here. Normally, a standalone table would have a computed identity key and if you were relating it to another table, you’d add a foreign key to that table. That’s what I was thinking when I suggested you remove ProjectID from the key. In a master-detail relationship, in most cases, the reason the master key is included as a key in the child table is because the detail records are only ever bound to one master record. If this is your use-case, then having ProjectID in the key IS correct, but I would suggest not making the ID field a computed identity key then, since a LineNbr field would make more sense. Take SOLine, which uses the parent keys as two of the three keys and LineNbr as the third.

If your detail records could be part of more than one master, then the ProjectID should NOT be part of the keys and the ID should be a computed identity key.

Userlevel 2
Badge

@darylbowman  I have tried this code with ProjectID as a part of key and without both is giving the same error. If you are able to create this please do let me know if it works on your machine. 

Badge +11

Ok, got it working. I did it the way I believe it should be done, so it’s not identical to yours, but you’re welcome to mess with it.

DAC keys:

(notice:

  • the PXDBDefault does NOT use the current parameter
  • the LineNbr defines a PXLineNbr with a custom counter field defined on the Project DAC, below)
[Serializable]
[PXCacheName("MyDAC")]
public class MyDAC : IBqlTable
{
#region ProjectID
[PXDBInt(IsKey = true)]
[PXParent(typeof(Select<PMProject, Where<PMProject.contractID, Equal<MyDAC.projectID.FromCurrent>>>))]
[PXDBDefault(typeof(PMProject.contractID))]
[PXUIField(DisplayName = "Project ID")]
public virtual int? ProjectID { get; set; }
public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { }
#endregion

#region LineNbr
[PXDBInt(IsKey = true)]
[PXLineNbr(typeof(ContractExt.usrMyDACLineCntr))]
[PXUIField(DisplayName = "Line Nbr")]
public virtual int? LineNbr { get; set; }
public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
#endregion

Project DAC extension:

public class ContractExt : PXCacheExtension<PX.Objects.CT.Contract>
{
#region UsrMyDACLineCntr
[PXDBInt]
[PXDefault(0)]
//[PXUIField(DisplayName="Custom Field")]
public virtual int? UsrMyDACLineCntr { get; set; }
public abstract class usrMyDACLineCntr : PX.Data.BQL.BqlInt.Field<usrMyDACLineCntr> { }
#endregion
}

ProjectEntry graph extension:

public class ProjectEntry_Extension : PXGraphExtension<PX.Objects.PM.ProjectEntry>
{
public PXSelect<MyDAC, Where<MyDAC.projectID, Equal<Current<PMProject.contractID>>>> MyView;

#region Event Handlers

protected virtual void _(Events.RowInserting<MyDAC> e)
{
MyDAC row = e.Row;
if (row is null) return;

var projectGraph = e.Cache.Graph as ProjectEntry;
var project = projectGraph?.Project.Current;
var projectExt = project?.GetExtension<ContractExt>();
if (projectExt?.UsrMyDACLineCntr is null)
projectGraph.Project.Cache.SetValue<ContractExt.usrMyDACLineCntr>(project, 0);
}

#endregion
}

the RowInserting event prevents an error when inserting a grid row on a project that was created prior to the new counter field. The counter field will be null for existing projects, and the PXLineNbr doesn’t know what to do with that.

 

Here it is in action:

Obviously, the Project ID and LineNbr fields can be hidden

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved