Expense claims sit at the intersection of employee self-service and AP — the claim itself is submitted by an employee, but once approved it needs to become something AP and GL can post, which is where most expense claim customizations actually live.
Core DACs and screens
An expense claim is built from a header/detail pair, commonly EPExpenseClaim and EPExpenseClaimDetails, entered through a screen in the EP number range (around EP301020) and backed by an entry graph such as EPExpenseClaimEntry. Each claim line references an expense category (mapped to a GL account and, often, a project/task if the claim is billable), and on approval the claim generates AP or GL transactions depending on whether it reimburses the employee through AP or nets against a corporate card liability account.
Extension points
Policy validation is the most common customization: per diem limits, receipt-required thresholds, category-specific spending caps. These are best implemented as RowPersisting or field-level validation on the claim detail DAC, checked against a configurable policy table rather than hardcoded thresholds, since expense policy tends to change more often than code deployment cycles allow for.
If the policy requires a receipt attachment above a dollar threshold, validating it only at the approver's review step means the approver is the one who discovers missing documentation — after the employee has already moved on. Enforce the check at claim submission (blocking the submit action, not the save) so the employee is the one prompted to attach it.
A realistic scenario: project-billable expense routing
A frequent customization: when an expense line is tagged against a project task, it needs to flow into the project's billing engine as a billable cost rather than (or in addition to) the standard AP/GL posting — useful for consulting or field-service businesses that rebill travel and materials to the client.
public class ExpenseClaimEntry_ProjectBillable_Extension : PXGraphExtension<EPExpenseClaimEntry>
{
protected virtual void EPExpenseClaimDetails_RowPersisting(PXCache sender, PXRowPersistingEventArgs e)
{
var line = (EPExpenseClaimDetails)e.Row;
if (line == null || line.ProjectID == null || line.TaskID == null) return;
if (line.Billable == true && string.IsNullOrEmpty(line.BillingRuleID))
{
sender.RaiseExceptionHandling<EPExpenseClaimDetails.billingRuleID>(line, line.BillingRuleID,
new PXSetPropertyException("A billing rule is required for expense lines marked billable to a project.", PXErrorLevel.Error));
}
}
}
Field names on the expense claim detail DAC (particularly around project billing linkage) vary by version and whether Projects module integration is enabled — verify against the target instance before assuming ProjectID/TaskID/Billable line up exactly as named here.
Multi-currency travel expenses
Employees traveling internationally submit receipts in foreign currencies, and the claim needs to convert to the employee's reimbursement currency using the correct rate type and date — usually the transaction date on the receipt, not the claim submission date. A customization that defaults the rate from the claim's header currency setting rather than each line's actual expense date will misprice claims with receipts spanning a multi-day trip across a rate change.
Testing considerations
Test a claim with a mix of billable and non-billable lines, at least one foreign-currency receipt, and a rejection-and-resubmission cycle — expense claim customizations are frequently only tested through a single clean approval path and never through a rejected claim being corrected and resubmitted, which exercises a different set of status transitions.
Wrapping up
Expense claim customization is really AP and Projects integration wearing a self-service front end. Keep policy thresholds configurable, enforce documentation requirements at submission rather than approval, and confirm project-billing field names against the specific version before building on them.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.