Ver Mensaje Individual
  #1344  
Antiguo 30-05-2017
joefrommalaka joefrommalaka is offline
Miembro
NULL
 
Registrado: mar 2017
Posts: 10
Reputación: 0
joefrommalaka Va por buen camino
Problema al enviar más de 20 facturas a la vez

Buenas tardes,

Estoy con un problema que no consigo encontrar la solución, a ver si alguien pudiese echarme una mano.
Cuando envío más de 20 facturas emitidas (me pasa lo mismo con las recibidas) recibo el siguiente error:

Se requiere un certificado para completar la autenticación de cliente - URL:https://www7.aeat.es/wlpl/SSII-FACT/...iiFactFEV1SOAP - SOAPAction:""

Si esas mismas facturas las envío en dos veces, me las envía sin problema.


Para realizar el envío, genero el xml con delphi 7 y realizo el envío mediante una dll que he creado con Delphi XE7.


El código mediante el cual hago el envío es el siguiente:


Código:
type
  TComunicacionSW = class(TObject)
    private
      FArchivoEnvio: String;
      FArchivoRespuesta: String;
      FHTTPRIO: THTTPRIO;
      procedure HTTPRIOBeforeExecute(const MethodName: string; SOAPRequest: TStream);
      procedure HTTPRIOAfterExecute(const MethodName: string; SOAPResponse: TStream);
    public
      Constructor Create;
      Destructor Destroy;
  end;


procedure TComunicacionSW.HTTPRIOBeforeExecute(const MethodName: string; SOAPRequest: TStream);
var
  v_fileStream: TFileStream;
begin
  SOAPRequest.Size := 0;
  v_fileStream := TFileStream.Create(FArchivoEnvio, fmOpenRead);
  SOAPRequest.Position := 0;
  SOAPRequest.CopyFrom(v_fileStream, v_fileStream.Size);
  v_fileStream.Free;
  SOAPRequest.Position := 0;
end;

procedure TComunicacionSW.HTTPRIOAfterExecute(const MethodName: string; SOAPResponse: TStream);
var
  v_fileStream: TFileStream;
begin
  if FileExists(FArchivoRespuesta) then
    DeleteFile(FArchivoRespuesta);
  v_fileStream := TFileStream.Create(FArchivoRespuesta, fmCreate);
  SOAPResponse.Position := 0;
  v_fileStream.CopyFrom(SOAPResponse, SOAPResponse.size);
  v_fileStream.Free;
  SOAPResponse.Position := 0;
end;

function ObtenerNumeroSerieCertificado(p_nombreCertificado: String): string;
var
  hStore: HCERTSTORE;
  PrevContext, CurContext: PCERT_CONTEXT;
  cbSize: DWORD;
  v_nombre: String;
begin
  Result := '';
  hStore := CertOpenSystemStore(0, PChar('MY'));
  if hStore <> nil then
  begin
    PrevContext := nil;
    CurContext := CertEnumCertificatesInStore(hStore, PrevContext);
    while CurContext <> nil do begin
      v_nombre := '';
      cbSize := CertGetNameString(CurContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, nil, 0);
      if cbSize > 0 then
      begin
        SetLength(v_nombre, cbSize-1);
        CertGetNameString(CurContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, PChar(v_nombre), cbSize);
        if SameText(p_nombreCertificado, v_nombre) then
        begin
          result := GetCertSerialNumber(@CurContext^.pCertInfo^.SerialNumber);
          break;
        end;
      end;
      PrevContext := CurContext;
      CurContext  := CertEnumCertificatesInStore(hStore, PrevContext);
    end;
  end;
end;

function EnviarFacturasEmitidas(p_nombreCertificado, p_archivoEnvio, p_archivoRespuesta: ShortString): PChar;stdcall;export;
var
  v_suministroLRFacturasEmitidas: SuministroFactEmitidas.SuministroLRFacturasEmitidas;
  v_respuestaLRFacturasEmitidas: SuministroFactEmitidas.RespuestaLRFacturasEmitidas;
  v_siiSOAP: SuministroFactEmitidas.siiSOAP;
  v_serialNum: String;
  v_error: string;
  v_comunicacionSW: TComunicacionSW;
begin
  v_error := '';

  v_serialNum := ObtenerNumeroSerieCertificado(p_nombreCertificado);
  
  v_comunicacionSW := TComunicacionSW.Create;
  v_suministroLRFacturasEmitidas := SuministroFactEmitidas.SuministroLRFacturasEmitidas.Create;
  v_respuestaLRFacturasEmitidas := SuministroFactEmitidas.RespuestaLRFacturasEmitidas.Create;
  try
    try
      v_comunicacionSW.FArchivoEnvio := p_archivoEnvio;
      v_comunicacionSW.FArchivoRespuesta := p_archivoRespuesta;
      v_comunicacionSW.FHTTPRIO.HTTPWebNode.ClientCertificate.SerialNum := v_serialNum;

      //Se realiza la llamada sin datos y en el evento HTTPRIOBeforeExecute se establece el xml con los datos generados anteriormente
      v_siiSOAP := SuministroFactEmitidas.GetsiiSOAP(true,'',v_comunicacionSW.FHTTPRIO);
      v_respuestaLRFacturasEmitidas := v_siiSOAP.SuministroLRFacturasEmitidas(v_suministroLRFacturasEmitidas);
    except
      on e:Exception do
        v_error := 'Error DLL: Error en la comunicación con el servicio web.' + e.Message;
    end;
  finally
    v_suministroLRFacturasEmitidas.Free;
    v_respuestaLRFacturasEmitidas.Free;
  end;

  result := StringToPChar(v_error);
end;


El archivo SuministroFactEmitidas lo he generado automáticamente con WSDL Importer de delphi y le he modificado lo siguiente (defURL realmente no lo utilizo):

const
defWSDL = 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroFactEmitidas.wsdl';
defURL = 'https://www7.aeat.es/wlpl/SSII-FACT/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP';
defSvc = 'siiService';
defPrt = 'SuministroFactEmitidasPruebas';


¿Se le ocurre a alguien que es lo que estoy haciendo mal?

Un saludo
Responder Con Cita