Solved

Why deleting one record in the Parent Grid, deletes ALL records from the Child Grid instead of deleting only the records tied to that parent record

  • 14 September 2023
  • 8 replies
  • 125 views

Userlevel 7
Badge +9

Hello everyone, 

My apology for the lengthy question here but it needed to provide all pieces of the information someone might need to help.

Also I have checked out these links:

https://stackoverflow.com/questions/49264233/how-to-create-master-detail-grids-in-acumatica

and 

https://asiablog.acumatica.com/2019/04/grids-master-detail-relationship.html

I am having a hard time understanding why deleting one record in the Parent Grid, deletes ALL records from the Child Grid instead of deleting only the records tied to that parent record. I have created a new screen made of Form-MasterGrid-ChildGrid. See the attached screenshot please.

When I navigate in the Form the Master Grid refreshes correctly and when I navigate in the Master Grid, the Child Grid refreshes correctly as well. The only problem I am facing is when I delete a record from the Master Grid, the system instead of deleting only the deleted Master Record children, deletes ALL records in the Child Grid.

Here are my partial DACs (Key Fields only):

1) My Form DAC

    public class HCLPMWIP : IBqlTable
{
#region Keys
public class PK : PrimaryKeyOf<HCLPMWIP>.By<wipID>
{
public static HCLPMWIP Find(PXGraph graph, string wipID) => FindBy(graph, wipID);
}
#endregion

#region WIPID
public abstract class wipID : PX.Data.BQL.BqlString.Field<wipID>
{
public const int Length = 15;
}
protected string _WIPID;
[PXDBString(HCLPMWIP.wipID.Length, IsUnicode = true, IsKey = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXDefault()]
[PXSelector(typeof(Search<HCLPMWIP.wipID>), Filterable = true)]
[PXUIField(DisplayName = "WIP ID", Visibility = PXUIVisibility.SelectorVisible, Required = true)]
public virtual string WIPID
{
get
{
return this._WIPID;
}
set
{
this._WIPID = value;
}
}
#endregion
}

 

2) My Master Grid DAC

    public class HCLPMWIPSummary : IBqlTable
{
#region Keys
public class PK : PrimaryKeyOf<HCLPMWIPSummary>.By<wipID, projectID>
{
public static HCLPMWIPSummary Find(PXGraph graph, string wipID, int? projectID) => FindBy(graph, wipID, projectID);
}

public static class FK
{
public class WIP : HCLPMWIP.PK.ForeignKeyOf<HCLPMWIPSummary>.By<wipID> { }
}
#endregion

#region WIPID
public abstract class wipID : PX.Data.BQL.BqlString.Field<wipID> { }
protected string _WIPID;
[PXDefault(typeof(HCLPMWIP.wipID.FromCurrent))]
[PXDBString(HCLPMWIP.wipID.Length, IsUnicode = true, IsKey = true)]
[PXUIField(DisplayName = "WIP ID", Required = true, Enabled = false, Visible = false)]
public virtual string WIPID
{
get
{
return this._WIPID;
}
set
{
this._WIPID = value;
}
}
#endregion

#region ProjectID
public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { }
protected int? _ProjectID;
[ActiveProjectOrContractBase(IsKey = true, Required = true)]
[PXDefault()]
[PXParent(typeof(Select<HCLPMWIP,
Where<HCLPMWIP.wipID.IsEqual<HCLPMWIPSummary.wipID.FromCurrent>>>))]
[PXForeignReference(typeof(Field<HCLPMWIPSummary.projectID>.IsRelatedTo<PMProject.contractID>))]
public virtual int? ProjectID
{
get
{
return this._ProjectID;
}
set
{
this._ProjectID = value;
}
}
#endregion
}

 

3) My Child Grid DAC

    public class HCLPMWIPDetail : IBqlTable
{
#region Keys
public class PK : PrimaryKeyOf<HCLPMWIPDetail>.By<wipID, projectID, projectTaskID, costCodeID, accountGroupID, inventoryID>
{
public static HCLPMWIPDetail Find(PXGraph graph, string wipID, int? projectID, int? projectTaskID, int? costCodeID, int? accountGroupID, int? inventoryID) => FindBy(graph, wipID, projectID, projectTaskID, costCodeID, accountGroupID, inventoryID);
}

public static class FK
{
public class WIPSummary : HCLPMWIPSummary.PK.ForeignKeyOf<HCLPMWIPDetail>.By<wipID, projectID> { }
}
#endregion

#region WIPID
public abstract class wipID : PX.Data.BQL.BqlString.Field<wipID> { }
protected string _WIPID;
[PXDBString(HCLPMWIP.wipID.Length, IsUnicode = true, IsKey = true)]
[PXDefault(typeof(HCLPMWIPSummary.wipID.FromCurrent))]
[PXUIField(DisplayName = "WIP ID", Required = true, Enabled = false, Visible = false)]
public virtual string WIPID
{
get
{
return this._WIPID;
}
set
{
this._WIPID = value;
}
}
#endregion

#region ProjectID
public abstract class projectID : PX.Data.BQL.BqlInt.Field<projectID> { }
protected int? _ProjectID;
[ActiveProjectOrContractBase(IsKey = true, Required = true, Enabled = false, Visible = false)]
[PXDefault(typeof(HCLPMWIPSummary.projectID.FromCurrent))]
public virtual int? ProjectID
{
get
{
return this._ProjectID;
}
set
{
this._ProjectID = value;
}
}
#endregion

#region ProjectTaskID
public abstract class projectTaskID : PX.Data.BQL.BqlInt.Field<projectTaskID> { }
protected int? _ProjectTaskID;
[BaseProjectTask(typeof(HCLPMWIPSummary.projectID), IsKey = true, DisplayName = "Task", AllowInactive = true, AllowCanceled = true, AllowCompleted = true, Required = true)]
[PXDefault()]
public virtual int? ProjectTaskID
{
get
{
return this._ProjectTaskID;
}
set
{
this._ProjectTaskID = value;
}
}
#endregion

#region CostCodeID
public abstract class costCodeID : PX.Data.BQL.BqlInt.Field<costCodeID> { }
protected int? _CostCodeID;
[CostCode(null, typeof(HCLPMWIPSummary.projectTaskID), AccountType.Income, IsKey = true, DisplayName = "Cost Code", ProjectField = typeof(HCLPMWIPSummary.projectID), DescriptionField = typeof(PMCostCode.description), Required = true, Enabled = false, Visible = false, AllowNullValue = false, Filterable = true)]
[PXDefault()]
public virtual int? CostCodeID
{
get
{
return this._CostCodeID;
}
set
{
this._CostCodeID = value;
}
}
#endregion

#region AccountGroupID
public abstract class accountGroupID : PX.Data.BQL.BqlInt.Field<accountGroupID> { }
protected int? _AccountGroupID;
[AccountGroup(typeof(Where<Match<PMAccountGroup, Current<AccessInfo.userName>>>), IsKey = true, DisplayName = "Account Group", Required = true, Enabled = false, Visible = false)]
[PXDefault()]
public virtual int? AccountGroupID
{
get
{
return this._AccountGroupID;
}
set
{
this._AccountGroupID = value;
}
}
#endregion

#region InventoryID
public abstract class inventoryID : PX.Data.BQL.BqlInt.Field<inventoryID> { }
protected int? _InventoryID;
[PXDBInt(IsKey = true)]
[PMInventorySelector(Filterable = true, SupportNewValues = true)]
[PXDefault()]
[PXUIField(DisplayName = "Inventory", Required = true, Enabled = false, Visible = false)]
[PXParent(typeof(Select<HCLPMWIPSummary,
Where<HCLPMWIPSummary.wipID.IsEqual<HCLPMWIPDetail.wipID.FromCurrent>
.And<HCLPMWIPSummary.projectID.IsEqual<HCLPMWIPDetail.projectID.FromCurrent>>>>))]
public virtual int? InventoryID
{
get
{
return this._InventoryID;
}
set
{
this._InventoryID = value;
}
}
#endregion
}

 

4) My Graph Public Views

    public class HCLPMWIPEntry : PXGraph<HCLPMWIPEntry, HCLPMWIP>
{
#region DataViews
[PXViewName(HCLPMMessages.WorkInProgress)]
public SelectFrom<HCLPMWIP>
.View HCLWIPDocument;

[PXImport(typeof(HCLPMWIP))]
public SelectFrom<HCLPMWIPSummary>
.Where<HCLPMWIPSummary.wipID.IsEqual<HCLPMWIP.wipID.FromCurrent>>
.View HCLWIPSummary;

[PXImport(typeof(HCLPMWIPSummary))]
public SelectFrom<HCLPMWIPDetail>
.Where<HCLPMWIPDetail.wipID.IsEqual<HCLPMWIPSummary.wipID.FromCurrent>
.And<HCLPMWIPDetail.projectID.IsEqual<HCLPMWIPSummary.projectID.FromCurrent>>>
.View HCLWIPDetail;
#endregion
}

 

5) and finally, my page

<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="True" ValidateRequest="False" CodeFile="HC305000.aspx.cs" Inherits="Page_HC305000" Title="Untitled Page" %>
<%@ MasterType VirtualPath="~/MasterPages/FormDetail.master" %>

<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
<px:PXDataSource
ID="ds" runat="server" Visible="True" Width="100%" TypeName="HCL.PM.WorkInProgress.HCLPMWIPEntry" PrimaryView="HCLWIPDocument"
BorderStyle="NotSet" HeaderDescriptionField="FormCaptionDescription">
</px:PXDataSource>
</asp:Content>

<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="Server">
<px:pxformview AllowAutoHide="True" AllowCollapse="True" BPEventsIndicator="True" MinHeight="1" LinkIndicator="True" ID="WIPForm" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" DataMember="HCLWIPDocument" Caption="Selection">
<Template>
<px:PXLayoutRule runat="server" StartColumn="True" LabelsWidth="S" ControlSize="XM" ></px:PXLayoutRule>
<px:PXSelector runat="server" ID="edWIPID" DataField="WIPID" CommitChanges="True"></px:PXSelector>
</Template>
</px:pxformview>
</asp:Content>

<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server">
<px:pxtab ID="tab" runat="server" Width="100%" Height="511px" DataSourceID="ds" DataMember="HCLWIPDocumentSettings">
<Items>
<px:PXTabItem Text="Projects">
<Template>
<px:PXSplitContainer runat="server" Panel1MinSize="250" Orientation="Horizontal" AllowResize="True" Panel2MinSize="40" SplitterPosition="600" SavePosition="True" PositionInPercent="False" AllowAutoHide="True" ID="SplitContainer" SkinID="Horizontal" Width="100%" EnableViewState="True">
<AutoSize Enabled="True" Container="Parent" />

<Template1>
<px:PXGrid runat="server" ID="HCLWIPSummaryGrid" SyncPosition="True" SkinID="Details" Width="100%" Height="150px" DataSourceID="ds" AllowPaging="False">
<Mode AllowAddNew="True" AllowUpdate="True" AllowDelete="True" AllowFormEdit="False" AllowUpload="True" InitNewRow="True" />
<AutoSize Enabled="True" Container="Parent" />
<%--<AutoCallBack Command="Refresh" Target="HCLWIPDetailGrid" ActiveBehavior="True">
<Behavior RepaintControlsIDs="HCLWIPDetailGrid" BlockPage="True" CommitChanges="False" />
</AutoCallBack>--%>
<AutoCallBack Command="Refresh" Target="HCLWIPDetailGrid" />
<OnChangeCommand Command="Refresh" Target="HCLWIPDetailGrid" />
<Levels>
<px:PXGridLevel DataMember="HCLWIPSummary">
<RowTemplate>
<px:PXSegmentMask runat="server" DataField="ProjectID" ID="edSummarProjectID" CommitChanges="True" />
<px:PXSegmentMask runat="server" </RowTemplate>
<Columns>
<px:PXGridColumn DataField="WIPID" />
<px:PXGridColumn DataField="ProjectID" CommitChanges="True" />
</Columns>
</px:PXGridLevel>
</Levels>
</px:PXGrid>
</Template1>

<Template2>
<px:PXGrid runat="server" ID="HCLWIPDetailGrid" SkinID="Details" Width="100%" Height="100%" DataSourceID="ds" AllowPaging="False" SyncPosition="True" NoteIndicator="True" FilesIndicator="True">
<Mode AllowAddNew="True" AllowUpdate="True" AllowDelete="True" AllowFormEdit="False" AllowUpload="True" InitNewRow="True" />
<AutoSize Enabled="True" Container="Parent" />
<%--<CallbackCommands>
<InitRow CommitChanges="true" />
</CallbackCommands>--%>
<CallbackCommands>
<Refresh SelectControlsIDs="HCLWIPSummaryGrid" />
</CallbackCommands>
<Levels>
<px:PXGridLevel DataMember="HCLWIPDetail">
<RowTemplate>
<px:PXSegmentMask runat="server" DataField="ProjectID" ID="edDetailProjectID" CommitChanges="True" />
<px:PXSegmentMask runat="server" DataField="ProjectTaskID" ID="edDetailProjectTaskID" CommitChanges="True" />
<px:PXSegmentMask runat="server" DataField="CostCodeID" ID="edDetailyCostCodeID" />
<px:PXSegmentMask runat="server" DataField="AccountGroupID" ID="edDetailyAccountGroupID" />
<px:PXSegmentMask runat="server" DataField="InventoryID" ID="edDetailyInventoryID" />
</RowTemplate>
<Columns>
<px:PXGridColumn DataField="WIPID" />
<px:PXGridColumn DataField="ProjectID" CommitChanges="True" />
<px:PXGridColumn DataField="ProjectTaskID" CommitChanges="True" />
<px:PXGridColumn DataField="CostCodeID" />
<px:PXGridColumn DataField="AccountGroupID" />
<px:PXGridColumn DataField="InventoryID" />
</Columns>
</px:PXGridLevel>
</Levels>
</px:PXGrid>
</Template2>

</px:PXSplitContainer>
</Template>
</px:PXTabItem>
</Items>
<AutoSize Container="Window" Enabled="True" MinHeight="150" ></AutoSize>
</px:pxtab>
</asp:Content>

 

Can anyone help me why this is happening, please?

 

@smarenich @rdevyatko 

icon

Best answer by aaghaei 17 September 2023, 07:04

View original

8 replies

Userlevel 7
Badge +4

@aaghaei 

I believe you are missing PXParent for your child grid DAC HCLPMWIPDetail for wipID field to add parent association to HCLPMWIPSummary DAC’s wipID

Userlevel 7
Badge +9

@RohitRattan88 thank you for the response. If I recall correctly, as per Acumatica guidelines PXParent can be place on any of the Key Fields referencing to the parent that I have placed it on my last key which is InventoryID.
This is not the only form I have I developed with 3 layers structure and they work just fine with this logic.

Userlevel 7
Badge +9

@RohitRattan88 to test whether moving the PXParent from the last Key to the first key, makes any difference, I made this change but no difference.

Userlevel 7
Badge +4

@aaghaei 

what is the definition for HCLWIPDocumentSettings view used on ASPX?

 

<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server"> <px:pxtab ID="tab" runat="server" Width="100%" Height="511px" DataSourceID="ds" DataMember="HCLWIPDocumentSettings">

Userlevel 7
Badge +9

@RohitRattan88 it's just a public view referring to the Current WIP document as follows:

        public SelectFrom<HCLPMWIP>
.Where<HCLPMWIP.wipID.IsEqual<HCLPMWIP.wipID.FromCurrent>>
.View HCLWIPDocumentSettings;

 

Userlevel 7
Badge +9

I figured it out. In the Detail DAC declarations, for ProjectTaskID and CostCodeID I was referring to HCLPMWIPSummary to get the ProjectID and ProjecTaskID instead of referring to HCLPMWIPDetail. It just wanted to drive me crazy.

Userlevel 7
Badge

Thank you for sharing your solution with the community @aaghaei!

Userlevel 7
Badge +4

I figured it out. In the Detail DAC declarations, for ProjectTaskID and CostCodeID I was referring to HCLPMWIPSummary to get the ProjectID and ProjecTaskID instead of referring to HCLPMWIPDetail. It just wanted to drive me crazy.

Great. thanks for sharing your finding. I was hoping to look further into it today but guess I dont need to😉

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