jueves, 19 de febrero de 2015

Diferencias entre SCRUM y Kanban

Os dejo un PDF que me ha venido muy bien para tener algunos conceptos mas claros:
http://www.proyectalis.com/documentos/KanbanVsScrum_Castellano_FINAL-printed.pdf
Un saludo.

WebServices de FacturaE, no funcionan.

Comentaros que por ahora los servicios Web de https://webservice.face.gob.es  no funcionan.
No se puede enviar facturas ni consultar sus estados.
Hay una incidencia Generalizada.
Toca esperar.
Un saludo.

Usar Web Services de Face con c# .NET y no morir en el intento. (FacturaE)

Primero: dar las gracias a sViudes Blog por su post sobre la creación del XML para la factura y su firma. A partir de ahí:
http://sviudes.blogspot.com.es/2010/05/facturae-con-net-y-c.html

Josep María Herrando ha subido a Github una aplicación que se conecta y envía facturas al FACE. Muchas gracias Josep.
Para descargarlo:
https://github.com/miamon/Face-Web-Service

Voy a intentar explicar paso por paso como atacar a estos servicios Web.
En primer lugar hay que tener claro que el entorno STAGE del que tanto hablan en la documentación a mi, por lo menos, no me funciona. He enviado varios emails al soporte y no he tenido contestación. Se nota que están desbordados.

Entorno: 

  • VS2013
  • c#
  • Framework 4.5
  • Proyecto WEB usando NuGet
  • Handler (generic Hanlder) para hacer las pruebas.
Estoy usando VS2013, con framework 4.5. Yo tengo un proyecto WEB y voy a intentar atacar a los Web Services del FacturaE con un Generic Handler o ASHX.
De todos modos el código os valdría para cualquier tipo de programa, ya sea web o cliente pesado (WinForms)


Añadir la referencia a nuestro proyecto Microsoft.Web.Services3.dll 

Paso , añadir la librería Microsoft.Web.Services3.dll (Web Services Enhancements (WSE) 3.0 for Microsoft .NET)

Para hacer esto tenéis varias maneras. O lo instaláis vía NugGet en vuestro proyecto Web o bien descargáis desde lo necesario (hay que instalarlo) y hacéis un add Reference a vuestro proyecto:


http://www.microsoft.com/en-us/download/details.aspx?id=14089

Esta librería la necesitamos para poder firmar las peticiones SOAP con nuestro certificado.

Una vez instalada la librería os recomiendo seguir las especificaciones para daros de alta como proveedores en la web del face:

http://administracionelectronica.gob.es/pae_Home/dms/pae_Home/documentos/CTT/FACE/FACe-Manual-de-Proveedores-1-2/FACe%20-%20Manual%20de%20Proveedores%201.2.pdf
Y aquí un resumen de lo que hay que hacer:


Para poder mandar una factura al portal FACe, si ya no está de alta como proveedor, se debe poner de alta en el portal FACe, menú Proveedores: https://face.gob.es/es/proveedores/1.    En  Gestión de Certificados, pulsar Alta de Certificado
2.    Informar los campos Nombre de proveedor e Email
3.    El campo PEM es la parte publica de su certificado digital:
Para poder obtener dicha parte pública los pasos a seguir son los siguientes:
-          En su explorador  ir al menú de Exportación de Certificados. (Menú contenido / Certificados) del Internet Explorer
-          Se abrirá un asistente para la exportación de certificados.
-          En este es importante seleccionar la opción “X.509 codificado en base 64 (.CER)”
-          Se seleccionará el nombre de un fichero en una carpeta local. Por ejemplo “certificado.cer”
-          A partir de ese momento se puede abrir el fichero obtenido con cualquier editor de texto.
4.    Pegar la parte publica del certificado que empieza por BEGIN CERTIFICATE  y termina por END CERTIFICATE. Ambos campos se deben escribir.
-          (También, se puede usar la aplicación online https://www.sslshopper.com/ssl-converter.html , introduciendo el certificado, seleccionando en Type of current certificate la opción DER/Binary y en Type to convert to la opción Standard PEM).
5.    Contestar al campo “Escriba las palabras de la imagen”
6.    Informar la línea “Usuarios autorizados para gestionar el certificado”. Se debe registrar un usuario y se pueden registrar varios.
 Sin la correcta información del campo PEM, la comunicación con FACe desde FACTURAe 3.1 devolverá un error de Certificado.

 Si usted utiliza la aplicación FACTURAe, también se debe configurar el certificado digital en Configuración / Configuración FACe.
 Una vez configurado el certificado en FACE/Proveedores y en FACTURAe/Configuración_Face, desde la aplicación FACTURAe se debe seleccionar un nuevo receptor de alta en FACe y aparece en el despegable las listas de oficina contable, órgano gestor y unidad tramitadora..Una ves estéis dados de alta pasamos a generar la clase proxy necesaria para atacar los servicios web del face.

Generación de Clase proxy para comunicación con el Servicio Web

Para hacerlo tenéis primero que ejecutar la Línea de comandos de Visual Studio:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts\Developer Command Prompt for VS2013.lnk
Luego ejectuar :
C:\Program Files (x86)\Microsoft Visual Studio 12.0>wsdl https://webservice.face.gob.es/sspp?wsdl

NOTA: estamos creando una clase para atacar al ENTORNO DE PRODUCCION. Cuidado con hacer pruebas con este entorno como enviar facturas. Este tutorial no pudo hacerse con el entorno de pruebas porque ha fecha de hoy no funciona correctamente.


Una vez tenemos la clase creada (nos genera un fichero .cs llamado SSPPWebServiceProxyService.cs en la misma ruta) la añadimos a nuestro proyecto.

Tenemos que tener algo así delante de nosotros:

Modificación del Proxy para poder usar Web Services Enhancements (WSE) 3.0 

La clase que hemos generado de por sí no podemos usarla para firmar peticiones SOAP. Para hacerlo tenemos que cambiar su inherits.
Cambiamos esta línea
public partial class SSPPWebServiceProxyService : System.Web.Services.Protocols.SoapHttpClientProtocol
 por 
public partial class SSPPWebServiceProxyService : Microsoft.Web.Services3.WebServicesClientProtocol

Ahora si tendremos acceso a los métodos que nos facilita WSE 3.0

Configuración del WSE Vía WebConfig

En el web.config tenéis que tener en cuenta estas líneas de configuración:
dentro de configuration
<configuration>
  <configSections>
    <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </configSections>
  <appSettings/>

en assemblys (lógicamente):
 <assemblies>
        <add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add assembly="System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
      </assemblies>

Dentro de System.Web
<webServices>
      <soapExtensionImporterTypes>
        <add type="Microsoft.Web.Services3.Description.WseExtensionImporter, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </soapExtensionImporterTypes>
      <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </webServices>

y por último lo realmente importante, la configuración de las peticiones con WSE:
<microsoft.web.services3>
    <security>
      <x509 allowTestRoot="true" storeLocation="CurrentUser" revocationMode="NoCheck"/>
      <securityTokenManager>
        <add type="Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" localName="UsernameToken"/>
      </securityTokenManager>
    </security>
    <diagnostics>
      <trace enabled="true" input="InputTrace.webinfo" output="OutputTrace.webinfo"/>
      <detailedErrors enabled="true"/>
    </diagnostics>
    <messaging>
      <mtom clientMode="Off"/>
    </messaging>
  </microsoft.web.services3>

¿Cómo podéis cambiar esta configuración si fuera necesario?

Lógicamente podéis cambiarla directamente en el webconfig, pero hay una herramienta que nos ayuda a cambiarlo fácilmente.
Cuando instaláis Web Services Enhancements 3.0 se copian unas serie de ficheros dentro de de c:\Program Files (x86)\Microsoft WSE\v3.0\Tools\Uno de ellos se llama WseConfigEditor3.exeSi lo ejecutáis se abrirá una ventana como esta:
Pulsar en File->Open y seleccionar vuestro web.config o app.config. Una vez lo haya leído solo tenéis que activar las casillas "Enable this project Web Services Enhancements" y "Enable Microsoft Web Services Enhancement Soap Protocol Factory".
Luego revisáis el apartado Securiy y modificáis lo que necesitéis. En nuestro caso para la facturaE lo dejamos como está en la imagen.


Una vez tengáis todo esto (todas las modificaciones expuestas anteriormente), es hora de probar a enviar peticiones firmadas a algunos de los métodos del FacE. En este caso, vamos a ver si funciona el método ConsultarEstados.

Firmar peticiones SOAP con nuestro certificado digital y hacer el request a ConsultarEstados

En la clase donde vayáis a hacer las consultas y peticiones al FACE tener en cuenta de añadir estos using:
using System.Web.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;
using Microsoft.Web.Services3.Security.X509;
Primero creamos el objeto SSPPWebServiceProxyService
SSPPWebServiceProxyService FacturaEServicio = new SSPPWebServiceProxyService();


Luego buscamos nuestro certificado:

X509Certificate2Collection Certificado = X509Util.FindCertificateBySubjectName("CN=VUESTRA ENTIDAD, OU=XXXXXXX, OU=FNMT Clase 2 CA, O=FNMT, C=ES", System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser, "My");


Si no sabéis exactamente el nombre del certificado (subject) os dejo unas líneas de código que recorren los certificados y dan su subject:

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
 
var certificates = store.Certificates;
foreach (var certificate in certificates)
{
    context.Response.Write(certificate.SubjectName.Name);//context.Response.Write porque estamos en un ASHX generic handler. Hacer el output donde creáis conveniente
}
 
store.Close();


Una vez tengamos el certificado localizado y cargado en X509Certificate2Collection Certificado firmamos las peticiones:
Nota: Se podría evitar hacer el paso anterior puesto que, como veis, luego solo le pasamos a GetSecurityToken el Subject del certificado. Mas que nada lo hago para verificar el certificado Existe y porque además le doy otro uso dentro del código (pero no tiene nada que ver con la FacturaE).

           SecurityToken Token = GetSecurityToken(Certificado[0].SubjectName.Name);
           FacturaEServicio.RequestSoapContext.Security.Tokens.Add(Token);
           MessageSignature sig = new MessageSignature(Token);
           FacturaEServicio.RequestSoapContext.Security.Elements.Add(sig);
os pongo el código de GetSecurityToken:

public X509SecurityToken GetSecurityToken(string subjectName)
  {
      X509SecurityToken securityToken = null;
      X509Store store = new X509Store(StoreName.My,
        StoreLocation.CurrentUser);
      store.Open(OpenFlags.ReadOnly);
      try
      {
          X509Certificate2Collection certs =
              store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName,
              subjectName, false);
 
          X509Certificate2 cert;
          if (certs.Count == 1)
          {
              cert = certs[0];
              securityToken = new X509SecurityToken(cert);
          }
          else
              securityToken = null;
      }
      catch (Exception ex)
      {
          Console.WriteLine(ex.ToString());
      }
      finally
      {
          if (store != null)
              store.Close();
      }
 
 
      return securityToken;
  }



y enviamos la petición ConsultarEstados:

//Testeamos método de estados
           try
           {
               context.Response.Write("Test Estados  </br>");
               SSPPEstados Estados = FacturaEServicio.consultarEstados();
               foreach (var item in Estados.estados)
               {
                   context.Response.Write(item.nombre + "</br>");
               }
 
           }
           catch (Exception Ex)
           {
 
               context.Response.Write(Ex.Message + " </br>");
           }
Y debería de darnos todos los estados de la factura de esta manera:
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://webservice.face.gob.es" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Header>
          <!-- Cabecera de seguridad -->
        </SOAP-ENV:Header>
        <SOAP-ENV:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="pfx4e3e9327-c62c-9319-017e-70f76c8de5e0">
          <ns1:consultarEstadosResponse>
            <return xsi:type="ns1:SSPPEstados">
              <estados SOAP-ENC:arrayType="ns1:SSPPEstado[9]" xsi:type="ns1:ArrayOfSSPPEstado">
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Registrada</nombre>
                  <codigo xsi:type="xsd:string">1200</codigo>
                  <descripcion xsi:type="xsd:string">La factura ha sido registrada en el registro electrónico REC</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Contabilizada la obligación reconocida</nombre>
                  <codigo xsi:type="xsd:string">2400</codigo>
                  <descripcion xsi:type="xsd:string">Se ha dado orden de pago de la factura</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Pagada</nombre>
                  <codigo xsi:type="xsd:string">2500</codigo>
                  <descripcion xsi:type="xsd:string">Factura pagada</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Rechazada</nombre>
                  <codigo xsi:type="xsd:string">2600</codigo>
                  <descripcion xsi:type="xsd:string">La Unidad rechaza la factura</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Anulada</nombre>
                  <codigo xsi:type="xsd:string">3100</codigo>
                  <descripcion xsi:type="xsd:string">La Unidad aprueba la propuesta de anulación</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">No solicitada anulación</nombre>
                  <codigo xsi:type="xsd:string">4100</codigo>
                  <descripcion xsi:type="xsd:string">No solicitada anulación</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Solicitada anulación</nombre>
                  <codigo xsi:type="xsd:string">4200</codigo>
                  <descripcion xsi:type="xsd:string">Solicitada anulación</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Aceptada anulación</nombre>
                  <codigo xsi:type="xsd:string">4300</codigo>
                  <descripcion xsi:type="xsd:string">Aceptada anulación</descripcion>
                </item>
                <item xsi:type="ns1:SSPPEstado">
                  <nombre xsi:type="xsd:string">Rechazada anulación</nombre>
                  <codigo xsi:type="xsd:string">4400</codigo>
                  <descripcion xsi:type="xsd:string">Rechazada anulación</descripcion>
                </item>
              </estados>
            </return>
          </ns1:consultarEstadosResponse>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>


Un saludo a todos!