Hi all,
I put together a small customization to make the **Sales Person** field
required on the Sales Order Lines grid (SO301000), since our process needs a
sales person on every line for commission tracking. I figured I'd share it
here in case it's useful to someone else, and also because I'm still fairly
new to Acumatica customization and would love a sanity check from people with
more experience.
The approach: since `SalesPersonID` already exists on `SOLine`, I used a
`CacheAttached` handler with `PXMergeAttributes(Method = MergeMethod.Merge)`
to add `Required = true` without redeclaring the field's other attributes,
plus a `RowPersisting` handler to actually block the save (since `Required`
alone only affects the UI).
Full code + explanation here: https://github.com/i-wild/acumatica-sales-person-required
```csharp
[PXMergeAttributes(Method = MergeMethod.Merge)]
[PXUIField(DisplayName = "Sales Person", Required = true)]
protected virtual void SOLine_SalesPersonID_CacheAttached(PXCache cache)
{
}
protected virtual void _(Events.RowPersisting<SOLine> e)
{
if (e.Row == null) return;
if (e.Operation == PXDBOperation.Delete) return;
if (e.Row.SalesPersonID == null)
{
e.Cache.RaiseExceptionHandling<SOLine.salesPersonID>(
e.Row, null,
new PXSetPropertyException("Sales Person is required.", PXErrorLevel.Error));
throw new PXRowPersistingException(
typeof(SOLine.salesPersonID).Name, null, "Sales Person is required.");
}
}
```
I'd genuinely welcome feedback on things like:
- Is `RowPersisting` the right event for this, or would a different one be more idiomatic for a "required across all lines" rule?
- Would this be better implemented as a Business Event / Workflow condition instead of code, so it's easier for non-developers to maintain later?
- Any edge cases I'm not considering — API-created orders, imports, mass processing, etc.?
I appreciate your responses and suggestions