Mostrando entradas con la etiqueta bapis. Mostrar todas las entradas
Mostrando entradas con la etiqueta bapis. Mostrar todas las entradas

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

domingo, 8 de septiembre de 2013

Bapis para cambiar la unidad de medida

La unidad de medida base, es la base para la gestión de stock y evaluación. Las cantidades de material disponible o en almacén (cuantos) se cuentan utilizando la unidad de medida base. toda cantidad que este medida en otra unidad, se convierte a la unidad de medida base para el calculo.

Todo material en Sap, tiene asignada una unidad de medida base. Se puede ver la unidad de medida base asignada a un material en el maestro de materiales, transacción MM03, en la pestaña de Datos básicos 1.

Unidad de medida base para el material en le maestro de materiales
En la base de datos, esta información se encuentra en el campo  MARA-MEINS.

Se pueden definir otras unidades de medida alternativa para el material y su factor de conversión en el Maestro de Materiales -> Datos adicionales -> Unidades de medida.

Unidades de medida alternativa y su relación
La información sobre las unidades de medida alternativa esta almacenada en la tabla MARM: Unidades de medida para el material.

En Abap, cuando necesitemos realizar alguna conversion entre unidades de medida podemos utilizar:

MATERIAL_UNIT_CONVERSION

Esta bapi, convierte una cantidad de un material en unidades de medida base a una unidad de medida alternativa y viceversa. Es obligatorio que una de las dos unidades de medida implicadas en la conversión sea la unidad de medida base del material (MARA-MEINS).


*&---------------------------------------------------------------------*
*&      Form  convert_unit_con_material
*&---------------------------------------------------------------------*
*  pi_um_inicial / pi_um_final: 1 de ellas, debe ser la UMB del material
*&---------------------------------------------------------------------*
FORM convert_unit_con_material USING pi_matnr       TYPE mara-matnr
                                     pi_cantida_ini TYPE gsmng
                                     pi_um_inicial  TYPE t006-msehi
                                     pi_um_final    TYPE t006-msehi
                               CHANGING po_cantida_fin TYPE gsmng.

   call function 'MATERIAL_UNIT_CONVERSION'
         exporting
              input                = pi_cantida_ini
*              kzmeinh              = 'X'
              matnr                = pi_matnr
              meinh                = pi_um_inicial
              meins                = pi_um_final
*              type_umr             = '3'
         importing
              output               = po_cantida_fin
         exceptions
              conversion_not_found = 1
              input_invalid        = 2
              material_not_found   = 3
              meinh_not_found      = 4
              meins_missing        = 5
              no_meinh             = 6
              output_invalid       = 7
              overflow             = 8
              others               = 9.

  IF sy-subrc <> 0.
*   Mensaje de error
  ENDIF.

ENDFORM.

UNIT_CONVERSION_SIMPLE

Con esta bapi no es necesario especificar el material ni la unidad de medida base. Convierte la cantidad  que indiquemos de una unidad de medida a otra. También permite redondear el resultado.

Los factores de conversión de las unidades de medida se configuran en:
   SPRO -> Sap Netweaver -> Parametrizaciones generales -> Verificar unidades de medida

*&---------------------------------------------------------------------*
*&      Form  convert_unit_sin_material
*&---------------------------------------------------------------------*
FORM convert_unit_sin_material USING pi_cantida_ini TYPE gsmng
                                     pi_um_inicial  TYPE t006-msehi
                                     pi_um_final    TYPE t006-msehi
                               CHANGING po_cantida_fin TYPE gsmng.


  CALL FUNCTION 'UNIT_CONVERSION_SIMPLE'
    EXPORTING
      input                = pi_cantida_ini
*     NO_TYPE_CHECK        = 'X'
*     ROUND_SIGN           = ' '
      unit_in              = pi_um_inicial
      unit_out             = pi_um_final
    IMPORTING
*     ADD_CONST            =
*     DECIMALS             =
*     DENOMINATOR          =
*     NUMERATOR            =
      output               = po_cantida_fin
    EXCEPTIONS
      conversion_not_found = 1
      division_by_zero     = 2
      input_invalid        = 3
      output_invalid       = 4
      overflow             = 5
      type_invalid         = 6
      units_missing        = 7
      unit_in_not_found    = 8
      unit_out_not_found   = 9
      OTHERS               = 10.

  IF sy-subrc <> 0.
*   Mensaje de error
  ENDIF.

ENDFORM.                    "convert_unit_sin_material

RS_CONV_EX_2_IN_NO_DD

No es una bapi para conversión entre unidades. Convierte un string a tipo cantidad, muy útil cuando la fuente de los datos es un fichero de texto plano y necesitas convertir los datos para poder trabajar con ellos.

*&---------------------------------------------------------------------*
*&      Form  convert_to_quan
*&---------------------------------------------------------------------*
FORM convert_to_quan  USING    p_mengec TYPE c
                      CHANGING p_mengei LIKE marc-eisbe.


  CONDENSE p_mengec NO-GAPS.
  CALL FUNCTION 'RS_CONV_EX_2_IN_NO_DD'
    EXPORTING
      input_external                    = p_mengec
*   CONVERT                           =
*   CURRENCY                          = ' '
   IMPORTING
     output_internal                   = p_mengei
   EXCEPTIONS
     input_not_numerical               = 1
     too_many_decimals                 = 2
     more_than_one_sign                = 3
     ill_thousand_separator_dist       = 4
     too_many_digits                   = 5
     sign_for_unsigned                 = 6
     too_large                         = 7
     too_small                         = 8
     invalid_date_format               = 9
     invalid_date                      = 10
     invalid_time_format               = 11
     invalid_time                      = 12
     invalid_hex_digit                 = 13
     unexpected_error                  = 14
     input_too_long                    = 15
     no_decimals                       = 16
     invalid_float                     = 17
     illegal_type                      = 18
     conversion_exit_error             = 19
     OTHERS                            = 20.


ENDFORM.                    " convert_to_quan

jueves, 11 de octubre de 2012

Bapis para cambiar la moneda

En muchos  empresas  facturan con mas de una moneda ( euros, dolares ). En estos casos cuando tratamos los importes tenemos que tener en cuenta la moneda. Toda sociedad de una empresa tiene especificada una moneda local, que es la moneda por defecto con la que trabaja, viene indicada en la tabla T001-WAERS.


Los factores de cambio entre las monedas salen de la tabla TCURF.



Si tenemos el importe en moneda local y queremos cambiar a otra moneda:

  CALL FUNCTION 'CONVERT_TO_FOREING_CURRENCY'
         EXPORTING
             CLIENT                             = SY-MANDT
             date                                    = SY-DATUM
             foreign_currency                 = wl_foreing_waers
             local_amount                      = wl_item_data-netpr
             local_currency                    = wl_item_data-waers
*           RATE = 0
*           TYPE_OF_RATE              = 'M'
*           READ_TCURR                 = 'X'
        IMPORTING
             FOREING_AMOUNT          = wl_foreing_netpr
        EXCEPTIONS
             NO_RATE_FOUND           = 1
             OVERFLOW                      = 2
            NO_FACTORS_FOUND    = 3
            NO_SPREAD_FOUND       = 4
            DERIVED_2_TIMES            = 5
            OTHERS                               = 6.

  
IF sy-subrc <> 0.
         MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
             WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
   ENDIF.




Si tenemos el importe una moneda diferente a al local y queremos convertirlo a moneda local:

  CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
         EXPORTING
             CLIENT                             = SY-MANDT
             date                                    = SY-DATUM
             foreign_amount                   = wl_item_data-netpr
             foreign_currency                 = wl_item_data-waers
             local_currency                    = wl_waers
*           RATE = 0
*           TYPE_OF_RATE              = 'M'
*           READ_TCURR                 = 'X'
        IMPORTING
             LOCAL_AMOUNT          = wl_local_netpr
        EXCEPTIONS
             NO_RATE_FOUND           = 1
             OVERFLOW                      = 2
            NO_FACTORS_FOUND    = 3
            NO_SPREAD_FOUND       = 4
            DERIVED_2_TIMES            = 5
            OTHERS                               = 6.

  
IF sy-subrc <> 0.
         MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
             WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
   ENDIF.