Buenas tardes, comunidad del Rincón.
Estoy de vuelta ya que se me presentó un nuevo problema.
Tengo un usuario al cual se le implementó una funcionalidad para que se enviaran por correo los archivos XML y PDF de la factura electrónica, como attachments, al momento de correr el proceso de timbrado.
En AX 2012:
1. Primero, el usuario crea la orden de venta.
2. Luego, registra la factura de la OV.
3. Por último, corre el proceso de timbrado desde la ruta
Cuentas por cobrar \ Periódico \ CFDI:Facturas electrónicas \ Proceso de exportación o importación de facturas electrónicas
Al realizar este último paso de manera manual, sin procesamiento por lotes, la nueva funcionalidad que se le agregó al código estándar en AX funciona de manera correcta. Se timbra la factura y, luego, en el mismo proceso envía por correo los archivos XML y PDF de la factura electrónica al e-mail destinatario configurado en la Información de Contacto del cliente a quién se le emitió la factura.
El problema resulta que cuando se corre ese mismo proceso de timbrado por lotes y se agrega al batch no envía el correo.
Voy a la ruta Administración del sistema \ Consultas \ Tareas por lotes:
1. Abro el formulario de tareas por lotes.
2. Selecciono la tarea de timbrado que se agregó al batch.
3. Luego, abro el formulario del historial de tareas por lotes.
4. En el historial revisó el lote más reciente que se llevó de forma automática en el batch
5. Me doy cuenta que ese lote tiene estado de Error y compruebo el Registro.
6. En el Registro me despliega el siguiente error en cuanto al estado de ese lote:
"No se puede inicializar el envío de emails" (Les adjunto la imagen correspondiente al error)
Ahora bien la clase estándar en AX 2012 que ejecuta el proceso de timbrado la identifiqué como la:
EInvoiceMsgBase_MX
- Voy a las propiedades de esa clase y veo que la propiedad RunOn tiene valor de "CalledFrom" lo cual quiere decir que esa clase se puede correr tanto en cliente como en servidor.
Así que, a esa clase se le añadió un método nuevo de nombre: processEmails
Aquí les pongo el código:
public void processEmails(CustInvoiceJour _custInvoiceJour)
{
System.Array filesXML;
SysMailerNet sysMailer;
SysEmailParameters sysEmailParameters = SysEmailParameters::find();
InteropPermission interopPermissionClr = new InteropPermission(InteropKind::ClrInterop);
InteropPermission interopPermissionCOM = new InteropPermission(InteropKind::ComInterop);
Set permissionset = new set(Types::Class);
CustTable custTable = _custInvoiceJour.custTable_OrderAccount();
LogisticsElectronicAddress logisticsElectronicAddress;
DirPartyLocation partyLocation;
Email email = custTable.email();
Filename filename;
FilePath fileNamePathXML;
int fileCountXML, i;
str folio = this.GetInvoiceIdWithoutPrefix(_custInvoiceJour.InvoiceId);
str folioMascliente;
SysEmailMessageTable SysEmailMessageTable;
SysEmailTable sysEmailTable;
#File
System.Array filesPDF;
FilePath fileNamePathPDF;
int fileCountPDF, i;
;
folioMascliente = folio + '_' + custTable.AccountNum;
fileNamePathXML = EInvoiceCFDIParameters_MX::find().CFDIXmlFilePath + "\\";
fileNamePathPDF = EInvoiceCFDIParameters_MX::find().CFDIPDFFilePath + "\\";
filesXML = System.IO.Directory::GetFiles(fileNamePathXML,strFmt("*%1*.xml",folioMascliente));
filesPDF = System.IO.Directory::GetFiles(fileNamePathPDF,strFmt("*%1*.pdf",folioMascliente));
try
{
// Permisos
permissionset.add(interopPermissionClr);
permissionset.add(interopPermissionCOM);
CodeAccessPermission::assertMultiple(permissionset);
//Inicialización de los parámetros de correo electrónico.
sysMailer = new SysMailerNet();
if (sysEmailParameters.smtpRelayServerName)
{
sysMailer.SMTPRelayServer(sysEmailParameters.smtpRelayServerName,
sysEmailParameters.smtpPortNumber,
sysEmailParameters.smtpUserName,
sysEmailParameters::password(),
sysEmailParameters.ntlm);
}
else
{
sysMailer.SMTPRelayServer(sysEmailParameters.smtpServerIPAddress,
sysEmailParameters.smtpPortNumber,
sysEmailParameters.smtpUserName,
SysEmailParameters::password(),
sysEmailParameters.ntlm);
}
// Dirección de origen
sysMailer.fromAddress(sysEmailParameters.SMTPUserName);
if (filesXML||filesPDF)
{
// SysMailer inicializado con parámetros y dirección de origen
fileCountXML = filesXML.get_Length();
fileCountPDF = filesPDF.get_Length();
if (email)
{
// Añadir destinatario
sysMailer.tos().add(email);
}
// Se pueden añadir destinatarios en copia (CC)
while select logisticsElectronicAddress
order by Location
where logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::Email
&& logisticsElectronicAddress.Locator != email
&& logisticsElectronicAddress.IsAutoInvoice == NoYes::Yes
exists join partyLocation
where partyLocation.Location == logisticsElectronicAddress.Location
&& partyLocation.Party == custTable.Party
{
if(_custInvoiceJour.InvoiceAmount >= 0)
sysMailer.ccs().add(logisticsElectronicAddress.Locator);
}
// Asunto del mensaje
select SysEmailMessageTable
where SysEmailMessageTable.EmailId == EInvoiceCFDIParameters_MX::find().EmailId
&& SysEmailMessageTable.LanguageId == _custInvoiceJour.LanguageId;
sysMailer.subject(SysEmailMessageTable.Subject);
sysMailer.htmlBody(SysEmailMessageTable.Mail);
for (i=0; i<fileCountXML; i++)
{
filename = filesXML.GetValue(i);
if (strScan(filename, folioMascliente, 1, strLen(filename)) != 0)
sysMailer.attachments().add(filename);
}
for (i=0;i<fileCountPDF;i++)
{
filename = filesPDF.GetValue(i);
if (strScan(filename, folioMascliente, 1, strLen(filename)) != 0)
sysMailer.attachments().add(filename);
}
// Send mail
sysMailer.sendMail();
}
// Renuncia de los permisos
CodeAccessPermission::revertAssert();
}
catch
{
throw error("No se puede inicializar el envío de emails");
}
}
Revisando mi código me doy cuenta que cuando se deja corriendo el batch y van timbrando facturas el flujo logra llegar al método que se le implementó, pero arroja un error en el código dentro del bloque try que ocasiona que "No se puede inicializar el envio de emails" y, por ende, no pueda enviar el correo por procesamiento por lotes.
Quisiera si a mi código le hace falta programarle más permisos, porque como comenté antes el problema no surge cuando se hace el timbrado de las facturas electrónicas de forma manual sin batch.