Acumatica · Customization

Acumatica Customer Screen — A Deep Dive

Acumatica Customer Screen — A Deep Dive is the screen the user actually lives in. Every other piece of Acumatica — the workflows, the reports, the integrations — exists to feed.

John Kihiu12 min read

The Customers screen (AR303000) is where a lot of first-time Acumatica developers get their first real surprise: the record you're editing isn't really a "Customer," it's a BAccount row wearing a Customer-shaped extension. Customer itself is a projection/extension of BAccount that adds the AR-specific fields — credit terms, statement cycle, tax settings — while shared identity fields (name, addresses, contacts) live on the base account. Vendors, Employees, and CRM Business Accounts all share that same underlying table.

BAccount, Customer, and CustomerClass

Most of what looks configurable on the Customer screen is actually inherited from CustomerClass at creation time — payment terms, statement cycle, price class, and default GL accounts for AR all come from the class unless overridden per customer. That inheritance only happens once, on creation; changing a CustomerClass later doesn't retroactively update existing customers, which is the single most common "why didn't my class change take effect" support ticket on this screen.

Key tabs

Extending CustomerMaint

Because Customer sits on top of BAccount, a graph extension against CustomerMaint usually needs to decide whether a new field belongs on the Customer extension or the base BAccount — the difference matters if the same field should also show up for Vendors or CRM Business Accounts sharing the same underlying record. A field that's genuinely AR-specific (a custom collections tier, say) belongs on the Customer extension; anything about the entity's identity belongs on BAccount.

C# · DAC EXTENSION
public class CustomerExt : PXCacheExtension<Customer>
{
    [PXDBString(1, IsFixed = true)]
    [PXDefault("A")]
    [PXStringList(new[] { "A", "B", "C" }, new[] { "Tier A", "Tier B", "Tier C" })]
    public virtual string UsrCollectionsTier { get; set; }
    public abstract class usrCollectionsTier : BqlField { }
}

Custom fields and tabs via the Customization Project Editor

Adding a field to Financial or General Info is standard. A whole new tab is more common on this screen than most, because Customer data is frequently the anchor for cross-module reporting (a "Sales Territory" tab, a custom "Onboarding" tab) — that's a related DAC keyed on BAccountID plus a PXTab in the graph extension, not something that fits cleanly as a field addition.

Common validation and event-handler use cases

The recurring asks: enforcing a custom credit-limit override workflow before a customer can be set to "Active" from "Prospect," syncing a custom field to every open Sales Order when it changes on the Customer (so in-flight orders reflect updated terms), and restricting which CustomerClass values a given role can select via a value-restriction on the field rather than a full permission redesign. All of these are RowSelected/RowUpdated handlers on the Customer graph extension.

Gotchas

Deactivating a customer (status = Inactive) doesn't stop existing open documents from referencing it, and doesn't hide it from historical reports — only from new-document lookups. The "one BAccount, many roles" model means a customer that later needs a Vendor record (a customer who's also a supplier) isn't a data-entry problem to solve on this screen; Acumatica's cross-reference for that is a distinct feature, not a field you add yourself. And restriction groups on BAccount, if enabled, apply per-user rather than per-role by default, which catches teams that designed their security model entirely around roles.

Test class changes against new records only

A change to CustomerClass defaults will not touch existing customers. If a customization needs to propagate a changed default to existing records, that has to be an explicit mass-update action — Acumatica won't do it for you on save.

Wrapping up

Treat the Customer screen as a view onto BAccount, not a standalone entity, and most of its quirks stop being surprising. Decide early whether a customization belongs on the shared account or the AR-specific extension — that one choice determines whether it also has to work correctly for Vendors and CRM accounts sharing the same row.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.