A menudo los clientes que tienen implementado Microsoft Dynamics AX 2012 en México solicitan poder crear vínculos con sistemas externos.
El escenario que expondré hoy, es validar una Factura Electrónica por medio de un servicio web externo de un Proveedor De Certificación De Factura.
El Servicio de Administración Tributaria en México ofrece una lista de proveedores de este tipo. El cliente en cuestión será encargado de contratar el servicio de acuerdo a sus necesidades.
Para este artículo se trabajó con uno en particular, el cual por medio de un servicio web recibía archivos XML en formato binario (base64Binary).
Dynamics AX ofrece una clase de sistema para poder manejar datos binarios como imágenes u objetos serializados:
Binary Class
Syntax X++
class Binary extends Object |
Prerrequisitos
Microsoft Visual Studio 2010.
Visual Studio Tools para Microsoft Dynamics AX 2012.
Crear y agregar la referencia de servicio
Se crea la referencia de servicio y se agrega al AOT en Visual Studio utilizando las herramientas de Visual Studio para Microsoft Dynamics AX 2012.
Crear la referencia de servicio.
Abrimos Visual Studio 2010 y luego creamos un nuevo proyecto de biblioteca de clases de Visual C #.
El proveedor habrá proporcionado un link a su servicio web público el cual generalmente está protegido por medio de contraseñas, Visual Studio importa el Web Services Description Language y crea las referencias.
Seleccionamos el proyecto ServiceReferences. En las Propiedades, verificamos que los parámetros estén configurados como se muestra en la siguiente tabla.
Propiedad | |
Implementar al cliente | Sí |
Implementar en EP | No |
Implementar en el servidor | Sí |
A continuación, hacemos clic derecho en el nombre del proyecto y luego haga clic en Agregar a AOT.
Para verificar la referencia de servicio.
- En el cliente de Microsoft Dynamics AX, abrimos el Área de trabajo del desarrollador.
- En el AOT, vaya a Proyectos de Visual Studio > Proyectos de C Sharp para ver ServiceReferences.
La referencia de servicio está disponible cuando el proyecto se ha agregado correctamente al AOT.
Creando una instancia de un cliente de servicio
Para usar el servicio web, debemos programar el código en Microsoft Dynamics AX para permitir que la referencia del servicio se construya y se configure una instancia de un cliente de servicio.
public void validateCFDI() { ClrObject clientType; //La clase del servicio web externo estará disponible en X++ PacServicesClient serviceClient; ;
// La seguridad de acceso al código (CAS) ayuda a proteger las API que tienen riesgos de seguridad potenciales cuando las API se ejecutan en el servidor.
Las API habilitadas para CAS llamadas en el servidor requieren el uso de una clase de permiso, una de las clases derivadas de CodeAccessPermission. new InteropPermission(InteropKind::ClrInterop).assert(); try { // La seguridad del servicio web del cliente se puede parametrizar y se manda llamar más adelante this.parmUser(PurchParameters::find().EIGOUserWS); this.parmPassword(PurchParameters::find().EIGOPassword);
if(!this.parmUser() || !this.parmPassword()) { throw error('Favor de configurar los parámetros de Servicio Web en Cuentas por Pagar'); }
// Habilitamos TLS 1.2 System.Net.ServicePointManager::set_Expect100Continue(true); System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);
if(this.parmFileContainer()) { // utilizamos un objeto System.Byte[] oByte; oByte = EIGOHelper::convertContainerToBytes(this.parmFileContainer()); } else if(this.parmFilePath()) { oByte = EIGOHelper::convertFileToBytes(this.parmFilePath()); } encoding = System.Text.Encoding::get_Default(); clientType = CLRInterop::getType("PacServicesClient"); serviceClient = AifUtil::CreateServiceClient(clientType);
switch(this.parmCFDIVersion()) { case EIGOCFDIVersion::v32: retVal = encoding.GetString(serviceClient.validaComprobanteV32(this.parmUser(), this.parmPassword(), oByte)); break; case EIGOCFDIVersion::v33: retVal = encoding.GetString(serviceClient.validaComprobanteV33(this.parmUser(), this.parmPassword(), oByte)); break; } // En la mayoría de los casos los códigos de error de los servicios web externos vienen en la documentación, estos no permitirán enviar un mensaje de error según sea el caso hacia el usuario final if(!retVal) { throw error('No se obtuvo respuesta del servicio'); }
if(strLen(retVal) > 16) { key = subStr(retVal, 6, 3); switch(key) { case 'V00': info('El documento XML pasó correctamente la validación por medio del servicio web'); break; default: throw error(retVal); } } } catch(Exception::CLRError) { ex = CLRInterop::getLastException(); info(ex.ToString()); } CodeAccessPermission::revertAssert(); }
|
Para el caso de los métodos que convertirán a objeto System.Byte[] utlizamos Binary Class:
public static System.Byte[] convertFileToBytes(str filePath) { System.IO.FileStream fileStream; System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); int size;
Binary assemblyBinary; System.IO.MemoryStream memStream; System.Byte[] bytes;
if (filePath) { try { new InteropPermission(InteropKind::ClrInterop).assert(); //Leer el contenido del archivo fileStream = System.IO.File::OpenRead(filePath); size = fileStream.get_Length(); memoryStream.SetLength(size); fileStream.Read(memoryStream.GetBuffer(), 0, size); //Utilización de la clase de sistema Binary assemblyBinary = Binary::constructFromMemoryStream(memoryStream);
memStream = assemblyBinary.getMemoryStream(); bytes = memStream.ToArray(); memStream.Close();
CodeAccessPermission::revertAssert();
} catch (Exception::CLRError) { SRSProxy::handleClrException(Exception::Error); } //Regresamos el objeto bytes return bytes; }
return null; }
|
De esta forma el binario puede servir como una interfaz simple entre AX (usando contenedores) y flujos de datos en un entorno .NET.
Al final es posible la validación del documento por medio del servicio web externo con reglas de negocio codificadas en Dynamics AX.
Espero que este artículo les sea de utilidad, si quieren aprender más sobre desarrollo de aplicaciones, desarrollo en Dynamics o de Dynamics en general por favor visita nuestro site de Eigo Academy para conocer nuestra oferta de cursos.