Esta serie de post tienen como objetivo ayudar a todos los desarrolladores de Acumatica en Latino América a iniciar, además de ahorrarles algunos dolores de cabeza. Para esta serie de tutoriales usaremos la versión 2018 R2.

Primero veremos los conceptos básicos del framework de Acumatica, DAC y Graph. Acumatica tiene una clara separación de la presentación (Views), la lógica de negocios (Graph) y la capa de persistencia (DAC)

DAC (Data Access Classes)

Un DAC es una clase que implementa la interfaz IBqlTable y representa un modelo de la tabla en la base de datos, en donde cada campo es declarado dos veces e implementa la interfaz IBqlField. Sus campos son declarados de la siguiente manera:

  • Como un type, el cual es un campo usado por las sentencias BQL.
  • Como valor, este es mapeado en la base de datos.

Existen ciertas reglas que debe seguir un DAC.

  • El nombre debe ser el mismo que el de la tabla que representa (Case sensitive)
  • Los nombres de los campos deben estar igualmente mapeado en la tabla con el mismo nombre.
  • Debes asegurarte que los nombres de las tablas y columnas sean identificadores válidos de C#.
  • No uses el guión bajo (_ underscore) para los nombres, pues son reservados para funciones internas del framework.
  • Deben implementar el atributo Serializable

Así es como se ve un DAC

[Serializable]
public class Product : PX.Data.IBqlTable
{
    public abstract class productID : PX.Data.IBqlField { }
    [PXDBIdentity(IsKey = true)]
    public virtual int? ProductID { get; set; }
   
    public abstract class availQty : PX.Data.IBqlField { }
    [PXDBDecimal(2)]
    public virtual decimal? AvailQty { get; set; }

    public abstract class bookedQty : PX.Data.IBqlField { }
    [PXDBDecimal(2)]
    public virtual decimal? BookedQty { get; set; }
}

Observemos que el campo ProductID está declarado dos veces , primero como una clase abstracta que implementa la interfaz IBqlField , esta declaración es usada para formar sentencias BQL (Calma explicamos que es BQL más adelante), y como un tipo entero nullable (int?) el cual es usado para asignar u obtener valores (set y get). Otro punto importante de resaltar es que la declaración de tipo entero tiene asignado un atributo PXDBIdentity, esta clase de atributos determinan el tipo de dato al que pertenecen en la base de datos y que comportamiento usan, concretamente PXDBIdentity es un tipo entero autoincremental.

Al igual que ProductID, BookedQty sigue las mismas reglas, cambiando solamente el tipo de dato que almacena, en este caso guarda un tipo decimal definido por el atributo PXDBDecimal y por la declaración.

BQL (Business Query Language)

Acumatica se basa en un ORM propio para acceder a la base de datos desde la capa de lógica de negocios. El framework provee de un conjunto de operaciones (CRUD) y métodos para ejecutar instrucciones SQL complejas. Dichas instrucciones son implementadas en un lenguaje propio que acumatica llama BQL (Business Query Language). BQL está escrito en C# y basado en una sintaxis de clases genéricas, pero mantiene una gran similitud con la sintaxis de SQL

Veamos un ejemplo de BQL y SQL. Supongamos que queremos obtener todos los registros de la tabla Product donde existan productos disponibles y estos sean mayor a los productos reservados.

En SQL esto sería de la siguiente manera:

SELECT * FROM Product
    WHERE Product.AvailQty IS NOT NULL
        AND Product.AvailQty > Product.BookedQty

En BQL se traduce así.

PXSelect<Product,
       Where<Product.availQty, IsNotNull,
           And<Product.availQty, Greater<Product.bookedQty>>>>

Lo sé, lo sé, los pico paréntesis son confusos (al inicio son una pesadilla) de escribir pero ¿que vamos a hacerle?(incluso a mi me causo problemas postear la sintaxis en el blog), así lo definieron,  la buena noticia es que acumatica liberó una herramienta llamada acuminator que te ayuda a sobrellevar este tema, además de que en las siguientes versiones (2019) este formato es sustituido.

Veamos el lado bueno, acumatica puede ser integrado con dos bases de datos, My SQL o Microsoft SQL Server, y ahi es donde BQL es conveniente por que sin importar la implementación de SQL de las bases de datos, BQL automáticamente  transforma a sentencia SQL nativas de cada una de las bases de datos. Más adelante veremos la forma de consultar esta transformación.

Hasta aquí el primer post de los conceptos básico de DAC y BQL. En el siguiente post veremos lo que es un Graph y su función dentro de Acumatica.