Skip to main content
Question

How to filter Prepare Payments (AP503000) using status from an external async API without storing the status?

  • September 1, 2026
  • 1 reply
  • 64 views

Hello 
 

I am customizing the Pay Bills screen and overriding the apdocumentlist delegate.

My requirement is:

  • When a specific Payment Method is selected
  • Only show AP Bills whose corresponding invoice in an external system has status Pending 
  • The external invoice ID is already stored on APInvoice in a custom field such as UsrExternalInvoiceId
  • I cannot store the external invoice status on APInvoice or in another database table

My current view override is similar to:
 

public delegate IEnumerable APDocumentListDelegate();

[PXOverride]
public IEnumerable apdocumentlist(APDocumentListDelegate baseMethod)
{
IEnumerable baseResult = baseMethod();

PayBillsFilter filter = Base.Filter.Current;

if (filter == null ||
!string.Equals(
filter.PayTypeID,
ExternalPaymentMethodID,
StringComparison.OrdinalIgnoreCase))
{
return baseResult;
}

var filtered = new PXDelegateResult();

foreach (object row in baseResult)
{

if (invoice == null)
continue;

APInvoiceExt ext =
PXCache<APInvoice>.GetExtension<APInvoiceExt>(invoice);


string externalInvoiceId =
ext?.UsrExternalInvoiceId?.Trim();

if (string.IsNullOrEmpty(externalInvoiceId))
continue;

// Need to retrieve the current invoice status from the external system here.

// Only add the AP Bill if the external status is "Pending".
}

return filtered;
}

The external API method is asynchronous:

string response = await service.SearchInvoices(
payerId,
invoiceNumber: externalInvoiceId);

I do not want to use:

.GetAwaiter().GetResult()

or:

Task.Run(...)

to block the request.

Normally, for external API calls in Acumatica, I would use:

Base.LongOperationManager.StartAsyncOperation(
cancellationToken =>
SomeAsyncMethod(cancellationToken));

However, apdocumentlist is a synchronous IEnumerable delegate and needs the external API result immediately in order to decide whether each AP Bill should be returned.

Also, starting a long operation directly from a data view delegate does not appear to be the correct pattern as I understand.
 

Question

What is the recommended pattern approach for this scenario?

Specifically:

How should an asynchronous external API call be used when the result is required to filter a synchronous data view such as apdocumentlist?

 

The goal is simply:

APInvoice.UsrExternalInvoiceId

Call External API

Get current invoiceStatus

If status == "Pending"

Show bill on the grid

Could you please advise on the correct approach and share an example if possible? Please also correct me if my understanding is incorrect.

1 reply

Forum|alt.badge.img+5
  • Jr Varsity II
  • September 2, 2026

Hi ​@vishalr53 ,

Can you try below recommendation-

Instead of trying to fetch the external status inside the data view delegate as the grid loads, you should separate the fetching of data from the rendering of data.

1. Create a custom Action (Button) to Fetch Data: Add a button to the screen (e.g., "Load External Bills" or "Refresh Statuses"). When the user selects the Payment Method and clicks this button, start a PXLongOperation.

2. Fetch Data Asynchronously: Inside the PXLongOperation, gather all the UsrExternalInvoiceIds for the current filter. Make one asynchronous API call (if your API supports bulk fetching) or multiple concurrent asynchronous calls to get the statuses for all relevant invoices at once.

3. Store Statuses Temporarily (In-Memory): Store the retrieved statuses in a Dictionary<string, string> (ExternalInvoiceId -> Status). You can save this dictionary in a custom Graph Extension property (using PXContext.Session or standard Graph state if applicable) or save the statuses into an Unbound Custom Field (PXUnboundDefault) on the APInvoice cache.

4. Filter the Delegate Synchronously: Finally, in your apdocumentlist delegate, simply check the in-memory dictionary or the unbound field. Because the data is already in memory, the delegate remains fast and completely synchronous.

Hope above helps!!