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
¿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:
- Crear una fórmula desde la transacción VOFM.
- Por configuración, asignaremos la fórmula a una clase condición de un esquema de cálculo.
- Por configuración, definiremos las secuencias de acceso
- En el código fuente de la fórmula modificaremos el valor resultante de la clase de condición.
- 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.
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
**---------------------------------------------------------------------------------------*
**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
Publicar un comentario