Skip to main content
Answer

how to attach a pdf to a record using code

  • February 28, 2024
  • 8 replies
  • 185 views

graphically it can be done this way 

but I need to bring the pdf file from a local path and then upload it through code

Best answer by VardanV

Change your code by the following example:

public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
public static bool IsActive() => true;

public PXAction<SOShipment> ApiTracking;

[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Tracking")]
public IEnumerable apiTracking(PXAdapter adapter)
{
string filePath = @"C:\Path\To\DownloadedFiles\downloadedFile4.pdf";
if (File.Exists(filePath))// Check if the file exists at the specified path
{
List<SOShipment> shipmentList = adapter.Get<SOShipment>().ToList();
PXLongOperation.StartOperation(this.Base.UID, delegate ()
{
SOShipmentEntry shipmentEntry = PXGraph.CreateInstance<SOShipmentEntry>();
UploadFileMaintenance upl = PXGraph.CreateInstance<UploadFileMaintenance>();
foreach (SOShipment shipment in shipmentList)
{
shipmentEntry.Clear();
shipmentEntry.Document.Current = shipmentEntry.Document.Search<SOShipment.shipmentNbr>(shipment.ShipmentNbr);
// Create a FileInfo object for the PDF file
PX.SM.FileInfo fileinfo = new PX.SM.FileInfo($"{Path.GetFileNameWithoutExtension(filePath)}.pdf", null, File.ReadAllBytes(filePath));
if (upl.SaveFile(fileinfo, FileExistsAction.CreateVersion))
{
PXNoteAttribute.SetFileNotes(shipmentEntry.Document.Cache, shipmentEntry.Document.Current, fileinfo.UID.Value);
shipmentEntry.Save.Press();
}
}
});
}
else
{
// Handle the case where the file is not found at the specified path
PXTrace.WriteWarning($"PDF file not found at path: {filePath}");
}
return adapter.Get();
}
}

You need make sure that file path is accessible for read action.

8 replies

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

Local to the server or local to the user?


 local to the user


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

I could be wrong, but I don’t believe code running server side will be able to accomplish this. Aside from possibly using JavaScript (I cannot confirm this), I don’t think you will be able to accomplish this without having the user choose a file.

That’s not to say you can’t go about it in a different way than what you’ve snipped above. Just that you’ll need to do something similar. I have a feeling this is not what you were hoping though.


Maybe I didn't realize the pdf file is located in this path @"C:\Ruta\Directory\ArchivosDescargados\archivoDescargado4.pdf" in graphic form it is done in acumatics as the image shows

Then the file is attached on the next screen.

What I want is to obtain from the code the pdf that is in this path @"C:\Ruta\Directorio\ArchivosDescargados\archivoDescargado4.pdf" I found an example but I couldn't make it work, I leave you the link to see what you think and give me your suggestion

https://help-2020r1.acumatica.com/Help?ScreenId=ShowWiki&pageid=591def3d-5fe5-42c1-bb35-cfe5b4c77f6f


I have the following code:

 

namespace PX.Objects.SO
{
    public class SOShipmentEntry_Extension : PXGraphExtension<SOShipmentEntry>
    {
        #region Event Handlers

        public PXAction<PX.Objects.SO.SOShipment> ApiTracking;

        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Tracking")]
        protected void apiTracking()
        {
            PXTrace.WriteWarning("PROCESSING 1");

            // Create a BQL command to select SO shipments
            BqlCommand command = new Select<SOShipment>();

            // Create a view for querying SO shipments
            PXView shipmentView = new PXView(Base, true, command);

            // Create a PXAdapter adapter with the shipments view
            PXAdapter adapter = new PXAdapter(shipmentView);

            foreach (SOShipment shipment in adapter.Get<SOShipment>())
            {
                PXTrace.WriteWarning("PROCESSING 2");

                // Get the path of the pre-existing PDF file
                string filePath = @"C:\Path\To\DownloadedFiles\downloadedFile4.pdf";

                // Check if the file exists at the specified path
                if (File.Exists(filePath))
                {
                    PXTrace.WriteWarning("PROCESSING 3");

                    // Create a FileInfo object for the PDF file
                    PX.SM.FileInfo file = new PX.SM.FileInfo(filePath, null, File.ReadAllBytes(filePath));

                    // Check that the objects are not null before calling AttachFile
                    if (Base.Caches[typeof(SOShipment)] != null && shipment != null && file != null)
                    {
                        try
                        {
                            PXTrace.WriteWarning("PROCESSING 4");

                            // Attach the PDF file to the current shipment
                            PXNoteAttribute.AttachFile(Base.Caches[typeof(SOShipment)], shipment, file);

                            PXTrace.WriteWarning("PROCESSING 5");
                        }
                        catch (Exception ex)
                        {
                            // Handle any exception that occurs during AttachFile
                            PXTrace.WriteError($"Error attaching PDF file: {ex.Message}");
                        }
                    }
                    else
                    {
                        // Handle the case where any object is null
                        PXTrace.WriteWarning("Error: One of the required objects is null.");
                    }
                }
                else
                {
                    // Handle the case where the file is not found at the specified path
                    PXTrace.WriteWarning($"PDF file not found at path: {filePath}");
                }
            }
        }
    }
}


but I get an error in this part of the code
  // Attach the PDF file to the current shipment PXNoteAttribute.AttachFile(Base.Caches[typeof(SOShipment)], shipment, file);

The messages shown reach PROCESSING 4 and then show the error
the mistake is :
Error attaching PDF file: Nullable object must have a value.

 


VardanV
Jr Varsity III
Forum|alt.badge.img+1
  • Jr Varsity III
  • Answer
  • February 29, 2024

Change your code by the following example:

public class SOShipmentEntryExt : PXGraphExtension<SOShipmentEntry>
{
public static bool IsActive() => true;

public PXAction<SOShipment> ApiTracking;

[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Tracking")]
public IEnumerable apiTracking(PXAdapter adapter)
{
string filePath = @"C:\Path\To\DownloadedFiles\downloadedFile4.pdf";
if (File.Exists(filePath))// Check if the file exists at the specified path
{
List<SOShipment> shipmentList = adapter.Get<SOShipment>().ToList();
PXLongOperation.StartOperation(this.Base.UID, delegate ()
{
SOShipmentEntry shipmentEntry = PXGraph.CreateInstance<SOShipmentEntry>();
UploadFileMaintenance upl = PXGraph.CreateInstance<UploadFileMaintenance>();
foreach (SOShipment shipment in shipmentList)
{
shipmentEntry.Clear();
shipmentEntry.Document.Current = shipmentEntry.Document.Search<SOShipment.shipmentNbr>(shipment.ShipmentNbr);
// Create a FileInfo object for the PDF file
PX.SM.FileInfo fileinfo = new PX.SM.FileInfo($"{Path.GetFileNameWithoutExtension(filePath)}.pdf", null, File.ReadAllBytes(filePath));
if (upl.SaveFile(fileinfo, FileExistsAction.CreateVersion))
{
PXNoteAttribute.SetFileNotes(shipmentEntry.Document.Cache, shipmentEntry.Document.Current, fileinfo.UID.Value);
shipmentEntry.Save.Press();
}
}
});
}
else
{
// Handle the case where the file is not found at the specified path
PXTrace.WriteWarning($"PDF file not found at path: {filePath}");
}
return adapter.Get();
}
}

You need make sure that file path is accessible for read action.


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

@vardan22 - But the whole point here is that he's writing server side code attempting to access a file client side. I don't see how that's going to work. I don't think the file will ever be found.


Related to the topic, I have the following code, but this time I try to obtain the pdf from an api, and save it in Shipment, I show you the code and the error that appears:

[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Track")]

protected void apiTracking()
{
    DownloadAndUploadFile();
}


public void DownloadAndUploadFile()
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            string url = "http://qaglp.paquetexpress.mx:8083/wsReportPaquetexpress/GenCartaPorte?trackingNoGen=19167736449";
            HttpResponseMessage queryResult = client.GetAsync(url).Result;

            if (queryResult.IsSuccessStatusCode)
            {
                byte[] fileContent = queryResult.Content.ReadAsByteArrayAsync().Result;

                UploadFile(fileContent, "downloadedFile55.pdf");
            }
            else
            {
                PXTrace.WriteWarning("HTTP request was not successful.");
            }
        }
    }
    catch (Exception ex)
    {
        PXTrace.WriteWarning("An exception occurred: " + ex.Message);
    }
}


private void UploadFile(byte[] file, string fileName)
{
    try
    {
        // Create an instance of PX.SM.UploadFileMaintenance
        PX.SM.UploadFileMaintenance uploadFileMaintenanceGraph = PXGraph.CreateInstance<PX.SM.UploadFileMaintenance>();

        // Create a FileInfo object for the file
        PX.SM.FileInfo fileInfo = new PX.SM.FileInfo(fileName, null, file);

        // Save the file
        if (uploadFileMaintenanceGraph.SaveFile(fileInfo, PX.SM.FileExistsAction.CreateVersion))
        {
            PXTrace.WriteInformation("File uploaded successfully.");

            // Associate the file with each shipment
            foreach (SOShipment shipment in Base.Document.Select().RowCast<SOShipment>().ToList())
            {
                // Upload the file and associate it with the shipment
                uploadFileMaintenanceGraph.SaveFile(fileInfo, PX.SM.FileExistsAction.CreateVersion);
                uploadFileMaintenanceGraph.AttachFile(typeof(SOShipment).FullName, shipment.ShipmentNbr, fileInfo);
            }
        }
        else
        {
            PXTrace.WriteWarning("Error uploading the file.");
        }
    }
    catch (Exception ex)
    {
        PXTrace.WriteWarning("An exception occurred: " + ex.Message);
    }
}
and I get this error:

[2024-03-05 18:21:11.673] \App_RuntimeCode\SOShipmentEntry.cs(164): error CS1061: 'UploadFileMaintenance' does not contain a definition for 'AttachFile' and no accessible extension method 'AttachFile' accepting a first argument of type 'UploadFileMaintenance' could be found (are you missing a using directive or an assembly reference?)