Photo capture is the mobile feature that looks trivial in a demo — tap camera icon, take photo, done — and then quietly becomes a storage and sync-bandwidth problem three months into production once field technicians are attaching multiple full-resolution photos per service call. This is what I've learned wiring photo attachments into Acumatica Mobile screens across a few field-service and warehouse-inspection projects.
Three different places a photo can end up
Acumatica Mobile screens can capture a photo into three genuinely different places, and picking the wrong one causes real downstream problems:
- Standard file attachment (NoteID-based). The photo becomes a regular file attachment on the record, exactly like any file uploaded from the browser's paperclip icon — visible in the Files tab, subject to the same access rights, retrievable via the standard attachment API. This is the right default for "evidence" photos: proof of delivery, damage documentation, before/after site photos.
- A dedicated custom image field on the DAC. A
PXDBLongStringor file-reference field on a specific DAC, used when exactly one photo per record has meaning as a first-class piece of data — a profile photo on an asset record, a single "primary" site photo shown inline on a screen rather than buried in an attachments list. - Embedded inline in a note or description field. Rare, and usually a mistake — I've had to unwind a couple of implementations where a previous developer stuffed base64 image data into a text field, which bloats every query against that DAC (the overfetch problem, in an especially painful form) and has no attachment-level access control.
For anything beyond a single "primary" image, standard NoteID-based attachments are almost always correct — they get the platform's existing attachment infrastructure (storage provider abstraction, access rights, retrieval API) for free.
Enabling camera capture on an attachment container
MSDL exposes a capture action on the attachment container that invokes the device's native camera rather than requiring the user to take a photo separately and then upload it as a generic file — this distinction matters a lot for field adoption, since a separate "open camera app, take photo, switch back to Acumatica, attach file" flow gets skipped constantly under time pressure, while an in-app capture button gets used:
<mobile>
<screen key="FS300100">
<container name="Attachments" type="files">
<capture source="camera" enabled="true" />
<capture source="library" enabled="true" />
</container>
</screen>
</mobile>
Full-resolution photos are a storage and sync problem you will hit
Modern phone cameras produce multi-megabyte images by default. A field technician attaching four or five photos per service call, multiplied across a team doing a dozen calls a day, adds up to real storage growth on your Acumatica instance's file storage — and on SaaS deployments, storage is a metered resource with real cost implications, not an afterthought. The fix isn't a policy asking technicians to resize photos manually (they won't); it's compressing on capture:
The mobile app's attachment capture settings support downscaling and compression before upload — set a sensible maximum dimension and JPEG quality for capture containers used for evidence photos rather than accepting full sensor resolution by default. Beyond storage, remember this is also a sync-bandwidth problem for offline-captured photos: several uncompressed photos queued while offline, syncing over a weak reconnect signal, is a realistic scenario in field-service and warehouse contexts, and compression at capture time directly reduces that sync burden too.
Server-side: don't assume every attachment made it, and validate what did
Because photo attachments captured offline queue and sync later (see the offline mode discussion), a graph's RowPersisting or completion logic that requires "at least one photo attached" needs to check for the attachment's actual presence at persist time, not assume the mobile UI enforced it — a technician can mark a job complete offline with the photo capture still queued, and if your business rule genuinely requires photographic evidence before completion, that check belongs server-side where it can't be bypassed by a UI quirk or a sync that hasn't happened yet:
protected virtual void _(Events.RowPersisting<FSAppointment> e)
{
var row = (FSAppointment)e.Row;
if (row?.Status != "C") return;
bool hasPhoto = PXNoteAttachedFiles.Select(Base, row.NoteID).Any();
if (!hasPhoto)
{
e.Cache.RaiseExceptionHandling<FSAppointment.status>(row, row.Status,
new PXSetPropertyException("At least one completion photo is required before closing this appointment."));
e.Cancel = true;
}
}
Retention policy is a conversation worth having explicitly
Nobody asks about attachment retention during scoping, and everybody asks about it eighteen months later when storage costs have crept up or a legal-hold requirement surfaces. Decide early, in the actual requirements conversation, whether evidence photos need indefinite retention (common for compliance-sensitive field service — proof of delivery disputes can surface a year later) or can be archived/purged after a defined period, and build that into the customization from the start rather than retrofitting a cleanup job onto years of accumulated full-resolution images later.
Wrapping up
Photo attachment capture on Acumatica Mobile is easy to wire up and easy to get subtly wrong in ways that only show up as cost or reliability problems months later: choose standard NoteID attachments over ad-hoc image fields for anything beyond a single primary image, compress on capture rather than trusting policy, validate photo presence server-side rather than trusting the offline UI enforced it, and settle retention policy during scoping rather than as an emergency cleanup project later.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.