Overview: I have a custom table to display info to a grid. When the user clicks a button on the form, I call two methods. One to delete the records matching the filter and then re-add the data back into the table using the same filter values. The data in the table cannot be “selected” using a normal select statement as I have to parse fields from the AuditHistory table (ModifiedFields contains null delimited field/value pairs). I am “de-normalizing” the data so there is one record in the custom table for each modified field in the ModifiedFields column. This is what the customer has requested.
The form works as expected except that the DeleteData method only works EVERY OTHER TIME!
Here is the sequence of events:
- open form. At this point there is no data in the table.
- Click Get New Data
- The DeleteData fires and nothing is deleted (obviously...there is no data in the table matching the filter yet)
- Data is added to the table as desired using the filter field values.
- The user clicks the Get New Data button and when the DeleteData is fired, there is a locking violation thrown. No data gets deleted and since an error is thrown, the AddData method doesn’t get called (which is good because it would just try to add duplicate data which would also throw errors as keys would be violated)
- The user clicks the Get New Data button and the data IS deleted and re-added.
- The user clicks the Get New Data button and the error in item 5 occurs.
In summary, every other time you click the Get New Data button it works fine.
I will paste the entire graph here in case anyone sees anything I can do to fix this.
using PX.Data;
using PX.Data.BQL;
using PX.Data.BQL.Fluent;
using PX.SM;
using QTCAuditReporting.DAC;
using System;
using System.Collections;
namespace QTCAuditReporting
{
public class QTCAuditReport : PXGraph<QTCAuditReport>
{
private Guid? _currentUser;
public QTCAuditReport()
{
_currentUser = CommonServiceLocator.ServiceLocator.Current.GetInstance<ICurrentUserInformationProvider>().GetUserId();
}
bPXHidden]
public class QTCAuditHistoryReportFilter : IBqlTable
{
#region ScreenID
gPXString(8, IsFixed = true, InputMask = "")]
uPXDefault]
PXUIField(DisplayName = "Screen ID", Required = true)]
iPXSelector(typeof(Search5<AUAuditTable.screenID,
InnerJoin<SiteMap, On<SiteMap.screenID, Equal<AUAuditTable.screenID>>>,
Where<AUAuditTable.isActive, Equal<True>>,
Aggregate<GroupBy<AUAuditTable.screenID>>>),
typeof(AUAuditTable.screenID),
typeof(SiteMap.title),
DescriptionField = typeof(SiteMap.title))]
public virtual string ScreenID { get; set; }
public abstract class screenID : PX.Data.BQL.BqlString.Field<screenID> { }
#endregion
#region ChangeDate
oPXDate]
/PXUIField(DisplayName = "Change Date", Required = true)]
iPXDefault]
public virtual DateTime? ChangeDate { get; set; }
public abstract class changeDate : PX.Data.BQL.BqlDateTime.Field<changeDate> { }
#endregion
}
public PXFilter<QTCAuditHistoryReportFilter> Filter;
PXFilterable]
public SelectFrom<QTCAuditHistoryReport>.Where<QTCAuditHistoryReport.screenID.IsEqual<QTCAuditHistoryReportFilter.screenID.FromCurrent>.
And<QTCAuditHistoryReport.changeDate.IsEqual<QTCAuditHistoryReportFilter.changeDate.FromCurrent>.
And<QTCAuditHistoryReport.reportingUserID.IsEqual<AccessInfo.userID.FromCurrent>>>>.View.ReadOnly DetailsView;
public PXSelect<QTCAuditHistoryReport> ItemsToAdd;
#region "Actions"
public PXAction<QTCAuditHistoryReportFilter> GetReportData;
GPXButton(CommitChanges = true)]
aPXUIField(DisplayName = "Get Report Data", Enabled = false)]
protected void getReportData()
{
if(Filter.Current.ScreenID is null || Filter.Current.ChangeDate is null) return;
if (Filter.Current.ScreenID.Equals(string.Empty) || Filter.Current.ChangeDate.Equals(string.Empty)) return;
DeleteData();
GetNewDataset();
}
#endregion
protected void DeleteData()
{
using (var ts = new PXTransactionScope())
{
foreach (QTCAuditHistoryReport item in DetailsView.Select())
{
var result = DetailsView.Delete(item);
}
var result2 = DetailsView.Cache.Persist(PXDBOperation.Delete);
ts.Complete(this);
}
}
protected void GetNewDataset()
{
DateTime startDate = (DateTime)Filter.Current.ChangeDate;
DateTime endDate = (DateTime)Filter.Current.ChangeDate;
startDate = startDate.Date;
endDate = endDate.Date;
startDate = startDate.AddDays(-1);
endDate = endDate.AddDays(1);
ItemsToAdd.Cache.Clear();
foreach (AuditHistory item in SelectFrom<AuditHistory>.
Where<AuditHistory.screenID.IsEqual<@P.AsString>.
And<AuditHistory.changeDate.IsBetween<@P.AsDateTime, @P.AsDateTime>>>
.View.Select(this, Filter.Current.ScreenID, startDate, endDate))
{
var dateTemp = (DateTime)item.ChangeDate;
var workingDate = dateTemp.Date;
QTCAuditHistoryReport newRow = new QTCAuditHistoryReport
{
BatchID = item.BatchID,
ChangeDate = workingDate,
ChangeID = item.ChangeID,
CombinedKey = item.CombinedKey,
Email = "",
FirstName = "",
LastName = "",
ModifiedFieldName = "",
ModifiedFieldValue = "",
ScreenID = item.ScreenID,
TableName = item.TableName,
Operation = item.Operation,
Userid = item.UserID,
ReportingUserID = _currentUser
};
ItemsToAdd.Insert(newRow);
}
ItemsToAdd.Cache.Persist(PXDBOperation.Insert);
ItemsToAdd.Cache.Clear();
DetailsView.View.RequestRefresh();
}
}
I haven’t even gotten to the parsing coding yet. I’m just getting the framework for the process working.
Sorry for posting so many help requests lately. I’m a noob and I am under the gun to get this out to the client.