Motor de reglas de descuentos y recargos
En el presente instructivo se detallan todas las posibilidades de programar descuentos en una operación.
Introducción
El motor de Reglas de Descuentos es una herramienta muy potente que permite configurar en las Operaciones, reglas que afecten a los ítems (como al resto del documento) dependiendo de los campos que se seleccionaron en la Operación.
De esta forma se podrá configurar un pedido de venta para que dependiendo el producto, se modifique el precio del ítem o se agregue un ítem de promoción o se agregue un descuento al total del pedido. La definición de la regla se hace mediante unas instrucciones que permiten todas las combinaciones y resultados.
Configuración
Lenguaje
Tipo de datos
Scripting maneja 4 tipos de datos, de manera que una variable o atributo puede contener un valor de los siguientes tipos de datos:
- Tipo Numérico (permite almacenar números enteros y decimales, positivos y negativos)
- Tipo Fecha
- Tipo Cadena de caracteres
- Tipo Booleano
Operaciones aritméticas
Se pueden usar las 4 operaciones básicas entre tipos de datos numéricos:
- Suma
- Resta
- Multiplicación
- División
Variables
El scripting permite definir variables: el dato que se asigne a la variable define su tipo.
El identificador de la variable, es decir su nombre, puede contener cualquier carácter entre los siguientes : ‘A’…‘Z’ + ‘a’…‘z’ + ‘1’…‘0’ + ‘_’
Por ejemplo:
Precio_Producto es un nombre de variable válido.
Precio_Producto_2014 es un nombre de variable válido.
Precio+2015 no es un nombre de variable válido.
Ejemplos de cómo se definen las variables:
- precio = 100;
define la variable precio y le asigna el valor numérico 100
- precio = “100”;
define la variable precio y le asigna la cadena de caracteres “100”
- fecha = #01/02/2015#;
define la variable fecha y le asigna el valor fecha 1 de febrero de 2015
- fecha = “01/02/2015”;
define la variable fecha y le asigna la cadena de caracteres “01/02/2015”;
- fecha = 01/02/2015;
define la variable fecha y le asigna el valor numérico 0.0002, qué es el resultado de dividir 1/2 y luego dividir por 2015
Comparadores
Scripting permite usar cualquiera de los comparadores:
- == para determinar la igualdad
- != para determinar diferencia
-
= para determinar mayor o igual
- <= para determinar menor o igual
Expresión booleana
Es cualquier expresión que dé como resultado un valor verdadero o falso.
La expresión booleana surge de comparar dos expresiones, atributos o variables.
Por ejemplo:
resultado = (1 == 2) crea la variable resultado y le asigna el valor falso
resultado = (1 <= 2) crea la variable resultado y le asigna el valor verdadero
Precio = 100;
Precio_Máximo = 100*1.1;
resultado = (Precio <= Precio_Maximo AND Precio != 100) da como resultado falso, ya que se cumple la primera condición, pero no la segunda.
Estructura de decisión
Scripting permite la estructura de decisión IF
if(expresión booleana [OR | AND expresión booleana]) begin
sentencia;
[sentencia;]
endif;
Por ejemplo
Precio = 100;
Precio_Maximo = 100*1.1;
if (Precio <= Precio_Maximo AND Precio == 100) begin
Precio = Precio_Maximo;
endif;
El resultado de ejecutar estas sentencias será que la variable Precio ahora tiene el valor 110.
Tipos de Documento
Se debe configurar cuáles tipos de documento permiten el cálculo de reglas con una tilde “Acepta Reglas”.
Maestro de Reglas
Acceder al Maestro de Reglas desde App Builder→ Documentos→ Reglas
Solapa General
Cada regla indistintamente, si es de ítem o global, debe tener su código, su nombre y descripción y debe indicar si está activa o no.
Luego se debe elegir qué tipo de regla se quiere utilizar:
Global: Que sea una regla global significa que se va a modificar algo de la factura en su todo y no algo de un ítem.
Ítem: Esta regla va a modificar algo específico del ítem y contiene un log.
Vigencia: Se debe indicar una fecha de vigencia para la cual estarán disponibles los descuentos. Se ejecutará siempre y cuando la fecha se encuentre dentro de las fechas desde/hasta
Evento: Depende de la configuración del widget que va a desencadenar el evento dentro del tipo de documento que ejecutará la regla.
Orden: En caso de que se aplique más de una regla, se debe indicar cuál de ellas se calculará primero por orden. Son números correlativos.
Solapa Parámetros
Permite indicar los parámetros que se tendrán en cuenta a la hora de programar el descuento. Por ejemplo, si se quiere tener en cuenta la condición de pago, se agrega un parámetro CondPago que tenga como valor el código, o el nombre. El campo Tipo Java es para diferenciar entre texto y número.
Solapa Productos
Esta solapa es de utilidad solo cuando en el script de la regla se usa la función Evaluar Conjunto de Productos. Esta función no utiliza ningún parámetro. Lo que hace es evaluar cuántas veces se presenta el conjunto (relación productos-cantidad) definido en la fórmula con los ítems de la transacción y devuelve la cantidad de conjuntos.
Modo de uso
Botones en el maestro de Reglas
Toolbar superior
Editar Fórmula: abre el editor del script.
Actualizar Atributos: agrega o elimina atributos en caso de necesitarlo
En el editor de scripting
Incorporar Función: Trae todas las funciones posibles de usar incorporadas por la herramienta.
Una de las funciones Ejecutar Reglas, permite ejecutar una regla de tipo ítem desde una regla de tipo global.
Atributos: Los atributos pueden ser de tipo HEADER o de tipo ITEM. Esta lista contiene todos los atributos que se pueden usar en un documento y además trae los de los maestros. Ejemplo: HEADER.Producto.Codigo es el código del producto puesto en el maestro.
Check: Chequea si la sintaxis de la regla se encuentra bien.
Botones en las transacciones que utilizan Reglas
En la toolbar superior
Ejecutar reglas: se utiliza solo para las reglas globales, y funciona para poder ver cómo quedará la factura con los descuentos aplicados antes de guardar, ya que cada vez que se guarda también se ejecutan las reglas.
Dentro de los ítems
Log de ítems: solapa que muestra los registros generados por las reglas de ítems.
Cómo configurar reglas de tipo “Evento”
Reglas Evento Globales
Elegir un widget a partir del cual se desea que se ejecute la regla. Se puede configurar un OnChange, OnClick u OnExit (cuando se cambie el campo, cuando se haga click en el campo o cuando se salga del campo).
Particularizar ese widget y agregar lo siguiente:
userEvents=“onChange:aplicarReglaGlobalEvento;CODIGOREGLA”
Donde CODIGOREGLA se debe reemplazar por el código de la regla correspondiente.
Reglas Evento Items
La única diferencia entre la configuración de esta regla y la anterior es que en este caso se debe particularizar un widget que se encuentre dentro de los ítems y agregar lo siguiente:
userEvents=“onChange:aplicarReglaItemEvento;CODIGOREGLA”
Reglas Evento onInit
Esta regla se configura en el maestro igual que reglas globales por evento. La diferencia es que se ejecutan siempre al abrir la transacción
Los pasos a seguir son:
- Agregar en el del xml lo siguiente:
onInit=“aplicarReglaInit” en el
- Agregar dentro del bloque lo siguiente:
Si no existe ese bloque en el xml, se agrega y quedaría:
Ejemplos
Se detallan ejemplos de regla global por vigencia y de reglas de ítem por vigencia.
Regla global por vigencia
Descuento por Contado
Tiene una fecha desde 01/05/2015 y fecha hasta 31/05/2016 y Orden = 1 (es la única regla global configurada)
Los parámetros son:
*CondPago = CON (que equivale al código de la condición de pago Contado) y es de tipo Texto.
*Porcentaje = 10 y de tipo Número.
En la toolbar superior hay un botón Editar Fórmula que abre el editor del script.
El código de este ejemplo es:
if (HEADER.CondicionPago.Codigo == CondPago)
begin
AgregarItem();
ImporteTotal = SumarImportes(“1==1”);
ITEM.Producto.Codigo = “DESC”;
ITEM.Cantidad = 1;
ITEM.PrecioFinal = 0-(ImporteTotal*Porcentaje)/100;
ITEM.Descripcion = “Item de descuento por pagar al contado”;
endif;
Lo que hace es:
Primero se fija si la condición de pago coincide con la que tiene el código puesto en el parámetro CondPago.
Luego inicia el if…
Lo primero que hace dentro del if es agregar un ítem nuevo. Es importante saber que una vez que se inserta esta función, el cursor queda parado en ese ítem nuevo, por lo cual no es posible preguntar por otro ítem o por otra cosa que no sea dentro de ese ítem recién agregado.
Luego, se ingresan los datos que va a tener ese ítem. En este caso solo se ingresan los datos obligatorios para guardar la factura y además se le agrega una descripción. Es indistinto agregarlos en orden o no.
En ImporteTotal se inserta la función SumarImportes. Esta función necesita que se pase alguna condición entre los paréntesis. La condición podría ser que sume los importes sólo de determinados ítems, por ejemplo sólo los que tengan un código en particular. En este caso, la condición es 1==1 que equivale a verdad, por lo que se van a sumar los importes de todos los items.
Después se ingresa el código del producto que se quiere seleccionar en el ítem, la cantidad y luego el Precio. Para precio se puede diferenciar entre el PrecioBase y PrecioFinal. En este caso se usa el precio final que sería el equivalente al campo llamado Precio en la factura. Se le pasa 0-(ImporteTotal*Porcentaje)/100. El 0- es para que el resultado quede negativo. Otra manera de hacerlo podría ser multiplicando todo por -1. Después se le ingresa la descripción entre comillas. Cada vez que se quiere ingresar o comparar con un texto se lo debe introducir entre comillas.
Y para terminar el if, se pone endif al final.
Ejemplo de uso en el que se ejecutó la regla
Regla de ítem por vigencia
Las reglas de ítem se ejecutan cada vez que se cambia el producto, la cantidad o el precio. En caso de haberse ejecutado alguna regla que dependa de alguno de esos tres atributos (y se cambió algo que haga que la regla no se deba ejecutar más) ese tipo de cosas se deben agregar en la fórmula.
Ejemplo: Se ejecuta una regla si es que se quiere vender un producto en particular y completa el campo descuento 1. En caso de que se cambie el producto a uno distinto que no deba ejecutar esa regla, el campo no se vaciará a menos que así lo indique en el código de la regla.
Las reglas de ítem cuentan con la posibilidad de generar un log. Dentro de los ítems en una operación se habilitó una nueva solapa Log de Reglas.
Para agregar registros en esa solapa, las reglas de ítems deben especificarlo.Dentro del if que filtra la regla, se ingresa log(“”);. Va dentro del if porque, si no sé ejecuta la regla, no tiene sentido que se la loguee.
Descuento por Proveedor
Para este ejemplo, el tipo de documento que se utilice debe estar configurado para que utilice el campo descuento 1.
Solapa General
Solapa Parámetros
El valor del parámetro Proveedor corresponde al código de un proveedor que será tenido en cuenta para hacer el descuento.
El código de la regla es el siguiente:
if (HEADER.Organizacion.Codigo == Proveedor)
begin
ITEM.Descuento1 = Porcentaje;
ITEM.PrecioFinal = ITEM.PrecioBase - (ITEM.PrecioBase*Porcentaje)/100
log(“Se aplica regla de descuento: Se hace un 5% de descuento sobre el precio porque el proveedor es Mundaka”);
endif;
Lo que hace es: pregunta si el código de la organización seleccionada es igual a la establecida en el valor del parámetro Proveedor. En caso de serlo, empieza…
Setea en el campo de descuento 1 el valor del parámetro porcentaje.
Luego modifica el precio final haciendo el cálculo según lo que el usuario ingresa en el campo precio base y le hace el descuento.
Por último genera un registro para el log. Entre comillas se coloca lo que se quiere que quede registrado dentro de la solapa log de ítems.
Descuento por comprar más de 10 botes
Esta regla se acopla a la regla de ítem anterior, por lo tanto el orden es = 2.
Para este ejemplo, el tipo de documento que se utilice debe estar configurado para que utilice el campo descuento 2.
Solapa General
Solapa Parámetros
La fórmula de Regla es la siguiente:
if (ITEM.Producto.Codigo == “Botegrup” and ITEM.Cantidad >= Cantidad)
begin
ITEM.Descuento2 = Porcentaje;
ITytEM.PrecioFinal = ITEM.PrecioFinal - (ITEM.PrecioFinal*Porcentaje)/100
log(“Se hace un 10% de descuento sobre el precio por haber comprado más de 10:” + ITEM.Producto.Nombre);
endif;
else if (ITEM.Producto.Codigo != “Botegrup”)
begin
ITEM.Descuento2 = 0;
endif;
En este caso la fórmula tiene dos condiciones: Pregunta si el código del producto ingresado en el ítem es igual a Botegrup (en este caso está especificado pero se podría haber pasado por parámetro) y además si la cantidad registrada es mayor o igual al valor que se pasó en el parámetro Cantidad, entonces hace lo siguiente:
En el campo descuento 2 le setea el valor ingresado en el parámetro Porcentaje. Luego edita el precio final en base al valor que estaba puesto en el mismo campo precio final.
Se toma lo ingresado en precio final y no en el precio base porque si no, en caso de haberse ejecutado la regla anterior, anularía los cálculos. Luego inserta un registro en el log y termina el if.
Luego hay un else if. Esto se hace en caso de que se cambie el valor del producto luego de haberse ejecutado la regla, los cambios hechos vuelvan atrás. En este caso le setea nuevamente un 0 en el campo descuento 2.
Importante
Cuando se usan los campos de descuentos a partir de las reglas, esos campos no se comportan como lo harían en los casos que no ejecuten reglas. Los campos son utilizados como sea especificado en la fórmula. La fórmula pisa todo comportamiento natural que tendrían.