Hi,
I have a code issue that are troubling me and I would like to see if any of you have an idea.
Currently we’re integrating to a new website.
One of the functions we need is to generate an invoice to the customer.
We’ve added a button on the website, once pushed it will send through an email and invoice number to a method in AX that will generate the invoice and email it back.
The headache comes as it works for some invoices but not others and I cannot seem to figure out why.
The error we get is that when sending the email there is no file to attach.
So somewhere when I’m generating the invoice in AX it doesn’t work and then when I call the send email code there is no file to attach.
When I preview the invoices in AX they all shows to screen with no issues.
I can also save them as PDF’s no issue.
But when running the code some invoice fails to save other work fine, the is error:
Method 'addAttachment' in COM object of class 'CDO.Message' returned error code 0x80070002 (<unknown>) which means: The system cannot find the file specified.
I haven’t been able to google anything useful regarding this error.
I have a job I’m using to call the method
static void SSS_EmailInvoice(Args _args)
{
//str xmlDoc = "<InvoicePrint><FromAddress>sales@sssaustralia.com.au</FromAddress><ToAddress>soren.rasmussen@sssaustralia.com.au</ToAddress><Subject>SSS Invoice</Subject><Body>This is your invoice</Body><InvoiceId>SI0483794</InvoiceId><SalesId></SalesId> </InvoicePrint>"; //works
str xmlDoc = "<InvoicePrint><FromAddress>sales@sssaustralia.com.au</FromAddress><ToAddress>soren.rasmussen@sssaustralia.com.au</ToAddress><Subject>SSS Invoice</Subject><Body>This is your invoice</Body><InvoiceId>SI0486086</InvoiceId><SalesId></SalesId> </InvoicePrint>"; //fails
//SI0497671,SI0483794,SI0483794,SI0486086,SI0497599,SI0497600
CV_SSSCustom::printInvoice(xmlDoc);
}
The method is a static method on a functions class
public static str printInvoice(str xmlPayload)
{
XmlDocument doc;
XmlElement element;
XmlElement item;
XMLNodeListIterator iterator;
//
SysEmailParameters parameters = SysEmailParameters::find();
SMTPRelayServerName relayServer;
SMTPPortNumber portNumber;
SMTPUserName userName;
SMTPPassword password;
InteropPermission interopPermission = new InteropPermission(InteropKind::ComInterop);
FileIOPermission fioPermission;
System.Exception e;
SysMailer mailer = new SysMailer();
//report variables
SrsReportRunController ssrsController = new SrsReportRunController();
SalesInvoiceContract salesInvoiceContract = new SalesInvoiceContract();
SRSPrintDestinationSettings printerSettings;
CustInvoiceJour custInvoiceJour;
smmParametersTable smmParametersTable = smmParametersTable::find();
Filename fileName;
str fromAddress;
str toAddress; //inbound parameter
str subject;
str body;
SalesId salesId;
InvoiceId invoiceId; //inbound parameter
doc = new XmlDocument();
doc.loadXml(xmlPayload);
element = doc.documentElement().selectSingleNode("//InvoicePrint");
fromAddress = element.getNamedElement("FromAddress").text();
toAddress = element.getNamedElement("ToAddress").text();
subject = element.getNamedElement("Subject").text();
body = element.getNamedElement("Body").text();
invoiceId = element.getNamedElement("InvoiceId").text();
SalesId = element.getNamedElement("SalesId").text();
// Add record
if (invoiceId)
{
select firstOnly custInvoiceJour
where custInvoiceJour.InvoiceId == invoiceId;
//where custInvoiceJour.InvoiceId == invoiceId || custInvoiceJour.SalesId == SalesId;
fileName = strFmt("%1\\%2.pdf", smmParametersTable.SSSCVArchivePath, invoiceId);
/* fioPermission = new FileIOPermission(fileName ,"RW");
fioPermission.assert();
interopPermission = new InteropPermission(InteropKind::ComInterop);*/
interopPermission.assert();
// Define which report design to print
ssrsController.parmReportName("SalesInvoice.ReportTFS"); //ssrsReportStr(SalesInvoice, ReportTFS));
ssrsController.parmReportName(ssrsReportStr(SalesInvoice, ReportTFS));
// Ddefine how we want to execute the report (right now or batch style)
ssrsController.parmExecutionMode(SysOperationExecutionMode::ReliableAsynchronous);
// Hide the report dialog
ssrsController.parmShowDialog(false);
// Need to populate the required parms for the current sales order controller
salesInvoiceContract.parmRecordId(custInvoiceJour.RecId);
salesInvoiceContract.parmCountryRegionISOCode(SysCountryRegionCode::countryInfo());
salesInvoiceContract.parmDocumentTitle('Invoice');
// Link the contract to the controller so we know how to run the dp
ssrsController.parmReportContract().parmRdpContract(salesInvoiceContract);
// Link the printer settings to the controller
printerSettings = ssrsController.parmReportContract().parmPrintSettings();
// Print to HTML and always overwrite if the file exists
printerSettings.printMediumType(SRSPrintMediumType::File);
printerSettings.fileFormat(SRSReportFileFormat::PDF);
printerSettings.overwriteFile(true);
printerSettings.fileName(fileName);
// Run & save the report
ssrsController.startOperation();
if (printerSettings.fileName())
{
if (parameters.SMTPRelayServerName)
relayServer = parameters.SMTPRelayServerName;
else
relayServer = parameters.SMTPServerIPAddress;
portNumber = parameters.SMTPPortNumber;
userName = parameters.SMTPUserName;
password = SysEmailParameters::password();
subject = subject;
body = body;
try
{
// interopPermission = new InteropPermission(InteropKind::ComInterop);
//interopPermission.assert();
mailer = new SysMailer();
mailer.SMTPRelayServer(relayServer,portNumber,userName,password, parameters.NTLM);
mailer.fromAddress(fromAddress);
mailer.tos().appendAddress(toAddress);
mailer.subject(subject);
mailer.htmlBody(body);
mailer.attachments().add(printerSettings.fileName());
mailer.sendMail();
//CodeAccessPermission::revertAssert();
//info("Email has been send!");
}
catch (Exception::CLRError)
{
e = ClrInterop::getLastException();
while (e)
{
info(e.get_Message());
e = e.get_InnerException();
info(strFmt("%1", e));
}
}
}
CodeAccessPermission::revertAssert();
}
else
info("No invoiceId selected");
return "OK";
}
Hi Janna,
no unfortunately I haven't been able to figure out the solution.
I believe it could be caused by the System account not having enough access.
But again I don't want to play around to much with those settings.
I've decided to follow another path and create a batch that will export all invoice to a directory.
Once exported the website can access the files and email them.
So there is definitely read access for the system account.
Thanks
Soren
Hi Soren,
Is he issue resolved on your side already?
Hi Soren Rasmussen,
Have you tried to debug it to find the exact place where the error is coming? Are you running the process in batch or it's user session? Have you already tried to make a full x++ compile + full CIL build?
Hi Sergei,
thanks for your reply. There is definitely an issue saving the file with this code.
For some reason the invoice generation cannot save the file.
I did restart the SQL and AOS and now it doesn't work at all.
The webservice are getting an the following error, have you seen this before?
Unable to cast object of type 'System.Object[]' to type 'Microsoft.Dynamics.Ax.Xpp.Common
I did alter the code as per below but gets the same error, it seems like the webservice cannot access the method or fails during the invoice generation. Can you see any issues?
public static str printInvoice(str xmlPayload)
{
#File
XmlDocument doc;
XmlElement element;
XmlElement item;
XMLNodeListIterator iterator;
//
SysEmailParameters parameters = SysEmailParameters::find();
SMTPRelayServerName relayServer;
SMTPPortNumber portNumber;
SMTPUserName userName;
SMTPPassword password;
InteropPermission interopPermission;
System.Exception e;
SysMailer mailer = new SysMailer();
//
//report variables
SalesInvoiceController salesInvoiceController;
SalesInvoiceContract salesInvoiceContract;
SrsReportDataContract contract;
SrsReportRunInterface reportRun;
SRSReportExecutionInfo executionInfo;
FilePath filePath;
SrsReportRunController ssrsController = new SrsReportRunController();
//SalesInvoiceContract salesInvoiceContract = new SalesInvoiceContract();
SRSPrintDestinationSettings printerSettings;
CustInvoiceJour custInvoiceJour;
smmParametersTable smmParametersTable = smmParametersTable::find();
Filename fileName;
Args args;
str fromAddress;
str toAddress; //inbound parameter
str subject;
str body;
SalesId salesId;
InvoiceId invoiceId; //inbound parameter
doc = new XmlDocument();
doc.loadXml(xmlPayload);
element = doc.documentElement().selectSingleNode("//InvoicePrint");
fromAddress = element.getNamedElement("FromAddress").text();
toAddress = element.getNamedElement("ToAddress").text();
subject = element.getNamedElement("Subject").text();
body = element.getNamedElement("Body").text();
invoiceId = element.getNamedElement("InvoiceId").text();
SalesId = element.getNamedElement("SalesId").text();
args = new Args();
args.parmEnumType(enumNum(PrintCopyOriginal));
args.parmEnum(PrintCopyOriginal::OriginalPrint);
// Add record
if (invoiceId)
{
select firstOnly custInvoiceJour
where custInvoiceJour.InvoiceId == invoiceId;
//where custInvoiceJour.InvoiceId == invoiceId || custInvoiceJour.SalesId == SalesId;
fileName = strFmt("%1\\%2.pdf", smmParametersTable.SSSCVArchivePath, invoiceId);
new FileIOPermission(filePath, "RW").assert();
salesInvoiceController = new salesInvoiceController();
salesInvoiceController.parmReportName(ssrsReportStr(SalesInvoice, ReportTFS));
salesInvoiceController.parmExecutionMode(SysOperationExecutionMode::ScheduledBatch);
salesInvoiceController.parmShowDialog(false);
args.record(custInvoiceJour);
salesInvoiceContract = salesInvoiceController.parmReportContract().parmRdpContract();
salesInvoiceContract.parmRecordId(custInvoiceJour.RecId);
salesInvoiceContract.parmCountryRegionISOCode(SysCountryRegionCode::countryInfo());
salesInvoiceContract.parmDocumentTitle("Invoice");
contract = salesInvoiceController.parmReportContract();
if(args.record() && contract != null)
{
reportRun = new SrsReportRunImpl(contract.parmReportName());
reportRun.parmReportContract(contract);
if (reportRun.parmReportContract().parmReportExecutionInfo() == null)
{
executionInfo = new SRSReportExecutionInfo();
reportRun.parmReportContract().parmReportExecutionInfo(executionInfo);
}
printerSettings = reportRun.parmReportContract().parmPrintSettings();
printerSettings.printMediumType(SRSPrintMediumType::File);
printerSettings.fileFormat(SRSReportFileFormat::PDF);
filePath = printerSettings.fileName(@fileName);
printerSettings.overwriteFile(true);
reportRun.runReport();
}
if (filePath)
{
if (parameters.SMTPRelayServerName)
relayServer = parameters.SMTPRelayServerName;
else
relayServer = parameters.SMTPServerIPAddress;
portNumber = parameters.SMTPPortNumber;
userName = parameters.SMTPUserName;
password = SysEmailParameters::password();
subject = subject;
body = body;
try
{
// interopPermission = new InteropPermission(InteropKind::ComInterop);
// interopPermission.assert();
mailer = new SysMailer();
mailer.SMTPRelayServer(relayServer,portNumber,userName,password, parameters.NTLM);
mailer.fromAddress(fromAddress);
mailer.tos().appendAddress(toAddress);
mailer.subject(subject);
mailer.htmlBody(body);
mailer.attachments().add(printerSettings.fileName());
mailer.sendMail();
// CodeAccessPermission::revertAssert();
//info("Email has been send!");
}
catch (Exception::CLRError)
{
e = ClrInterop::getLastException();
while (e)
{
info(e.get_Message());
e = e.get_InnerException();
info(strFmt("%1", e));
}
}
}//filepath
CodeAccessPermission::revertAssert();
}//invoice
else
info("No invoiceId selected");
return "OK";
}
Hi Tigerrasmussen,
I would add check if the file exists before adding the attachment to the e-mail. Maybe it's not ready or locked by another process and can't be attached because of that.
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,253 Super User 2024 Season 2
Martin Dráb 230,188 Most Valuable Professional
nmaenpaa 101,156