Solved

Problem with downloading attachment from cloud programmatically


Userlevel 7
Badge +8

Hello All,

 

I have a customization that programmatically downloads the attachments to a local folder “C:\Temp”. It works fine on my local environment but when I publish it to the cloud it doesn’t download to the expected path. In fact, it shows the process is completed successfully but I guess it uses the server’s local path instead of the user’s local machine. Any idea how I can fix this?

icon

Best answer by AaronB 2 August 2023, 17:10

View original

18 replies

Userlevel 7
Badge +8

@zfebert56 @Yuriy Zaletskyy any help is appreciated

Here is the partial code related to this issue 

 

// some code
PX.SM.FileInfo sourceFile = uploadGraph.GetFile(fileID);

// Some codes to get the targetFile name which is something like @"C:\\Temp\\ACU\\Test.pdf"
System.IO.File.WriteAllBytes(targetFile, sourceFile.BinData);

 

Badge +11

Have you seen this?

 

I believe you will be somewhat restricted in what you can do, since you are downloading a file from a website.

Userlevel 6
Badge +3

Hi @aaghaei,

Your code runs on the server, so you save your files on the server’s temp folder.

If you want to save it on the user computer, you have to do it through the browser, using

throw new PXRedirectToFileException(sourceFile, true);

and it will save the file to the download folder.

Userlevel 7
Badge +8

@darylbowman thanks for chiming in.

@zfebert56 thanks for the reply. I have tried this from your reply to another post but it is not working for me. I guess because mine is a processing screen that downloads multiple attachments as per the defined filters by user. Seems when the first file exception is thrown the process breaks.

Any thoughts how to overcome this?

Userlevel 7
Badge +8

@smarenich @Dmitrii Naumov @Brian Stevens @Yuriy Zaletskyy @Dioris Aguilar  @zfebert56 

sorry to bug you, Gents. Any help is appreciated.

 

namespace MyTest
{
public class MyFileInq : PXGraph<MyFileInq>
{
public SelectFrom<UploadFile>.View Files;

public static void DownloadFile(List<UploadFile> downloadList, bool isMassProcess = false)
{
var target = PXGraph.CreateInstance<MyFileInq>();

for (int i = 0; i < downloadList.Count; i++)
{
if (downloadList[i] == null) continue;
UploadFile file = downloadList[i];

try
{
target.Clear();
target.Files.Current = file;

UploadFileMaintenance uploadGraph = PXGraph.CreateInstance<UploadFileMaintenance>();
Guid fileID = (Guid)file.FileID;
PX.SM.FileInfo sourceFile = uploadGraph.GetFile(fileID);

if (sourceFile.BinData != null)
{
//File.WriteAllBytes("C:\\TEMP\\test.pdf", sourceFile.BinData);
//PXTrace.WriteInformation(targetFile);

//throw new PXRedirectToFileException(new PX.SM.FileInfo("test.pdf", null, sourceFile.BinData), true);
throw new PXRedirectToFileException(sourceFile, true);
}

if (isMassProcess == true)
{
PXProcessing<UploadFile>.SetInfo(i, string.Format("{0}", file.Name));
}
}

catch (Exception e)
{
PXProcessing<UploadFile>.SetError(i, e);
}

finally
{

}
}
}
}
}

 

Userlevel 5
Badge +3

It has nothing to do with code then, but with permissions. In that case, you need to open support case through the customer, and discuss permissions, which your service may have. As additional option, you can consider upload into database.

Badge +11

It has nothing to do with code then, but with permissions...

@Yuriy Zaletskyy - I’m confused. I think it’s pretty standard Acumatica functionality to break out of a process when an exception of any kind is thrown. I remember trying to download multiple reports at a time and running into a similar situation. In that case, I used a method which combined several report exceptions into one which was thrown at the end, but I don’t think there is anything like that for URLs / files.

Am I missing something?

Userlevel 7
Badge +5

@aaghaei  @darylbowman is right.

it’s pretty standard Acumatica functionality to break out of a process when an exception of any kind is thrown. I remember trying to download multiple reports at a time and running into a similar situation. In that case, I used a method which combined several report exceptions into one which was thrown at the end

That should be the way to do it. 

I recommend packing it all in zip in code and download all at once as a zip in the end.

Userlevel 7
Badge +8

Thank you @Yuriy Zaletskyy @darylbowman @Dmitrii Naumov for the responses.

The reason I initially developed the code using WriteAllBytes() method (commented code above) was to avoid throwing exceptions. Then I thought maybe forceDownlload = true parameter of the FileException from @zfebert56 reply somehow bypasses the error and allows platform resume. 

Doe’s anyone have a working sample code to help me how to zip all attachments in a zip file then download please?

 

Considering the attachments could be all types of files, merging to pdf will scope out some of the attachments if I am to combine the attachments into one pdf but if it come to it, again does anyone  have a working sample to share please?

 

Any help is appreciated.

Badge +11

Have a look-see here or here

Userlevel 7
Badge +8

@darylbowman either I am missing something or ZipArchive has been removed from PX.Common.Std.dll as the compiler cant recognize the method.

ZipArchive zipArchive = ZipArchive.CreateFrom(zipStream, false);
Userlevel 6
Badge +3

You need to reference System.IO.Compression in your csproj file.

Userlevel 7
Badge +8

hi @zfebert56 Thanks for the response. I have the references

 

Userlevel 6
Badge +3

Try to use this:

ZipArchive zipArchive = new ZipArchive(zipStream);

 

Userlevel 4
Badge +1

Hi,
I have this example to upload multiple PDF’s to a single .zip download inside Acumatica.

It stores the file(s) in a byte[] array then outputs the file as a file download in Acumatica via PXRedirectToFileException

using (var ms = new MemoryStream())

{

using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))

{

var i = 1;

foreach (var file in files)

{

var entry = zipArchive.CreateEntry("file" + i + ".pdf", CompressionLevel.Fastest);

using (var entryStream = entry.Open())

{

entryStream.Write(file, 0, file.Length);

}

i++;

}

ms.Flush();



SMFileInfo info = new SMFileInfo("OutputFile.zip", null, ms.ToArray());



throw new PXRedirectToFileException(info, true);


}

}

 

Userlevel 7
Badge +8

thank you very much @AaronB for the code sample. I believe you have mentioned the file & files are byte[] but why I am getting an error on “file.Length”  that ‘byte’ does not have a definition for ‘length’? 

Userlevel 7
Badge

Hi @aaghaei were you able to find a solution? Thank you!

Userlevel 7
Badge +8

Hi @Chris Hackett, Thanks to all who helped out I could make it work. 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved