Skip to main content
Question

Attach header files to Email via Email Purchase Order button; 2025R2

  • May 8, 2026
  • 3 replies
  • 22 views

bpickles
Freshman I

I have tried 20+ code variations and can’t seem to get this working.  Scoured here, stackoverflow and everything else I can find over the last month without a solution.  Some appeared to work in prior versions but not now.

 

As the title says; would like these files attached to the email when it sends:

 


Single code file I named POOrderEntry_Extension:
 

using PX.Data;
using PX.Objects.CR;
using PX.Objects.PO;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Customizations
{
[PXProtectedAccess]
public abstract class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
[PXProtectedAccess]
protected abstract IEnumerable Notification(PXAdapter adapter, string notificationCD);

public delegate IEnumerable NotificationDelegate(PXAdapter adapter, string notificationCD);

[PXOverride]
public IEnumerable Notification(PXAdapter adapter, string notificationCD, NotificationDelegate baseMethod)
{
IEnumerable result = baseMethod(adapter, notificationCD);

POOrder order = Base.Document.Current;
if (order?.NoteID == null)
return result;

CRSMEmail email = PXSelect<CRSMEmail,
Where<CRSMEmail.refNoteID, Equal<Required<CRSMEmail.refNoteID>>>>
.Select(Base, order.NoteID);

if (email == null)
return result;

var fileUids = PXNoteAttribute.GetFileNotes(Base.Document.Cache, order)?
.OfType<Guid>()
.ToArray();

if (fileUids != null && fileUids.Length > 0)
{
PXNoteAttribute.SetFileNotes(Base.Caches<CRSMEmail>(), email, fileUids);
Base.Caches<CRSMEmail>().Update(email);
}

return result;
}
}
}


Would think this would so difficult; in fact absolutely surprised it’s not just part of Acumatica as a preference setting, but it is what it is right now.

Any help or pointers would be greatly appreciated!

3 replies

darylbowman
Captain II
Forum|alt.badge.img+16

Without digging in real deep, I would suggest verifying PXProtectedAccess behavior. I’ve always created the protected access class as a second-order extension. Pretty sure that’s a requirement.

(docs)


bpickles
Freshman I
  • Author
  • Freshman I
  • May 9, 2026

Thanks ​@darylbowman ; gave me something else to look at.  Getting closer, this now almost works.

When the button is clicked the email is created and goes into pending processing; the files aren’t there, but if you cancel sending they immediately populate. Gather I’m injecting this this with the wrong timing.

using PX.Data;
using PX.Objects.CR;
using PX.Objects.PO;
using System;
using System.Linq;

namespace Customizations
{
public class CREmailActivityMaint_Extension
: PXGraphExtension<CREmailActivityMaint>
{
protected void _(Events.RowPersisting<CRSMEmail> e)
{
if (e.Row == null)
return;

// Only process PO-related emails
if (e.Row.RefNoteID == null)
return;

// Find related PO
POOrder order =
PXSelect<
POOrder,
Where<
POOrder.noteID,
Equal<Required<POOrder.noteID>>
>
>
.Select(Base, e.Row.RefNoteID);

if (order == null)
return;

// Get PO attached files
Guid[] poFiles =
PXNoteAttribute
.GetFileNotes(Base.Caches<POOrder>(), order)
?.ToArray();

if (poFiles == null || poFiles.Length == 0)
return;

// Existing email files
Guid[] emailFiles =
PXNoteAttribute
.GetFileNotes(e.Cache, e.Row)
?.ToArray()
?? new Guid[0];

// Merge without duplicates
Guid[] merged =
emailFiles
.Union(poFiles)
.Distinct()
.ToArray();

// Attach to email
PXNoteAttribute.SetFileNotes(
e.Cache,
e.Row,
merged);

// Force row dirty state
e.Cache.SetValueExt<CRSMEmail.subject>(
e.Row,
e.Row.Subject + "");

e.Cache.Update(e.Row);
}
}
}

 


darylbowman
Captain II
Forum|alt.badge.img+16

You could try overriding the persist method instead.