jueves, 22 de enero de 2015

Manejar campos a medida en pedidos de venta

Es muy común añadir campos a medida o "campos Z" a los pedidos de venta de SAP para poder adaptar SAP a los procesos de negocio del cliente. Si se quiere añadir campos a medida, basta con crear un append a la tabla correspondiente:

  • VBAK si son campos a medida para la cabecera del pedido de ventas.
  • VBAP  si son campos a medida para las posiciones del pedido de venta.
  1. Desde la transacción SE11, dentro de la tabla correspondiente pulsamos el botón APPEND
  2. Creamos un nuevo append y añadimos nuestros campos a medida.
  3. Guardad y activar.

Crear un nuevo append a la tabla
Nuevos campos a medida para la tabla VBAP
ATENCIÓN: Si añadís campos a través de append a las tablas estándar, SAP recomienda que el nombre del campo empiece por dos ZZ o dos YY, si no, os saltara una advertencia al activar el append a la tabla como me acaba de pasar a mi al utilizar una sola Z.

Aviso: el nombre del campo debería empezar por ZZ o YY

El problema surge cuando queremos gestionar estos campos con alguna bapi de ventas como:

  • SD_SALESDOCUMENT_CREATE
  • BAPI_SALESORDER_CHANGE
  • BAPI_SALESORDER_CREATEFROMDAT2
  • .... y más que hay....

¿Donde están nuestros campos a medida? ¿ como puedo usarlos en estas bapis?
Para estas bapis, los campos a medida se gestionan a través del parámetro EXTENSIONIN.

Primero, añadir los nuevos campos a las siguientes tablas a través de un APPEND:

Si son campos a medida en las posiciones del pedido de venta:
  • BAPE_VBAP
  • BAPE_VBAPX
  • VBAPKOZ
  • VBAPKOZX
Si son campos a medida en la cabecera del pedido de venta:
  • BAPE_VBAK
  • BAPE_VBAKX
  • VBAKKOZ
  • VBAKKOZX
NOTA  MUY IMPORTANTE
En las estructuras BAPE_VBAK/BAPE_VBAP todos los campos deben ser de tipo CHAR sino cuando más adelante rellenéis la estructura de la bapi, los campos numéricos saldrán con caracteres extraños como &# y no coincidirán las longitudes.

Por ejemplo:

  •  Un campo DEC 15 con 3 decimales , lo definiremos como CHAR de 15
  •  Un campo INT de longitud, lo definiremos como CHAR de 8.



En las estructuras  BAPE_VBAPX / BAPE_VBAKX los campos deben ser CHAR1 (char de long. 1)
En las estructuras  VBAPKOZX o VBAKKOZX los campos deben ser CHAR1 (char de long. 1)

Centrándonos en el ejemplo, ampliamos las tablas para posiciones de pedido:
BAPE_VBAP - todos los campos son de tipo CHAR
BAPE_VBAPX - todos los campos son de tipo CHAR
VBAPKOZ
VBAPKOZX

Con esto hemos terminado la parte de las estructuras que necesitamos.
Ahora vamos con el código.

EXTENSIONIN es de tipo BAPIPAREX, su estructura es la siguiente:

Estructura BAPIPAREX
En el primer campo indicamos que estructura vamos a pasarle BAPE_VBAP o BAPE_VBAPX
En los siguientes campos guardamos los valores de los campos concatenados como un solo registro.
Lo mejor es utilizar el método fill_container_c de la  cl_abap_container_utilities.

Aquí os dejo un ejemplo para rellenar la estructura EXTENSIONIN:

DATA: wl_vbape  TYPE  bape_vbap,
      wl_vbapex TYPE  bape_vbapx.

DATA: tl_extin type STANDARD TABLE OF bapiparex.

FIELD-SYMBOLS: <fs_extin> TYPE bapiparex.

wl_vbape-VBELN = wg_vbeln.   "nº de documento de ventas
wl_vbape-POSNR = wg_posnr.   "nº de posición

wl_vbapex-VBELN = wg_vbeln.  "nº de documento de ventas
wl_vbapex-POSNR = wg_posnr.  "nº de posición

wl_vbape-zzcampo1 = 'prueba'.
wl_vbape-zzcampo2 = 'de campos'.
wl_vbape-zzcampo3 = 'a medida'.

wl_vbapex-zzcampo1 = 'X'.   "o ABAP_TRUE si usais TYPE-POOLS: ABAP.
wl_vbapex-zzcampo2 = 'X'.
wl_vbapex-zzcampo3 = 'X'.

APPEND INITIAL LINE TO it_extin ASSIGNING  <fs_extin>.
<fs_extin>-structure = 'BAPE_VBAP'.

*si parecen caracteres extraños, revisar que todos los campos de la estrc son CHAR
cl_abap_container_utilities=>fill_container_c( EXPORTING im_value  = wl_vbape
                                               IMPORTING ex_container = <fs_extin>+30 ).


APPEND INITIAL LINE TO it_extin ASSIGNING  <fs_extin>.
<fs_extin>-structure = 'BAPE_VBAPX'.

cl_abap_container_utilities=>fill_container_c( EXPORTING im_value  = wl_vbapex
                                               IMPORTING ex_container = <fs_extin>+30 ).

* ya podemos usarlo en la bapi:
    CALL FUNCTION 'SD_SALESDOCUMENT_CREATE'
      EXPORTING
        sales_header_in      = wa_so_hearder
        sales_header_inx     = wa_so_hearderx
        testrun              = test
      IMPORTING
        salesdocument_ex     = wa_saorder
      TABLES
        return               = lt_return
        sales_items_in       = it_items
        sales_partners       = it_fi
        extensionin          = it_extin. "<Campos a medida del pedido


Notas relacionadas:
Note 143580 - Information on SD BAPIs and customer enhancement