ADempiere: Codigo Comun

Revisando mis notas me di cuenta que me salte un punto importante al hablar de la arquitectura de ADempiere, y es que para el proceso de extensión del ERP se cuenta con códigos comunes que pueden ser usados desde el código como dentro del diccionario de datos. Al escribir sobre los códigos comunes voy a hablar acerca de reglas de validación y referencias desde el diccionario de datos.

Variables de Contexto

Estas son variables globales que pueden usarse en todo el sistema, o para una ventana o tabla especifica.
Todas las variables de contexto se pueden ver desde Herramientas » Preferencias

Desde el código o programaticamente las puedes llamar como se muestra en este ejemplo (se invocan usando el operador #):
- Invocando la variable de contexto AD_Role_ID
  int rolactual_id =Env.getContextAsInt(ctx, "#AD_Role_ID");
Desde un campo (ad_field) puedes invocar una variable de contexto desde el campo "displaylogic" llamándola entre el operador @, como se muestra en este ejemplo:
@$Element_PJ@='Y' (Muestra el campo si el elemento 'Proyecto' del Esquema Contable esta activo)
Todos los campos en una ventana tienen su variable de contexto. Podemos usarlas de distintas maneras ya sea para validar cuando se muestra una pestaña o un campo, para definir el valor por defecto de un campo, entre otras.
Ejemplos:
- Mostrar una pestaña solo si el campo IsEmployee='Y': En la ventana "Ventana, Pestaña & Campo", en la pestaña "Pestaña", en el campo "DisplayLogic" (Lógica de Despliegue) escribimos: @IsEmployee@='Y' - El valor de este campo lo tendremos en la pestaña superior a la que estamos validando.
- Para validar que la pestaña sea de solo lectura dependiendo el valor de un campo colocamos en el campo "ReadOnlyLogic" (Lógica de solo lectura) el valor que debe tener la variable de contexto: @Processed@='Y' 
- Para validar que se muestre un campo dependiendo del valor que se le asigne a otro campo, colocamos desde la pestaña "Campo", en el campo "DisplayLogic" la condición correspondiente: @C_BP_Group_ID@=1000000
 También se pueden usar para indicar el valor predeterminado de un campo, Ej.:
@#AD_Org_ID@ - Toma por defecto la organización que se escogió al inicar el sistema.

Los operadores usados para comprobar el valor de la variable pueden ser:
  • = (Igualar)
  • ! (Negar o diferenciar)
  •  > (Mayor que)
  • < (Menor que)
  • <= (Mayor o igual)
  • >= (Menor o igual)
  • | (O - para filtrar: un valor u otro)
  • & (Y - para filtrar: un valor y otro)
Podemos usar las variables de contexto dentro de las referencias (AD_Reference), cuando estas son del tipo "Validacion de Tabla", desde el campo "Clausula WHERE Sql" invocamos la variable de contexto para indicarle el valor en la condicion del sql, ejemplo:
C_Charge.AD_Client_ID=@#AD_Client_ID@ --Esto seria interpretado por el sistema como: SELECT * FROM C_Charge WHERE C_Charge.AD_Client_ID=<id_del_cliente_activo>
Ademas, las podemos usar desde las reglas de validacion, llamandolas en el campo "Codigo de Validacion", ejemplo:
AD_Client.AD_Client_ID=@#AD_Client_ID@
Este codigo de validacion formara parte de la clausula WHERE de la sentencia Sql que usa el sistema para el filtrado de los datos.

SQL

Ya hemos visto que podemos usar sentencias sql dentro del diccionario de aplicación en el campo código de validación, en las pestañas (campo: Clausula WHERE sql), en las referencias cuando son del tipo validación de tabla, y obviamente podemos usar sql al revés y al derecho en la codificación (cuando estamos creando clases). Algunas consideraciones importantes a tomar en cuenta al realizar las sentencias sql son las siguientes:
  • Cuando usas sql embebido (en los casos mencionados anteriormente) se recomiendo usar MAYÚSCULAS (UpperCase) para las palabras reservadas del sql, esto para no tener problemas con el Parser de sql.
    • SELECT, FROM, WHERE, AS, AND, OR, ON, INNER, JOIN, LEFT, OUTER, etc
  • Cuando uses JOIN en las sentencias el parser requerirá que encierres las clausulas del ON entre paréntesis ()
  • Preferiblemente usa la sintaxis de Oracle, esta sera traducida a la de postgres. Evita usar sintaxis única de postgres.
  • Cuando realices una sentencia que te trae un solo valor como resultado puedes capturarlo usando el método: DB.getSqlValue(). Ejemplo:
    • String sql = "SELECT COUNT(*) FROM C_Recurring_Run WHERE C_Recurring_ID=?";
      int current = DB.getSQLValue(get_TrxName(), sql, getC_Recurring_ID());
  • Cuando hagas sentencias como UPDATE, DELETE, INSERT usa el método DB.executeUpdate(). Ejemplo:
    • String sql = "UPDATE C_CashLine SET Processed='N' WHERE C_Cash_ID=" + getC_Cash_ID();
      int noLine = DB.executeUpdate (sql, get_TrxName());
  • Cuando hagas una consulta en la que necesitas traer valores múltiples, usas el PreparedStament y ResultSet. Ejemplo:
    • tring sql = "SELECT C_PaymentAllocate_ID FROM C_PaymentAllocate WHERE C_Payment_ID = ?";
      PreparedStatement pstmt = null;
      pstmt = DB.prepareStatement(sql, get_TrxName());
      pstmt.setInt(1, payment_ID);
      ResultSet rs = pstmt.executeQuery();
      while (rs.next()) {
         payment_allocate_ID = rs.getInt(1);
         /// ... more code
      }
      rs.close();
      pstmt.close();
El Parser de sql tiene sus condiciones especificas que lanzan una excepcion cuando la sentencia no esta de acorde a la sintaxis esperada. Algo que me ha pasado recientemente es que cuando hago sentencias en las que necesito usar dentro del WHERE el operador IN me lanza un mensaje de error porque en la programacion tienen el supuesto o la logica de que no se usa el IN dentro del WHERE. El mensaje de error que me lanza es el siguiente: AccessSqlParser.getTableInfo: Could not remove ON <mi sentencia sql>
Todavia no he descubierto como salir de este error, si alguien sabe si hay alguna mejor manera de hacer una sentencia sin usar IN o si es algo que me falta o si modifica el condigo del parser, por favor me ayudan para mejorar ;)

Mensajes

Esto es algo verdaderamente interesante en ADempiere. Cuando estes programando y necesitas lanzar cualquier mensaje al usuario lo puedes hacer creando el mensaje en AD_Message (con su respectiva traduccion) y luego invocarlo desde tu codigo de esta manera:
String mensaje = ""; 
mensaje = Msg.getMsg(Env.getCtx(), "<nombre del mensaje que creaste>")
Esto es una facilidad i18n que provee el sistema, muy buena por cierto, para estandarizar los mensajes que usas en tu codigo.

Comentarios

  1. Hola Angelica,
    Dios te bendiga,

    Excelente Blog Adempiere, Te Felicito. Comparto contigo mis experiencias con adempiere:

    http://bseni.blogspot.com

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

ADempiere: Configuración Inicial de la Compañía

Instalar Oracle Java 6 en Ubuntu