A field services client asked for something that sounded simple: "tag every service call with GPS coordinates when the technician marks it complete, so we can prove the technician was actually on site." Geolocation capture on Acumatica Mobile is genuinely straightforward to wire up mechanically. The part that takes real design thinking is everything around it — accuracy expectations, what happens without signal, and the fact that "prove someone was on site" is a claim with legal weight that a sloppy implementation can't actually support.
Wiring a location field into a mobile screen
Geolocation on Acumatica Mobile is exposed through a device capability container in the MSDL patch, backed by two decimal DAC fields (latitude and longitude) plus, in most implementations I build, a timestamp and an accuracy-radius field alongside them:
public sealed class FSAppointmentExt : PXCacheExtension<FSAppointment>
{
public static bool IsActive() => true;
[PXDBDecimal(6)]
[PXUIField(DisplayName = "Capture Latitude")]
public decimal? UsrCaptureLat { get; set; }
public abstract class usrCaptureLat : PX.Data.BQL.BqlDecimal.Field<usrCaptureLat> { }
[PXDBDecimal(6)]
[PXUIField(DisplayName = "Capture Longitude")]
public decimal? UsrCaptureLng { get; set; }
public abstract class usrCaptureLng : PX.Data.BQL.BqlDecimal.Field<usrCaptureLng> { }
[PXDBDecimal(1)]
[PXUIField(DisplayName = "Accuracy (m)")]
public decimal? UsrCaptureAccuracy { get; set; }
public abstract class usrCaptureAccuracy : PX.Data.BQL.BqlDecimal.Field<usrCaptureAccuracy> { }
}
<mobile>
<screen key="FS300100">
<container name="Header">
<field name="UsrCaptureLat" geolocation="true" role="latitude" />
<field name="UsrCaptureLng" geolocation="true" role="longitude" />
</container>
</screen>
</mobile>
The mobile app requests the device's location through its native OS permission prompt (which the user must have granted for the app), and populates the mapped fields on capture. Decimal(6) precision on latitude/longitude is deliberate — six decimal places resolves to roughly 10cm, which is more precision than consumer GPS actually delivers but avoids being the bottleneck; storing fewer decimal places measurably degrades usable accuracy.
Capture accuracy alongside the coordinates, not just the coordinates
The single biggest mistake in geolocation implementations I've reviewed: storing latitude and longitude without also storing the device-reported accuracy radius. Consumer GPS accuracy varies wildly — 5 meters in open sky, 50+ meters between tall buildings or indoors, sometimes far worse on older devices or with location services degraded to save battery. A coordinate pair with no accuracy figure attached is a claim you can't actually stand behind if a client ever disputes "was the technician on site." Capturing the accuracy value the OS reports alongside the coordinates, and surfacing it downstream (a GI flagging captures above a threshold as "low confidence"), is what makes the feature legally and operationally useful rather than just a pin on a map nobody trusts.
GPS itself works without a network connection — a device with no signal can still resolve coordinates from satellites, though it takes longer without assisted-GPS data from a cell network. Don't gate geolocation capture behind "online" checks in your mobile screen logic; the coordinates should capture and queue locally like any other offline field, syncing to the server once connectivity returns. Conflating "no network" with "no GPS" is a common design mistake that strips the feature of its value in exactly the low-connectivity field scenarios it's usually built for.
Validate distance server-side, not just capture it
If the business requirement is genuinely "prove the technician was near the customer site," raw coordinate storage alone doesn't satisfy it — you need a server-side comparison against the customer's registered address coordinates, computed on RowPersisting when the appointment is marked complete:
protected virtual void _(Events.RowPersisting<FSAppointment> e)
{
var row = (FSAppointment)e.Row;
var ext = row?.GetExtension<FSAppointmentExt>();
if (row == null || row.Status != "C" || ext?.UsrCaptureLat == null) return;
var siteCoords = GetSiteCoordinates(row.LocationID); // your own lookup
var distanceMeters = HaversineDistance(
(double)ext.UsrCaptureLat.Value, (double)ext.UsrCaptureLng.Value,
siteCoords.Lat, siteCoords.Lng);
if (distanceMeters > 500) // configurable per business
{
ext.UsrLocationFlag = "OUT_OF_RANGE"; // flag, don't silently block —
// a legitimate reason (customer met tech at gate, poor GPS fix)
// is common enough that hard-blocking the save creates support tickets
}
}
I flag rather than hard-block in almost every implementation, because GPS drift and legitimate off-site meetings are common enough that a hard block turns into a stream of support tickets from technicians who did nothing wrong. Flag for review, let a supervisor clear exceptions, and reserve hard blocking for cases with a genuinely zero-tolerance business reason.
Battery and privacy considerations that come up in every rollout
Continuous background location tracking is a different feature entirely from point-in-time capture, with materially different privacy, battery, and (in some jurisdictions) legal-consent implications for tracking employees. Every geolocation feature I scope explicitly confirms with the client whether they want point-in-time capture (attached to a specific action — appointment start, appointment complete) or continuous tracking, because clients sometimes ask for the former using language that describes the latter, and the two are not remotely the same undertaking.
Wrapping up
Geolocation capture on Acumatica Mobile is a short MSDL patch and two or three decimal fields mechanically — the design work is in capturing accuracy alongside coordinates so the data means something, treating GPS as available offline even without network connectivity, and validating distance server-side with a flag-not-block posture unless the business genuinely needs a hard rule. Scope point-in-time capture versus continuous tracking explicitly; they are different features with different implications, even though clients often describe them with the same sentence.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.