lunes, 19 de octubre de 2015

SAFT con SAP. Error SECSTORE:023

Estoy aplicando las notas para el SAFT de la AT Portugal para hacer la comunicación de los transportes Online con Web Services:

• Note 1901250 - PT Web Services- Online communication to AT : Technical Req
• Note 1901252 - PT Web Services- Online communication to AT:Solution Details

Al probar la transacción WSPT_MONI me da el siguiente error:
  • (SECSTORE:023) No se ha encontrado entrada /WSPT/DELIVERY/<código de la empresa>;* en memoria segura 
  • (SECSTORE:023) Entrada /WSPT/DELIVERY/<código de la empresa>;* não encontrada na memória segura
La solución es introducir el usuario y password de la AT portuguesa con la transacción WSPT_STORE_PASS.

Por cierto es importante saber que los certificados correctos son los de "2054553 - PT: WS - Online communication to AT: Certificates" y NO los de la nota "1901250 - PT Web Services- Online communication to AT : Technical Req".

lunes, 28 de septiembre de 2015

Seguimiento (trace) del log de un Web Service en SAP.

Es interesante lo que explica la nota "1901252 - PT: WS - Online communication to AT:Solution Details" en el documento "Guidelines_for_endpoint_config2_v2.pdf" para como mirar el log al usar un web service.

For trace and LOG you can either use SRT_UTIL transaction or the trace functionality in SOAMANAGER. For the later proceed as indicated below:



Press Add New Button,



After you can define the duration of the trace in seconds, and in order to reduce overhead in SMICM choose a value that can allow you to test.
Example 10h = 36000s.

You should refine the trace either by adding the interface name CO_WSPT_DOCUMENTOS_TRANSPORTE or choose a Username.


jueves, 16 de julio de 2015

Campos adicionales para acreedor / proveedor.

Para añadir campos adicionales de acreedor (lfa1, lfb1) he seguido estos 2 links:
  1. Custom Screen in Vendor Master
  2. Adding Customer Fields In Vendor Master
El primero no me acababa de funcionar a la hora de grabar y el segundo no me acaba de gustar lo que hace para dejar modificar los campos o no. He seguio lo que decía para activar las BADIS. Aqui explico lo que he hecho para poder grabar, he usado un grupo de funciones para el control del screen como hace el segundo link. 

Mi append lo he hecho para la LFB1 y le he llamado ZLFB1.

Me he creado un grupo de funciones ZBC_VENDOR con un dynpro 9000 y he puesto he cogido los campos de diccionario de LFB1.

Tiene como variables globales en LZBC_VENDORTOP
tables: zlfb1.data: gl_activity type aktyp.

La dynpro tiene   process before output.   module status_9000.

module status_9000 output.
* SET PF-STATUS 'xxxxxxxx'.
* SET TITLEBAR 'xxx'.
loop at screen.
*For XD01, It would be H
*For XD02, it would be V
*For XD03, it would be A. 
 if gl_activity = 'A'. " 
Display screen-input = '0'. 
 endif. 
 modify screen. 
 endloop.*
endmodule.

Y tiene 2 módulos de funciones.

function z_bc_vendor_screen_get.
*"----------------------------------------------------------------------
*"*"Interfase local
*"  EXPORTING
*"     REFERENCE(P_ZLFB1) TYPE  ZLFB1
*"----------------------------------------------------------------------

  move-corresponding zlfb1 to p_zlfb1.

endfunction.

function z_bc_vendor_screen_set.
*"----------------------------------------------------------------------
*"*"Interfase local
*"  IMPORTING
*"     REFERENCE(P_ACTIVITY) TYPE  AKTYP OPTIONAL
*"     REFERENCE(P_ZLFB1) TYPE  ZLFB1 OPTIONAL
*"----------------------------------------------------------------------
*
  move-corresponding p_zlfb1 to zlfb1.
  gl_activity = p_activity.
*
endfunction.

Y las implementos en los métodos de la BADI VENDOR_ADD_DATA_CS de la siguiente forma.

  method if_ex_vendor_add_data_cs~set_data.
*
    data: l_zlfb1 type zlfb1.
    move-corresponding  i_lfb1 to l_zlfb1.
*
    call function 'Z_BC_VENDOR_SCREEN_SET'
      exporting
        p_activity = i_activity
        p_zlfb1   = l_zlfb1.
*
  endmethod.

  method if_ex_vendor_add_data_cs~get_data.
    data: l_zlfb1 type zlfb1.
    call function 'Z_BC_VENDOR_SCREEN_GET'
      importing
        p_zlfb1 = l_zlfb1.
*
    move-corresponding l_zlfb1 to s_lfb1.
*
  endmethod.

method if_ex_vendor_add_data_cs~get_taxi_screen.
  if flt_val = 'Z1'.
    case i_taxi_fcode.
      when 'ZTAB1'.
      e_program = 'SAPLZBC_VENDOR'. "Grupo de funciones ZBC_VENDOR
      e_screen = '9000'.
      e_headerscreen_layout = 'B'.
    when others.
    endcase.
  endif.
endmethod.


Además para que si no hay datos de sociedad no salga la pestaña ZTAB1

  METHOD if_ex_vendor_add_data_cs~suppress_taxi_tabstrips.
*
    DATA: code   TYPE not_used_taxi_fcodes_tab,
          code_l LIKE LINE OF code.
*
    IF i_bukrs IS INITIAL.
      code_l = 'ZTAB1'.
      APPEND code_l TO code.
*
      e_not_used_taxi_fcodes = code.
    ENDIF.
*
  ENDMETHOD.

De la parte de Custo dejo aquí la pantalla de la SPRO en castellano.

jueves, 2 de julio de 2015

Leyendo fichero de la AL11 con caracter extraño # (hashtag).

Un compañero, Joan Zenon, tenía un problema al leer con OPEN DATA SET un fichero que tiene en el servidor. Tanto con la AL11 como al leer en el programa tenía carácter # al final. Estas cosas son por el fin de carro o fin de línea, pero intentado reemplazar con las constantes de la clase cl_abap_char_utilities no acababa de encontrar cual era. 

Al final lo ha solucionado con la función SCP_REPLACE_STRANGE_CHARS. Por defecto pone el punto (.) porque es 46 el valor que tiene el parámetro REPLACEMENT, si ponemos 32 deja un espacio.

martes, 21 de abril de 2015

Consumo de web services con xsd:dateTime (UTC) en SAP.

Para los web services que tienen tipo de datos xsd:dateTime, sap los transforma en el tipo sap XSDDATETIME_Z (Evento XSD (UTC): aaaa-mm-ddThh:ssZ [ext.]). Este tipo de dato guarda internamente la fecha, la hora y el huso horario.

Para poder pasar de UTC a fecha, hora y huso y viceversa podemos servirnos de guía de este código que he extraido de la clase de SAP cl_appointment. Prueba con este código.

Programa de ejemplo.

  DATA: l_tst TYPE xsddatetime_z, "LIKE scappt-tst_from,
        l_zone TYPE tznzone,      "LIKE scappt-zone_from,
        l_date TYPE datum,        "LIKE scappt-date_from,
        l_time TYPE sytime.       "LIKE scappt-time_from.

  CLEAR: l_tst, l_zone, l_date, l_time.
*
  GET TIME STAMP FIELD l_tst.
  l_zone = 'CET'."No es necesario si nos viene ya dentro del l_tst y nos lo resolvería el convert time. 
*
  WRITE: / 'UTC->fecha, hora, huso'.
*
  CONVERT TIME STAMP l_tst
           TIME ZONE l_zone
           INTO DATE l_date
                TIME l_time.
*
  WRITE: / 'TIME STAMP ', l_tst.
*
  WRITE: / 'ZONE ', l_zone.
  WRITE: / 'DATE ', l_date.
  WRITE: / 'TIME ', l_time.
*
  WRITE: /.
  WRITE: / 'fecha, hora, huso->UTC'.
*
  CLEAR: l_tst, l_zone, l_date, l_time.
*
  l_date = sy-datum.
  l_time = sy-uzeit.
  l_zone = SY-ZONLO.
*
  CONVERT DATE l_date
  TIME l_time
  INTO TIME STAMP l_tst
  TIME ZONE l_zone.
*
  WRITE: / 'ZONE ', l_zone.
  WRITE: / 'DATE ', l_date.
  WRITE: / 'TIME ', l_time.
*
  WRITE: / 'TIME STAMP ', l_tst.
*

domingo, 19 de abril de 2015

Excepción de clase CX_AI_SOAP_FAULT (SoapFaultCode:4 ) al invocar un WebService.

Para este errores al intentar implementar un Web Services que había creado en .Net:

SoapFaultCode:4  System.Web.Services.Protocols.SoapException: Server did not
recognize the value of HTTP Header SOAPAction: .##   at
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()##   at
System.Web.Services.Protocols.SoapServerProtocol.Initialize()##   at
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type,
HttpContext context, HttpRequest request, HttpResponse response, Boolean&

abortProcessing)


    Excepción de clase CX_AI_SOAP_FAULT

Solución.

En el soamanager he ido al endpoint que había creado. Luego en pestaña "Operation Specific" hay que mirar que todas las operaciones tengan el SOAP Action informado. 

viernes, 17 de abril de 2015

Excepción de clase CX_AI_SOAP_FAULT (SoapFaultCode:3 ) al invocar un WebService.

Para estos 2 errores al intentar implementar un par Web Services que había creado en .Net:

Error 1.

SoapFaultCode:3  The header 'Action' from the namespace
http://schemas.xmlsoap.org/ws/2004/08/addressing' was not understood by the
ecipient of this message, causing the message to not be processed.  This
rror typically indicates that the sender of this message has enabled a
ommunication protocol that the receiver cannot process.  Please ensure that
he configuration of the client's binding is consistent with the service's
inding.

   Excepción de clase CX_AI_SOAP_FAULT

Error 2.

SoapFaultCode:3  System.Web.Services.Protocols.SoapHeaderException: SOAP
header Action was not understood.##   at
System.Web.Services.Protocols.SoapHeaderHandling.
SetHeaderMembers(SoapHeaderCollection headers, Object target,
SoapHeaderMapping[] mappings, SoapHeaderDirection direction, Boolean client)##
at System.Web.Services.Protocols.SoapServerProtocol.CreateServerInstance()##
at System.Web.Services.Protocols.WebServiceHandler.Invoke()##   at
System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

    Excepción de clase CX_AI_SOAP_FAULT

Solución.

En el soamanager he ido al endpoint que había creado. Luego en pestaña Messaging y en Message ID Protocol lo he cambiado a "SAP Message ID".