Saltar al contenido principal

Guía de Desarrollador

Introducción

Elastic Business expone APIs REST para integración con sistemas externos y customización.

Arquitectura Técnica

Stack Tecnológico

Frontend
├── HTML5 / CSS3
├── JavaScript
└── AJAX

Backend
├── Java EE 11+
├── Spring Framework
├── Hibernate ORM
└── RESTful APIs

Base de Datos
└── SQL Server 2016+

Servidor Aplicaciones
└── Apache Tomcat 9+

Capas de Aplicación

Presentation Layer

Business Logic Layer

Data Access Layer (DAO)

Database

Acceso a APIs

Documentación OpenAPI/Swagger

URL: http://localhost:8080/elastic_business/swagger-ui.html

Visualiza todas las APIs disponibles con:

  • Endpoints disponibles
  • Parámetros requeridos
  • Respuestas esperadas
  • Códigos de error

Autenticación

POST /elastic_business/api/auth/login
Content-Type: application/json

{
"username": "usuario",
"password": "contraseña"
}

Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600
}

Usar token en subsecuentes requests:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Principales APIs

Gestión de Artículos

GET /api/v1/articulos
GET /api/v1/articulos/{codigo}
POST /api/v1/articulos
PUT /api/v1/articulos/{codigo}
DELETE /api/v1/articulos/{codigo}

Ejemplo - Obtener artículo:

curl -H "Authorization: Bearer [TOKEN]" \
http://localhost:8080/elastic_business/api/v1/articulos/ART001

Response:

{
"codigo": "ART001",
"descripcion": "Producto A",
"familia": "FAM001",
"precio_coste": 15.50,
"precio_venta": 25.00,
"stock": 150,
"unidad": "ud"
}

Gestión de Clientes

GET /api/v1/clientes
GET /api/v1/clientes/{codigo}
POST /api/v1/clientes
PUT /api/v1/clientes/{codigo}

Gestión de Pedidos

GET /api/v1/pedidos
GET /api/v1/pedidos/{numero}
POST /api/v1/pedidos
PUT /api/v1/pedidos/{numero}

Crear pedido:

POST /api/v1/pedidos
{
"cliente": "CLI001",
"fecha": "2024-03-10",
"almacen": "ALM001",
"lineas": [
{
"articulo": "ART001",
"cantidad": 100,
"precio_unitario": 25.00
}
]
}

Gestión de Facturas

GET /api/v1/facturas
POST /api/v1/facturas/{pedido}/facturar

Reportes

GET /api/v1/reportes/ventas?desde=2024-01-01&hasta=2024-03-31
GET /api/v1/reportes/costes?producto={codigo}
GET /api/v1/reportes/inventario

Validación de Datos

Campos Obligatorios

Al crear artículo:

  • codigo ← Requerido
  • descripcion ← Requerido
  • familia ← Requerido

El sistema retorna error si faltan:

HTTP 400 Bad Request
{
"error": "Validation failed",
"fields": [
{
"field": "codigo",
"message": "Field is required"
}
]
}

Códigos de Error HTTP

CódigoSignificado
200OK - Éxito
201Created - Recurso creado
400Bad Request - Datos inválidos
401Unauthorized - Sin autenticación
403Forbidden - Sin permiso
404Not Found - Recurso no existe
500Server Error - Error interno

Integración de Ejemplo

Sincronizar inventario desde ERP externo

import requests
import json

# 1. Autenticar
auth_url = "http://elastic:8080/elastic_business/api/auth/login"
auth_payload = {"username": "admin", "password": "admin123"}
response = requests.post(auth_url, json=auth_payload)
token = response.json()["token"]

headers = {"Authorization": f"Bearer {token}"}

# 2. Obtener artículos
articulos_url = "http://elastic:8080/elastic_business/api/v1/articulos"
response = requests.get(articulos_url, headers=headers)
articulos = response.json()

# 3. Sincronizar con sistema externo
for art in articulos:
try:
# Enviar a sistema externo
requests.post(
"https://mi-erp.com/api/productos",
json={
"codigo": art["codigo"],
"nombre": art["descripcion"],
"precio": art["precio_venta"],
"stock": art["stock"]
}
)
print(f"✓ {art['codigo']} sincronizado")
except Exception as e:
print(f"✗ Error sincronizando {art['codigo']}: {e}")

Webhooks

Recibir notificaciones en tiempo real.

Configurar Webhook

Sistema >> Webhooks

Evento: Pedido creado
URL: https://mi-sistema.com/webhook/pedido
Activo: Sí

Payload de Webhook

Cuando se crea pedido:

POST https://mi-sistema.com/webhook/pedido
{
"evento": "pedido.creado",
"timestamp": "2024-03-10T10:30:00Z",
"data": {
"numero": "PED001",
"cliente": "CLI001",
"total": 2500.00
}
}

Extensiones y Plugins

Estructura de Plugin

mi-plugin/
├── plugin.xml # Definición
├── lib/ # Dependencias
├── src/
│ └── com/miempresa/
│ └── plugin/Plugin.java # Código
└── config/
└── configuracion.properties

Ejemplo - Plugin de Validación

package com.miempresa.plugin;

import com.imatia.elastic.api.Plugin;
import com.imatia.elastic.model.Articulo;

public class ValidadorCostes implements Plugin {

public void onArticuloCreated(Articulo articulo) {
// Validación personalizada
if (articulo.getPrecioCoste() > articulo.getPrecioVenta()) {
throw new RuntimeException(
"Coste no puede ser mayor que venta"
);
}
}
}

Base de Datos - Esquema

Tabla ARTICULOS

CREATE TABLE ARTICULOS (
id_articulo INT PRIMARY KEY IDENTITY(1,1),
codigo VARCHAR(50) UNIQUE NOT NULL,
descripcion VARCHAR(255) NOT NULL,
id_familia INT NOT NULL,
precio_coste DECIMAL(10,2),
precio_venta DECIMAL(10,2),
stock INT DEFAULT 0,
fecha_alta DATETIME DEFAULT GETDATE(),
FOREIGN KEY (id_familia) REFERENCES FAMILIAS(id_familia)
);

Tabla PEDIDOS

CREATE TABLE PEDIDOS (
id_pedido INT PRIMARY KEY IDENTITY(1,1),
numero VARCHAR(50) UNIQUE NOT NULL,
id_cliente INT NOT NULL,
fecha_pedido DATETIME NOT NULL,
total DECIMAL(12,2),
estado VARCHAR(20),
FOREIGN KEY (id_cliente) REFERENCES CLIENTES(id_cliente)
);

Relaciones ERD

CLIENTES 1 ←  → n PEDIDOS
FAMILIAS 1 ← → n ARTICULOS
PEDIDOS 1 ← → n LINEAS_PEDIDO
ARTICULOS 1 ← n LINEAS_PEDIDO
PROVEEDORES 1 ← → n PEDIDOS_COMPRA

Performance y Mejores Prácticas

Consultas Optimizadas

❌ Evitar N+1 queries:

// MAL - N+1
for (Cliente c : clientes) {
Pedidos p = db.query("SELECT * FROM PEDIDOS WHERE cliente=" + c.getId());
}

✅ Usar JOIN:

// BIEN - Una sola query
SELECT c.*, p.* FROM CLIENTES c
LEFT JOIN PEDIDOS p ON c.id = p.id_cliente

Caché y Índices

  • Índice en campos de búsqueda frecuente
  • Cachear datos estáticos
  • Limpiar caché después de cambios

Rate Limiting

Límite: 1000 requests/hora por token
Exceder: HTTP 429 Too Many Requests

Seguridad

HTTPS Obligatorio

Configurar certificado SSL en Tomcat
connector protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
scheme="https" secure="true"

Validación de Entrada

// Prevenir SQL Injection
String query = "SELECT * FROM ARTICULOS WHERE codigo = ?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString(1, codigo); // Parametrizado

Encriptación de Contraseñas

// Usar bcrypt, no MD5
passwordEncoder.encode("contraseña");

Documentación Adicional

  • OpenAPI Specification: /swagger-ui.html
  • JavaDoc: /apidocs/
  • Ejemplos de código: https://github.com/imatia/elastic-samples
  • Comunidad: forum.imatia.com/developers

Soporte Técnico Desarrolladores