web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Email PDF invoice from folder

(0) ShareShare
ReportReport
Posted on by 160

With a variety of code available in various resources on the internet, I managed to put together a class that basically will run as batch run and according to the query specified it shall collect any new invoices for a customer(s) and;

1. save to a folder (local drive)

2. collect that file and then email it. 

Now the program works fine when I run it manually, that is, not via a batch job. When run in batch, I get the following error below:

Method 'addAttachment' in COM object of class 'CDO.Message' returned error code 0x80070005 (<unknown>) which means: Access is denied.

The 'process' method I have in the class is shown below- I'd appreciate if anyone could tell me where I'm going wrong, or even suggest an alternative way of achieving this. I should add, that the first part of the method - the one that saves the file, runs perfectly, it is only when the SysMailer attempts to attach it that the error occurs.
     Args                        args=new Args();
    SalesFormLetter             salesFormLetter;
    SysMailer                   mailer;
    PrintJobSettings            printJobSettings;
    str                         _fileName;
    InteropPermission permission;
    FileIOPermission  dirPermission, filePermission;
    Set               permissionSet;
    ;
    args.record(_custInvoiceJour); 
    _fileName=strfmt('%1\\%2.pdf',filepath,_custInvoiceJour.InvoiceId);   
        if(_custInvoiceJour)
        {
            salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice,false);
            printJobSettings = new printJobSettings();
            printJobSettings.setTarget(PrintMedium::File);
            printJobSettings.format(PrintFormat::PDF_EMBED_FONTS);
            printJobSettings.fileName(_filename);
            salesFormletter.updatePrinterSettingsFormLetter(printJobSettings.packPrintJobSettings());
            _custInvoiceJour.printJournal(SalesFormletter);
            {
                permission = new InteropPermission(InteropKind::ComInterop);
                dirPermission = new FileIOPermission(_fileName,'W');
                permissionSet = new Set(Types::Class);
                permissionSet.add(permission);
                permissionSet.add(dirPermission);
                CodeAccessPermission::assertMultiple(permissionSet);
                mailer = New SysMailer();
                mailer.fromAddress('abc@xyz.com');
                mailer.subject(strfmt("Invoice %1,date %2", _custInvoiceJour.invoiceId,_custInvoiceJour.InvoiceDate));
                if(email) //<--dialog field
                {
                    mailer.tos().appendAddress(email);
                }
                if(!email)
                {
                    mailer.tos().appendAddress(CustTable::find(_custInvoiceJour.InvoiceAccount).Email);
                }
                mailer.htmlBody("Please see attached");
                mailer.SMTPRelayServer( SysEmailParameters::find().SMTPRelayServerName,
                                          SysEmailParameters::find().SMTPPortNumber,
                                          SysEmailParameters::find().SMTPUserName,
                                          SysEmailParameters::find().SMTPPassword,
                                          SysEmailParameters::find().NTLM);
                mailer.attachments().add(_fileName);
                mailer.sendMail();
            }
            CodeAccessPermission::revertAssert();
        }

 

*This post is locked for comments

I have the same question (0)
  • Community Member Profile Picture
    on at

    Quick glance of your code and it looks fine.

    First things to check:  

    1) Your classes "RunOn" method.  Set it to called From or Server

    2) Your batch AOS actually has your class in it.

    If both okay then I think error might be thrown from mailer.attachments().add(_fileName);  Check what permissions your pdf files have.  Could be the case that you are assigning this batch under a different user account that does not have access to those files.

  • diskwars Profile Picture
    160 on at

    Setting it to Client worked. Called  From was what it was already on. Server produced an error about not being able to find the path specified. But when run set to Client it worked great.

    Many thanks!

  • diskwars Profile Picture
    160 on at

    I spoke to soon. While it now works when setting Run on to 'client' It only emails the invoices to one specific email address. Even if I choose a different address!?! So, the class had a dialog that allows to specific a location and email address. With it set to run on client, i would enter an email address e.g. efg@xyz.com and execute it. But the email is received at lmn@xyz.com. lmn@xyz.com is actually mine (the developer/class creator's) address. It is not specified in the user information or anywhere within Ax. On our 'batch aos' the ax runs as a service and I am not sure where it get's my address from!

    Anyhow, it doesn't work on run on Server or Called from.

    Furthermore, when run on client, even though the attachment is received, if the filetype is PDF it throws an error 'insufficient memory' from the PDF when it is opened. However, when the filetype is PDF_EMBEDED_FONTS, it opens fine, albeit a larger file.

    Any ideas on any of it? I am mostly concerned in getting it to work on the batch server to any address I specify. The PDF issue is negligible at the moment.

  • Dawson Britto Profile Picture
    115 on at

    Hi diskwars,

    Good job.

    I need to do the same thing what you have done. Can you please send me over the entire code on dawson@geidi.com

    Thanks in advance

  • Suggested answer
    Jonathan Havard Profile Picture
    on at

    Hello,

    I've done something similar to you and ran into a similar issue.  Reports will always run on the client tier, so when you specify the file name and tell the report to run, it will switch tiers to client to run the report and will save the file at the filename relative to the client path.  Then when the execution switches back to the server tier it will try to attach the file at the path relative to the server.

    The error you're getting is a permissions issue which is being enforced because you're on the server tier.  I would first make sure the location which you are trying to save the report to is accessible from both locations, on a network share, for example.  Second and what I think will solve your immediate problem, change your FileIOPermission to read-write instead of just write.  The attachment process needs read permission to do the attaching.

    I hope this helps,

  • diskwars Profile Picture
    160 on at

    I've checked the location (which is on the local drive of the server that executes our batch journals) and it is accessible by both me (as the user) and the batch user (the service). I also changed the file permission to RW. It was also suggested to increase the folder rights for the batch user - who now has Full Control to that folder. I even created a share for that folder and gave both me and the batch user Full Control rights to the share.

    Despite all of this, it still does not work.

    As before, it runs fine when executed manually. However, the running as batch issue has changed;

    a. when I run it as myself (triggering batch processing manually from the same client) - the class executes and the same error 'Access is denied' appears.

    b. when I run it as the batch user - it no longer executes. It simply ends up as an ended job. it seems like just skips the Run method alltogether.

  • Suggested answer
    Jonathan Havard Profile Picture
    on at

    a. Hm, I know the administrative shortcut //c$ or similar does not work and will give you that error message.  You said you tried creating a network share and that's one of the things I had to do to get things working.  Verify that the AOS service account has access to the network share you've created, because that's the only permissions issue I think you can run into at this point.  

    b. To troubleshoot this sort of thing you could throw some error messages and they should appear in the batch job's log.  You do have a big IF that circumvents everything.  Maybe toss a message in the else to make sure it's not just following your logic.

    It doesn't look like you're deleting the report in your method.  Can you verify the report is being generated and is just failing to attach?

    I would add some checks for error conditions so you can get closer to understand what may be going wrong.  After generating the file, use winApiServer::fileExists() to verify the file has been created and the server side process can access the file.

  • diskwars Profile Picture
    160 on at

    Hi,

    Took on board you advice and;

    a. Changed the locationg to \\servername\folder\file.pdf. It still returned the same error - access is denied.

    b. I added the if(WinAPIServer::fileExists()) - just after the PrintJournal. This time, the error was; "Request for the permission of type 'FileIOPermission' failed." I did not change anything else in the code.

     

    You are correct. The report is always being generated. When I debugged the class as it was running in private batch job, I found that it falls over on the line -

    mailer.attachments().add(_filename);

    When you 'step in' to this line - it takes you to the SysMailerAttachment class and it runs all through to the Create method of that class before the error about access is denied.

     

  • Shweta Aggarwal Profile Picture
    35 on at

    Hey Diskwars,

    Your code help me alot......but i stuck somewhere in the middle....

    If possible can u share the entire code with me on shweta.aggarwal@rocketmail.com

  • Suggested answer
    Kauto Profile Picture
    2,701 on at

    Hi Guys,

    I had a similar issue in my code where I was generating a csv output file and then creating an email with SysMailer and calling the attachment method.

    Ran fine on client tier but when I called it via batch job on the server had the message stating the file was in use and it had no access.

    To get around the issue, I used the code:

    System.IO.File::Copy(excelFile,attachFile,true);

    To create a copy of the output file and then I was able to attach the copied version of the file to my email via SysMail

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

News and Announcements

Season of Giving Solutions is Here!

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics AX (Archived)

#1
Martin Dráb Profile Picture

Martin Dráb 4 Most Valuable Professional

#2
TAHER Mehdi Profile Picture

TAHER Mehdi 3

#3
Nakul Profile Picture

Nakul 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans