Skip to main content
Question

How to extend PrepareImportRow in INPIEntry when it’s not virtual?

  • October 29, 2025
  • 13 replies
  • 85 views

I’m trying to modify the behaviour of the PrepareImportRow method in the INPIEntry graph to handle a custom field during import. The original method signature looks like this:

 

public bool PrepareImportRow(string viewName, IDictionary keys, IDictionary values)

 

I attempted to use a PXOverride as follows:

 

public delegate bool PrepareImportRowDelegate( string viewName, IDictionary keys, IDictionary values);

[PXOverride]

public bool PrepareImportRow( string viewName, IDictionary keys, IDictionary values, PrepareImportRowDelegate baseMethod) { // custom logic here }

 

However, I’m getting the following error:

Declaration referenced in a method implementation cannot be a final method. Type: 'Wrapper.PX.Objects.IN.Cst_INPIReview'. Assembly: 'INPIReview_Container, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.

PrepareImportRow in INPIEntry is not declared as virtual, which could be preventing the override.

Has anyone successfully extended or replaced this method or something similar which is not virtual? Do I maybe have something wrong in my override?
What are the correct options or workarounds to customize the PrepareImportRow behaviour in this case?

13 replies

Forum|alt.badge.img+8
  • Captain II
  • October 29, 2025

I think you should declare it as

public override bool PrepareImportRow(string viewName, IDictionary keys, IDictionary values)
{
//Your custom logic here.

bool result = base.PrepareImportRow(viewName, keys, values);

//or here.
}

 


  • Author
  • Freshman I
  • October 29, 2025

@aiwan -

Thank you for your reply and for taking the time to suggest that approach. Unfortunately, that won’t work in my case because I’m implementing the logic within a graph extension, not by inheriting directly from the base graph.

 


Forum|alt.badge.img+8
  • Captain II
  • October 29, 2025

if you change base to Base that should work the same way.


Forum|alt.badge.img+1

Hi ​@Joseph Cauana 

  1. PXOverride requires the base method to be virtual
  2. PrepareImportRow in the base class is not marked as virtual
  3. Acumatica's framework doesn't allow overriding non-virtual methods through extensions

Therefore, you are unlikely to be able to override the method.
But you can try a few other workarounds: 

Option 1: Event Handler Approach
instead of overriding the method, subscribe to the appropriate event that occurs before/after PrepareImportRow is called:
 

    public class INPIEntryExt : PXGraphExtension<INPIEntry>
{
public override void Initialize()
{
base.Initialize();
// Subscribe to events that occur during the import process
Base.RowInserting.AddHandler<INPIHeader>((sender, e) =>
{
// Custom logic before row is inserted
if (e.Row is INPIHeader row)
{
HandleCustomField(row);
}
});

Base.RowUpdating.AddHandler<INPIHeader>((sender, e) =>
{
// Custom logic before row is updated
if (e.Row is INPIHeader row)
{
HandleCustomField(row);
}
});
}

protected virtual void HandleCustomField(INPIHeader row)
{
// Your custom field logic here
if (row != null)
{
// Process your custom field
}
}
}

or like this: 
 

public class INPIEntryExt : PXGraphExtension<INPIEntry>
{
protected virtual void _(Events.RowInserting<INPIHeader> e, PXRowInserting baseHandler)
{
baseHandler?.Invoke(e.Cache, e.Args);
if (e.Row is not INPIHeader row) return;
// Your custom logic here
}

protected virtual void _(Events.RowUpdating<INPIHeader> e, PXRowUpdating baseHandler)
{
baseHandler?.Invoke(e.Cache, e.Args);
if (e.Row is not INPIHeader row) return;
// Your custom logic here
}
}

You can also try using event handlers 

  • FieldDefaulting
  • FieldUpdating
  • FieldVerifying

for fields whose values need to be changed during import.


  • Author
  • Freshman I
  • October 29, 2025

@aiwan  Sorry, I was not clear. The problem is with the override keyword in the  method declaration. 


  • Author
  • Freshman I
  • October 29, 2025

Hi ​@aleksejslusar19 -

Thanks for your feedback and for sharing the code samples.

The challenge I see with that approach is that I need access to the data coming from the Excel import. One of the columns in the uploaded Excel file corresponds to my custom field, but in Acumatica’s implementation of PrepareImportRow, it explicitly selects which fields to import — and as a result, it skips my custom field entirely.

From what I can tell, the PrepareImportRow method receives a Dictionary of values that should include all the imported data (including my column). However, since Acumatica’s logic does not include my custom field, its value never gets included.

With the approach you mentioned, is there still a way to access the value of that custom field from the Excel import, even though it’s not part of the hard-coded import field mappings in Acumatica PrepareImportRow?


Forum|alt.badge.img+1

@Joseph Cauana
Is this custom field visible on the screen or not?


  • Author
  • Freshman I
  • October 29, 2025

@aleksejslusar19

Yes, it is. But I think the issue lies in how the PrepareImportRow method is implemented. In Acumatica’s code, this method updates specific fields directly through the cache and then disables the rest of the standard import process.

Essentially, the method takes full control of the import logic and explicitly defines which fields are imported and how they’re handled. That’s why my custom field is being skipped. You can see this behaviour in the INPIEntry code.


Forum|alt.badge.img+1

@Joseph Cauana 

You can also try to implement the interface on the graph extension.

Like this:

    public class INPIEntryExt : PXGraphExtension<INPIEntry>, PXImportAttribute.IPXPrepareItems
{
public bool PrepareImportRow(string viewName, IDictionary keys, IDictionary values)
{
// Your custom logic here
return true;
}

public void PrepareItems(string viewName, IEnumerable items)
{
// Your custom logic here
}

public bool RowImported(string viewName, object row, object oldRow)
{
// Your custom logic here
return true;
}

public bool RowImporting(string viewName, object row)
{
// Your custom logic here
return true;
}

}

 


  • Author
  • Freshman I
  • October 29, 2025

@aleksejslusar19 , thanks for the suggestion. Tried it, but no luck - it just get’s ignored and it only considers what is in the Base Acumatica Graph.


Forum|alt.badge.img+1

The documentation for the PXImportAttribute attribute also says the following:

 

//     You can control all stages of data import if you make sure that the graph implements
//     the following interfaces: PX.Data.PXImportAttribute.IPrepare, PX.Data.PXImportAttribute.IImport
//     and PX.Data.PXImportAttribute.IConfirm.

 

I would try them all until I get the result I need.


Forum|alt.badge.img+1

Sometimes the best solution is to contact Acumatica support with the problem.😎


Chris Hackett
Community Manager
Forum|alt.badge.img
  • Acumatica Community Manager
  • November 6, 2025

Hi ​@Joseph Cauana were you able to find a solution? Thank you!