Skip to main content
Answer

Custom Table Insert Does Not Happen for Customer Extension

  • February 2, 2025
  • 7 replies
  • 88 views

Forum|alt.badge.img

I completed the T210 course and proceeded to apply it to a real world use case where I need multiple custom fields attached to a specific class of Customer.  Rather than the user field approach, which will enhance Business Account and extend those fields to all related entities using the shared DB table, I want to use a custom table to limit the storage to Customers only. It doesn’t seem to work on Insert though.  Is there something additional that needs to be done to insert a new record in a custom table from a graph extension? I don’t remember doing that in T210 for the custom tab on the Stock Items screen. I have the PXDBDefault and PXParent attributes assigned.  Aren’t they supposed to facilitate insertion as well as other operations? On Create, with an explicitly assigned Customer code, I get the error “BAccountID can’t be null”, but if I manually insert a record from SSMS after create, everything works fine.

What did I miss?  Thanks.

Here is the start of the DAC definition:

using System;
using PX.Data;
using PX.Data.BQL;
using PX.Data.BQL.Fluent;
using PX.Objects.AR;

namespace CustomerDealerExtended
{
[PXCacheName(Messages.ZZCustomerDealerExt)]
public class ZZCustomerDealerExt : PXBqlTable, IBqlTable
{
#region BAccountID
[PXDBInt(IsKey = true)]
[PXDBDefault(typeof(Customer.bAccountID))]
[PXParent(typeof(SelectFrom<Customer>.Where<Customer.bAccountID.
IsEqual<ZZCustomerDealerExt.bAccountID.FromCurrent>>))]
public virtual int? BAccountID { get; set; }
public abstract class bAccountID : PX.Data.BQL.BqlInt.Field<bAccountID> { }
#endregion

...
}

Here is the start of the graph extension:

using PX.Data;
using PX.Data.BQL.Fluent;
using CustomerDealerExtended;

namespace PX.Objects.AR
{
// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public sealed class CustomerMaintExt : PXGraphExtension<PX.Objects.AR.CustomerMaint>
{

#region Data Views
public SelectFrom<ZZCustomerDealerExt>.Where<ZZCustomerDealerExt.bAccountID.
IsEqual<Customer.bAccountID.FromCurrent>>.View CustomerDealerExt = null!;

#endregion

 

Best answer by Django

Just to confirm - are you wanting to add a parallel table to ARCustomer (which is an extension of BAccount)? Or are you wanting to add a series of custom fields to ARCustomer?

In case it is the first, this article might help:

https://www.acumatica.com/blog/creating-acumatica-dac-extension-tables/

 

7 replies

Forum|alt.badge.img+7
  • Captain II
  • Answer
  • February 2, 2025

Just to confirm - are you wanting to add a parallel table to ARCustomer (which is an extension of BAccount)? Or are you wanting to add a series of custom fields to ARCustomer?

In case it is the first, this article might help:

https://www.acumatica.com/blog/creating-acumatica-dac-extension-tables/

 


Forum|alt.badge.img
  • Author
  • Varsity II
  • February 3, 2025

Thanks for the response.  Yes, the first option is similar to what I’m trying to achieve with a custom table that doesn’t impact the other BAccount types with added UDF fields, but I was looking for a cleaner approach that doesn’t mix the fields together in the CurrentCustomer view.  The blog link is very helpful though.  I see more related posts when using the correct terms. I was hoping that the master:detail approach from T210 would work to link the custom table to ARCustomer; it does as far as I can tell, just not for inserts. I’m sure it will become clearer as to why that is as I get more experience with this framework.  I’ll try this approach for now.  Thanks again.


Forum|alt.badge.img
  • Author
  • Varsity II
  • February 3, 2025

The PXTable approach worked for inserts.  I can query the underlying custom table and see the records.  However, when going back to the same customer in change mode, the values are not pulled into the view fields for display and any attempt to save results in the message Error: Another process has added the 'Customer' record. Your changes will be lost.

DAC Definition:

using System;
using PX.Data;
using PX.Objects.AR;

namespace CustomerDealerExtended
{
// Acuminator disable once PX1011 InheritanceFromPXCacheExtension [Justification]
[PXCacheName(Messages.ZZCustomerDealerExt)]

[PXTable(typeof(Customer.bAccountID), IsOptional = true)]

public class ZZCustomerDealerExt : PXCacheExtension<Customer>
{
public static bool IsActive()
{
return true;
}

#region BAccountID
[PXDBInt(IsKey = true)]
public virtual int? BAccountID { get; set; }
public abstract class bAccountID : PX.Data.BQL.BqlString.Field<bAccountID> { }

#endregion
...
}

Graph Definition (no more view):

using PX.Data;

namespace PX.Objects.AR
{
// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public class CustomerMaintExt : PXGraphExtension<PX.Objects.AR.CustomerMaint>
{
public static bool IsActive()
{
return true;
}

}
}

I will look at the SQL for the join in change mode.


RohitRattan88
Acumatica Moderator
Forum|alt.badge.img+4
  • Acumatica Moderator
  • February 3, 2025

@bbohn I dont think your require GraphExt for your purposes. Reference to PXTable can be found at DAC Extension Mapped to an Extension Table

Other issue working with Customer DAC could be that it is derived from BAccount DAC. Maybe share full SQL and full DAC code to review and assist accordingly.


Forum|alt.badge.img
  • Author
  • Varsity II
  • February 4, 2025

@bbohn I dont think your require GraphExt for your purposes. Reference to PXTable can be found at DAC Extension Mapped to an Extension Table

Other issue working with Customer DAC could be that it is derived from BAccount DAC. Maybe share full SQL and full DAC code to review and assist accordingly.

Thanks for the response and the link.  True on the need for the graph extension, until I re-add the event handler for RowSelected to conditionally hide the tab. After a bunch of errors, I started over with a clean install and project.  It works for Create and Change but not for Delete.  Whether I use an inner join or left out join in the DAC definition, I get the exception message “The multi-part identifier "Customer.BAccountID" could not be bound.”.  I’m assuming it’s a JOIN issue but I’m not seeing it.  The Trace shows the message and exception but not exactly which SQL operation is failing.

 

 


RohitRattan88
Acumatica Moderator
Forum|alt.badge.img+4
  • Acumatica Moderator
  • February 4, 2025

@bbohn Maybe consider adding CompanyID, DeletedDatabaseRecord and Audit Columns and test again for Deletion
Requirements for an Extension Table Schema


Forum|alt.badge.img
  • Author
  • Varsity II
  • February 4, 2025

@bbohn Maybe consider adding CompanyID, DeletedDatabaseRecord and Audit Columns and test again for Deletion
Requirements for an Extension Table Schema

Thanks, I have the CompanyID and DeletedDatabaseRecord fields defined already.  I excluded the standard audit fields as instructed and didn’t elect to rename them because they’re not needed.