CREATING VOFM CUSTOM ROUTINE

Te has preguntado alguna vez: ¿Cómo se crea una fórmula que realiza el cálculo del precio? 
¿Cómo se asigna la fórmula a una clase de condición de algún esquema de cálculo?

Si tienes dudas sobre este punto y/o tienes curiosidad de saber cómo es el procedimiento... 
Este publicación es para ti, te animo a que lo leas con ejemplos en imágenes.

En SAP los precios se determinan mediante esquemas de cálculo

Escenario:
Para nuestro ejemplo trataremos la clase de condición ZK25 (Descuento MAGALEXSIS)

Objetivo: 
Modificar el cálculo del valor neto según la determinación de precios de la clase de condición.

Regla del Negocio: 
Consideraremos el mayor descuento de la clase de condición


Veremos los siguientes puntos:

  1. Crear una fórmula desde la transacción VOFM. 
  2. Por configuración, asignaremos la fórmula a una clase condición de un esquema de cálculo.
  3. Por configuración, definiremos las secuencias de acceso
  4. En el código fuente de la fórmula modificaremos el valor resultante de la clase de condición.
  5. Por la transacción VA21 simularemos crear una oferta y comprobaremos como cambia el resultado final para la clase de condición en análisis.
1. Crear una fórmula desde la Tcode VOFM


A modo de ejemplo, la fórmula es 941 y será aplicado a la clase condición ZK25 
Grabamos y activamos
Nota: Al momento de crear la formula nos solicitará una clave de acceso.

Por las tablas TFRM y TFRMT puedes visualizar la fórmula creada, veamos:

TFRM: Rutinas FORM p.condiciones/fórmulas/transporte datos

TFRMT: Rutinas form p.condiciones/fórmulas/transporte datos: Textos


 2. Asignaremos la fórmula a una clase condición de un esquema de cálculo.

Ingresamos a la T-code SPRO
Comercial/Funciones básicas/Determinación de Precio/Control de la determinación de precios/Definir y asignar esquemas de cálculo

Luego seleccionamos 'Actualizar esquema de cálculo'

El sistema nos mostrará una vista como la siguiente imagen:

clic en el botón 'Posicionar' y seleccionamos un esquema de cálculo.
 En mi caso seleccionaré el esquema de cálculo ZMAG4L


En la sección del panel izquierdo, doble clic en 'Control':

Como se observa en la imagen para el esquema de cálculo ZMAG4L donde la clase de condición es ZK25 le asignamos la fórmula de cálculo 941 y grabamos.

Estos datos se pueden verificar en las siguientes tablas :
T638S


T683T

3. Definir secuencias de acceso

Ingresamos a la t-code SPRO
Comercial/Funciones básicas/Determinación de Precio/Control de la determinación de precios/Definir secuencias de acceso.

Seleccionamos la clase de condición, en mi caso es ZK25

Clic en 'Accesos' para ver las tablas de las secuencias de acceso

Indicador: Acceso exclusivo a la condición
Indicador que controla, que tras el acceso correcto a un registro de una clase de condición dentro de una secuencia de acceso, no se busquen otros registros.

Si deseamos acceder a cada tabla sólo debemos de añadir  la letra 'A' ejemplo:
514 => A514
513 => A513
510 => A510
512 => A512
516 => A516

TABLA: A514 (Org.Ventas/Can.distr./Material) 

TABLA: A513 (Org.Ventas/Can.distr./Marca/SCode/Mode/DCode/CCom/Gr.mater.1)

TABLA: A510 (Org.Ventas/Can.distr./Gr.mater.1)

TABLA: A512 (Org.Ventas/Can.distr./Marca/SCode/Mode/DCode/CCom)

 TABLA: A516 (Org.Ventas/Material)

Tabla: KONP (Condiciones posición)

4. En el código fuente de la fórmula
 modificaremos el valor resultante de la clase de condición


FORM FRM_KONDI_WERT_941.
*&-------------------------------------------------------------------------------------------&*
* INCLUDE..............................: RV64A941                                                          *
*&-------------------------------------------------------------------------------------------&*
* TITULO.................................: Fórmula 41                                                          *
* DESCRIPCION.....................: Cálculo del importe para Cl.Cond. ZK25           *
* MODULO..............................: SD                                                                       *
* CONSULTOR SAP-ABAP...: Alex Alcántara                                                    *
* VERSION...............................: 1                                                                         *
*&-------------------------------------------------------------------------------------------&*

*---------------------------------------------------------------------------------------*
*CONSTANTS
*---------------------------------------------------------------------------------------*

CONSTANTS: lc_a TYPE kinak VALUE 'A',
lc_i TYPE sign VALUE 'I',
lc_v TYPE kappl VALUE 'V',
lc_eq TYPE option VALUE 'EQ',
lc_zk25 TYPE kscha VALUE 'ZK25',
lc_zp21 TYPE kscha VALUE 'ZP21'.

*---------------------------------------------------------------------------------------*
*LOCAL TYPES
*---------------------------------------------------------------------------------------*

TYPES: BEGIN OF lty_clvcond,
knumh type knumh,
END OF lty_clvcond,

BEGIN OF lty_konp,
knumh type knumh,
kopos type kopos,
kappl type kappl,
kschl type kscha,
kbetr type kbetr_kond,
END OF lty_konp.

**---------------------------------------------------------------------------------------*
**INTERNAL TABLES
**---------------------------------------------------------------------------------------*

DATA: ltd_clvcond TYPE STANDARD TABLE OF lty_clvcond,
ltd_konp TYPE STANDARD TABLE OF lty_konp,
ltd_xkomv TYPE STANDARD TABLE OF komv.

**---------------------------------------------------------------------------------------*
**FIELD-SYMBOLS
**---------------------------------------------------------------------------------------*

FIELD-SYMBOLS: <ltd_clvcond> LIKE LINE OF ltd_clvcond,
<xkomv> LIKE LINE OF xkomv,
<ltd_konp> LIKE LINE OF ltd_konp,
<ltd_xkomv> LIKE LINE OF ltd_xkomv.

**---------------------------------------------------------------------------------------*
**RANGES
**---------------------------------------------------------------------------------------*

RANGES: lr_knumh FOR a512-knumh.


**---------------------------------------------------------------------------------------*
**PROCESS LOGIC FOR FORMULA 41 (ZK25)
**---------------------------------------------------------------------------------------*

**---------------------------------------------------------------------------------------*
**A514
**Org.Ventas/Can.distr./Material
**---------------------------------------------------------------------------------------*
SELECT knumh
INTO TABLE ltd_clvcond
FROM a514
WHERE kappl = lc_v
AND kschl = lc_zk25
AND vkorg = komk-vkorg
AND vtweg = komk-vtweg
AND matnr = komp-matnr
AND datbi GE komk-prsdt
AND datab LE komk-prsdt.

**---------------------------------------------------------------------------------------*
**A513
**Org.Ventas/Can.distr./Marca/SCode/Mode/DCode/CCom/Gr.mater.1
**---------------------------------------------------------------------------------------*
IF komp-prodh IS NOT INITIAL.
 SELECT knumh
  APPENDING TABLE ltd_clvcond
  FROM a513
  WHERE kappl = lc_v
   AND kschl = lc_zk25
   AND vkorg = komk-vkorg
   AND vtweg = komk-vtweg
   AND prodh1 = prodh-prodh1
   AND prodh2 = prodh-prodh2
   AND prodh3 = prodh-prodh3
   AND zzmvgr1 = komp-zzmvgr1
   AND datbi GE komk-prsdt
   AND datab LE komk-prsdt.
ENDIF.

**---------------------------------------------------------------------------------------*
**A510
**Org.Ventas/Can.distr./Gr.mater.1
**---------------------------------------------------------------------------------------*
SELECT knumh
APPENDING TABLE ltd_clvcond
FROM a510
WHERE kappl = lc_v
AND kschl = lc_zk25
AND vkorg = komk-vkorg
AND vtweg = komk-vtweg
AND zzmvgr1 = komp-zzmvgr1
AND datbi GE komk-prsdt
AND datab LE komk-prsdt.

**---------------------------------------------------------------------------------------*
**A512
**Org.Ventas/Can.distr./Marca/SCode/Mode/DCode/CCom
**---------------------------------------------------------------------------------------*
IF komp-prodh IS NOT INITIAL.
SELECT knumh
APPENDING TABLE ltd_clvcond
 FROM a512
 WHERE kappl = lc_v
  AND kschl = lc_zk25
  AND vkorg = komk-vkorg
  AND vtweg = komk-vtweg
  AND prodh1 = prodh-prodh1
  AND prodh2 = prodh-prodh2
  AND prodh3 = prodh-prodh3
  AND datbi GE komk-prsdt
  AND datab LE komk-prsdt.
ENDIF.

**---------------------------------------------------------------------------------------*
**A516
**Org.Ventas/Material
**---------------------------------------------------------------------------------------*
SELECT knumh
 APPENDING TABLE ltd_clvcond
 FROM a516
 WHERE kappl = lc_v
  AND kschl = lc_zk25
  AND vkorg = komk-vkorg
  AND matnr = komp-matnr
  AND datbi GE komk-prsdt
  AND datab LE komk-prsdt.

**---------------------------------------------------------------------------------------*
**Agrupamos todas las Clv.Condición (KNUMH)
**---------------------------------------------------------------------------------------*
FREE lr_knumh.
CLEAR lr_knumh.
REFRESH lr_knumh[].

lr_knumh-sign = lc_i.
lr_knumh-option = lc_eq.
LOOP AT ltd_clvcond ASSIGNING <ltd_clvcond>.
  lr_knumh-low = <ltd_clvcond>-knumh.
  APPEND lr_knumh TO lr_knumh.
ENDLOOP.

**---------------------------------------------------------------------------------------*
**Para cada Clv.Cond. KNUMH consultamos su porcentaje (KBETR) en la tabla KONP
**---------------------------------------------------------------------------------------*

SELECT knumh kopos kappl kschl kbetr
  INTO TABLE ltd_konp
  FROM konp
  WHERE knumh IN lr_knumh.
 IF sy-subrc EQ 0.
    ltd_xkomv[] = xkomv[].

    SORT ltd_konp BY kbetr.
    READ TABLE ltd_konp ASSIGNING <ltd_konp> index 1.
    IF sy-subrc eq 0.
         xkomv-kbetr = <ltd_konp>-kbetr.
         MODIFY xkomv TRANSPORTING kbetr."Modifica el porcentaje(%) para ZK25

         READ TABLE ltd_xkomv ASSIGNING <ltd_xkomv> with key kschl = lc_zp21.
         IF sy-subrc eq 0."Toma el valor de ZK21 (Precio de Lista)
              xkomv-kwert = <ltd_xkomv>-kwert * ( xkomv-kbetr / 10 ).
              MODIFY xkomv TRANSPORTING kwert."Modifica el valor para ZK25
         ENDIF.
     ENDIF.
 ENDIF.
ENDFORM



5. Por la transacción VA21 simularemos crear una Oferta 
Comprobaremos como cambia el resultado final para la clase de condición en análisis.

Tcode: VA21 (Crear Oferta)

Luego ingresamos el Solicitantes, el material, la cantidad, la unidad de medida 
Luego dentro de la pestaña Solicitante, ingresamos el dato del Centro
Si deseamos, podemos ponerle un breakpoint externo dentro de la línea del código de la fórmula para ver como accede a la data.

Por ejemplo, veamos el siguiente debug:
Una vez puesto el breakpoint externo, luego de ingresar el dato del Centro y presionar la tecla Enter, ingresará al Debug.

Observamos que ha ingresado al Debug y la primera consulta que realizará será a la tabla A514

Los valores encontrados para el campo KNUMH (Nº registro condición) lo iremos almacenando en la tabla interna LTD_CLVCOND

La segunda consulta que realizará, será a la tabla A513
Para nuestro ejemplo, de la consulta a la tabla A513 no se obtuvo data

La tercera consulta que realizará será a la tabla A510
Para nuestro ejemplo, de la consulta a la tabla A510 tampoco se obtuvo data

La cuarta consulta que realizará será a la tabla A512
Para nuestro ejemplo, de la consulta a la tabla A512 si encontramos data.


Los valores encontrados para el campo KNUMH (Nº registro condición) se va almacenando en la tabla interna LTD_CLVCOND

Ahora tenemos 2 registros

La quinta consulta que realizará, será a la tabla A516
Para nuestro ejemplo, de la consulta a la tabla A516 si encontramos data.

Los valores encontrados para el campo KNUMH (Nº registro condición) se va almacenando en la tabla interna LTD_CLVCOND
Ahora tenemos 3 registros


Agrupamos todos los Nro registro de condición en LR_KNUMH
la cual ha sido definido de la siguiente manera:
RANGES: LR_KNUMH FOR KONP-KNUMH

Para cada N° registro condición (KNUMH) obtenemos los porcentajes de descuentos de la tabla KONP

Visualizamos los datos obtenidos de la KONP
Importante:
Por regla de negocio elegiremos el porcentaje con mayor descuento
En nuestro caso elegiremos el descuento del 25% 
(LTD_KONP-KBETR = -250.00)

Antes, visualizaremos los datos que viene por defecto en la tabla interna XKOMV
Observamos que para la clase de condición ZK25 el Precio que viene por defecto es -62.88
(Ver: XKOMV-KWERT para XKOMV-KSCHL = ZK25)

Estos valores que vienen por defecto en la tabla interna XKOMV lo pasamos a una tabla interna temporal llamada LTD_XKOMV como se ve en la línea 189
Luego ordenaremos de menor a mayor la tabla interna LTD_KONP la cual contiene los porcentajes de manera que nuestro primer registro será el que tenga el mayor descuento

Observar la línea 194
Hemos leído el primer registro de la tabla interna LTD_KONP y como vemos tenemos el dato del mayor descuento, este valor será el que actualicemos en la variable XKOMV-KBETR

observemos:
Antes:

Después:
En este caso han observado que no hubo ningún cambio...
 Ya que el porcentaje que existía en la variable XKOMV-KBETR era el mismo del valor a ser reemplazado <LTD_KONP>-KBETR

Pero, ahora observemos como si será modificado el importe

Antes:


Después:

Finalmente, salimos del Debug y visualizamos las Condiciones:


Observamos que ahora para nuestro propósito la clase de condición ZK25 ya trae el  precio considerando el mayor descuento.
Valor condición: -65.50 PEN



Observamos que el Precio Neto (NETW) es 166.53 PEN

Para comprobar el cálculo, si deseamos podemos abrir un excel y colocar los importes.

Comprobamos que el cálculo es el correcto.

Nos vemos en el siguiente Blog ;)
MAGALEX

Comentarios

Entradas populares de este blog

Modificando Vista de Actualización SM30

User Exit para VA01 y VA02

Buttons and events in ALV GRID and ALV GRID OO