xonecode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/dist/agent/authEnDisco.js +56 -0
- package/dist/agent/authEnDisco.js.map +1 -0
- package/dist/agent/configEnDisco.js +109 -0
- package/dist/agent/configEnDisco.js.map +1 -0
- package/dist/agent/crearProyecto.js +34 -0
- package/dist/agent/crearProyecto.js.map +1 -0
- package/dist/agent/entorno.js +124 -0
- package/dist/agent/entorno.js.map +1 -0
- package/dist/agent/guionizado.js +53 -0
- package/dist/agent/guionizado.js.map +1 -0
- package/dist/agent/instantanea.js +129 -0
- package/dist/agent/instantanea.js.map +1 -0
- package/dist/agent/interrupts.js +83 -0
- package/dist/agent/interrupts.js.map +1 -0
- package/dist/agent/mensajes.js +24 -0
- package/dist/agent/mensajes.js.map +1 -0
- package/dist/agent/modelos.js +42 -0
- package/dist/agent/modelos.js.map +1 -0
- package/dist/agent/normalizar.js +20 -0
- package/dist/agent/normalizar.js.map +1 -0
- package/dist/agent/perfiles.js +103 -0
- package/dist/agent/perfiles.js.map +1 -0
- package/dist/agent/proyecto.js +107 -0
- package/dist/agent/proyecto.js.map +1 -0
- package/dist/agent/puente.js +142 -0
- package/dist/agent/puente.js.map +1 -0
- package/dist/agent/resumenDeTool.js +48 -0
- package/dist/agent/resumenDeTool.js.map +1 -0
- package/dist/agent/skills.js +65 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/textoDeTool.js +113 -0
- package/dist/agent/textoDeTool.js.map +1 -0
- package/dist/agent/turnoReal.js +173 -0
- package/dist/agent/turnoReal.js.map +1 -0
- package/dist/agent/verificador.js +65 -0
- package/dist/agent/verificador.js.map +1 -0
- package/dist/agent/xoneAgent.js +106 -0
- package/dist/agent/xoneAgent.js.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/aprobar.js +82 -0
- package/dist/cli/aprobar.js.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consola.js +346 -0
- package/dist/cli/consola.js.map +1 -0
- package/dist/cli/describe.js +53 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/doctor.js +45 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/markdown.js +90 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/run.js +164 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spinner.js +89 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/stdio.js +193 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/tema.js +40 -0
- package/dist/cli/tema.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/core/bitacora.js +30 -0
- package/dist/core/bitacora.js.map +1 -0
- package/dist/core/config.js +236 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextos.js +56 -0
- package/dist/core/contextos.js.map +1 -0
- package/dist/core/deps.js +51 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/diff.js +79 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/esqueleto.js +366 -0
- package/dist/core/esqueleto.js.map +1 -0
- package/dist/core/events.js +2 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/modelos.js +85 -0
- package/dist/core/modelos.js.map +1 -0
- package/dist/core/notify.js +106 -0
- package/dist/core/notify.js.map +1 -0
- package/dist/core/ports.js +114 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/turno.js +127 -0
- package/dist/core/turno.js.map +1 -0
- package/dist/vendor/hitl.js +103 -0
- package/dist/vendor/hitl.js.map +1 -0
- package/dist/vendor/skillLoaders/catalog.js +74 -0
- package/dist/vendor/skillLoaders/catalog.js.map +1 -0
- package/dist/vendor/tokenTracking.js +58 -0
- package/dist/vendor/tokenTracking.js.map +1 -0
- package/package.json +41 -0
- package/skills/xone-debugging/SKILL.md +52 -0
- package/skills/xone-debugging/references/faq.md +561 -0
- package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
- package/skills/xone-development/SKILL.md +105 -0
- package/skills/xone-development/references/anti-patrones.md +94 -0
- package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
- package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
- package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
- package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
- package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
- package/skills/xone-development/references/datos/appdata.md +611 -0
- package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
- package/skills/xone-development/references/datos/http.md +366 -0
- package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
- package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
- package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
- package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
- package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
- package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
- package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
- package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
- package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
- package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
- package/skills/xone-development/references/indice-completo.md +77 -0
- package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
- package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
- package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
- package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
- package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
- package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
- package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
- package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
- package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
- package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
- package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
- package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
- package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
- package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
- package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
- package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
- package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
- package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
- package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
- package/skills/xone-development/references/tipos-de-prop.md +28 -0
- package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
- package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
- package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
- package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
- package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
- package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
- package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
- package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
- package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
- package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
- package/skills/xone-development/references/xml-ui/mapas.md +685 -0
- package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
- package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
- package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
- package/skills/xone-plan-builder/SKILL.md +183 -0
- package/skills/xone-plan-builder/agents/openai.yaml +5 -0
- package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
- package/skills/xone-project-generator/SKILL.md +111 -0
- package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
- package/skills/xone-project-generator/references/colecciones-base.md +16 -0
- package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
- package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
- package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
- package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
- package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
- package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
- package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
- package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
- package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
- package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
- package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
- package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
- package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
- package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
- package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
- package/skills/xone-review/SKILL.md +189 -0
- package/skills/xone-spec-builder/SKILL.md +235 -0
- package/skills/xone-spec-builder/agents/openai.yaml +5 -0
- package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
- package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
- package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# XOne — appData: referencia ampliada
|
|
2
|
+
|
|
3
|
+
> Fuente: `xone/v2/xone-project-generator/references/xone-javascript-patterns-c-appdata-http.md` §2.2. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
|
|
4
|
+
|
|
5
|
+
Contenido: segunda redacción del corpus para appData, con ejemplos adicionales
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### 2.2 Objeto `appData`
|
|
10
|
+
|
|
11
|
+
El objeto `appData` gestiona datos, configuración y estado de la aplicación.
|
|
12
|
+
|
|
13
|
+
#### 2.2.1 Colecciones
|
|
14
|
+
|
|
15
|
+
**Crear objetos — patrón preferido (constructor `new`):** toda colección de la aplicación está disponible como constructor global. Acepta un parámetro opcional con los valores iniciales (cada propiedad se asigna igual que `obj.PROP = valor`, disparando sus `onchange`):
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
// Crear un objeto nuevo con valores iniciales
|
|
19
|
+
let obj = new Clientes({ NOMBRE: "ACME", ACTIVO: 1 });
|
|
20
|
+
|
|
21
|
+
// El parámetro es opcional
|
|
22
|
+
let obj2 = new Clientes();
|
|
23
|
+
|
|
24
|
+
// Crear, añadir a la colección y guardar
|
|
25
|
+
let coll = appData.getCollection("Clientes");
|
|
26
|
+
let obj3 = new Clientes({ NOMBRE: "Nuevo registro" });
|
|
27
|
+
coll.addItem(obj3);
|
|
28
|
+
obj3.save();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Cuándo NO aplica el constructor:
|
|
32
|
+
|
|
33
|
+
- **Contents anidados**: para crear líneas de un content usa `self.Contents("Lineas").createObject()` — crear desde el content establece el vínculo con el objeto padre; el constructor crea sobre la colección global y no vincula.
|
|
34
|
+
- **Nombre de colección dinámico**: si el nombre llega en una variable, usa el patrón legacy `appData.getCollection(nombre).createObject()`.
|
|
35
|
+
|
|
36
|
+
El constructor solo crea objetos. No existen métodos estáticos tipo ORM (`Usuarios.find(...)`, `Usuarios.create(...)`, `Usuarios.findById(...)`); las consultas se hacen con `appData.getCollection("Usuarios").findObject(...)` y demás métodos de la colección.
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
// Obtener una coleccion por nombre
|
|
40
|
+
let coll = appData.getCollection("NombreColeccion");
|
|
41
|
+
|
|
42
|
+
// Cargar todos los registros de la coleccion
|
|
43
|
+
coll.loadAll();
|
|
44
|
+
|
|
45
|
+
// Obtener cantidad de registros cargados
|
|
46
|
+
let nCount = coll.getCount();
|
|
47
|
+
|
|
48
|
+
// Obtener objeto por indice (base 0)
|
|
49
|
+
let obj = coll.get(0);
|
|
50
|
+
|
|
51
|
+
// Buscar un objeto con filtro SQL-like
|
|
52
|
+
let obj = coll.findObject("LOGIN = 'admin'");
|
|
53
|
+
let obj = coll.findObject("ID = 5 AND ACTIVO = 1");
|
|
54
|
+
|
|
55
|
+
// Buscar objeto por campo y valor
|
|
56
|
+
let obj = coll.getItem("MAP_CAMPO", valor);
|
|
57
|
+
|
|
58
|
+
// Crear un nuevo objeto en la coleccion (constructor preferido)
|
|
59
|
+
let newObj = new NombreColeccion({ MAP_NOMBRE: "Nuevo registro" });
|
|
60
|
+
coll.addItem(newObj);
|
|
61
|
+
newObj.save();
|
|
62
|
+
|
|
63
|
+
// Clonar coleccion (copia en memoria)
|
|
64
|
+
let collClone = coll.createClone();
|
|
65
|
+
|
|
66
|
+
// Aplicar filtro y recargar
|
|
67
|
+
coll.setFilter("ACTIVO = 1 AND TIPO = 'A'");
|
|
68
|
+
coll.clear();
|
|
69
|
+
coll.loadAll();
|
|
70
|
+
|
|
71
|
+
// Ordenar registros
|
|
72
|
+
coll.doSort("FECHA DESC");
|
|
73
|
+
|
|
74
|
+
// Borrar todos los registros de la BD
|
|
75
|
+
coll.browseDeleteAll();
|
|
76
|
+
|
|
77
|
+
// Guardar todos los registros modificados
|
|
78
|
+
coll.saveAll();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### 2.2.2 Autenticación
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// Login
|
|
85
|
+
appData.login({
|
|
86
|
+
userName : "usuario",
|
|
87
|
+
password : "contraseña",
|
|
88
|
+
entryPoint : "MenuPrincipal",
|
|
89
|
+
onLoginSuccessful : function() {
|
|
90
|
+
ui.showToast("Bienvenido!");
|
|
91
|
+
},
|
|
92
|
+
onLoginFailed : function() {
|
|
93
|
+
ui.showToast("Credenciales incorrectas");
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Logout
|
|
98
|
+
appData.logout();
|
|
99
|
+
|
|
100
|
+
// Salir de la aplicación
|
|
101
|
+
appData.exit();
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### 2.2.3 Rutas y Configuración
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
// Obtener ruta base de la aplicación
|
|
108
|
+
let sAppPath = appData.getAppPath();
|
|
109
|
+
|
|
110
|
+
// Obtener ruta de la carpeta files/
|
|
111
|
+
let sFilesPath = appData.getFilesPath();
|
|
112
|
+
|
|
113
|
+
// Obtener macro global del sistema
|
|
114
|
+
let sDeviceOs = appData.getGlobalMacro("##DEVICE_OS##");
|
|
115
|
+
let sVersion = appData.getGlobalMacro("##VERSION##");
|
|
116
|
+
let sFrameVersion = appData.getGlobalMacro("##FRAME_VERSION##");
|
|
117
|
+
|
|
118
|
+
// Obtener/Establecer macros personalizadas
|
|
119
|
+
let valor = appData.getGlobalMacro("##MI_MACRO##");
|
|
120
|
+
appData.setGlobalMacro("##MI_MACRO##", "mi_valor");
|
|
121
|
+
|
|
122
|
+
// Escribir mensaje de debug
|
|
123
|
+
appData.writeConsoleString("Debug: valor = " + valor);
|
|
124
|
+
|
|
125
|
+
// Limpiar errores acumulados
|
|
126
|
+
appData.error().clear();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### 2.2.4 Empresa Actual y Variables Globales de Sesión
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
// Obtener la empresa actual del usuario logueado
|
|
133
|
+
var empresa = appData.getCurrentEnterprise();
|
|
134
|
+
|
|
135
|
+
// Almacenar variables globales de sesion (persisten durante la sesion)
|
|
136
|
+
appData.getCurrentEnterprise().setVariable("LATITUD", latitud);
|
|
137
|
+
appData.getCurrentEnterprise().setVariable("LONGITUD", longitud);
|
|
138
|
+
appData.getCurrentEnterprise().setVariable("MODO_DARK", true);
|
|
139
|
+
|
|
140
|
+
// Recuperar variables globales de sesion
|
|
141
|
+
var lat = appData.getCurrentEnterprise().getVariable("LATITUD");
|
|
142
|
+
var lng = appData.getCurrentEnterprise().getVariable("LONGITUD");
|
|
143
|
+
var debug = appData.getCurrentEnterprise().getVariable("Debug");
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### 2.2.5 Formateo y Utilidades Numéricas
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
// Convertir cualquier valor (fecha, número, booleano, …) a string siguiendo
|
|
150
|
+
// las reglas de XOne (formato de fecha de la empresa, decimales, etc.).
|
|
151
|
+
// Segundo parámetro opcional: flags numéricos.
|
|
152
|
+
var sqlStr = appData.variantToString(valor);
|
|
153
|
+
var sFecha = appData.variantToString(new Date());
|
|
154
|
+
|
|
155
|
+
// Redondeo seguro (importante para evitar errores de precision con decimales/euros)
|
|
156
|
+
var precio = appData.safeRound(vPendiente, 2);
|
|
157
|
+
var total = appData.safeRound(cantidad * precioUnitario, 2);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### 2.2.6 Cifrado y Descifrado (métodos de appData)
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// Cifrar una cadena de texto
|
|
164
|
+
var cifrado = appData.encryptString("texto sensible");
|
|
165
|
+
|
|
166
|
+
// Descifrar una cadena previamente cifrada
|
|
167
|
+
var descifrado = appData.decryptString(cifrado);
|
|
168
|
+
|
|
169
|
+
// Variantes con flags opcionales
|
|
170
|
+
var cifrado2 = appData.encrypt("texto", "flags_opcionales");
|
|
171
|
+
var descifrado2 = appData.decrypt(cifrado2, "flags_opcionales");
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### 2.2.7 Objeto error() - Control de Errores del Framework
|
|
175
|
+
|
|
176
|
+
El manejo de errores del framework se realiza a traves de `appData.error()`. Es fundamental verificar errores después de operaciones críticas.
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
// Verificar si hubo error
|
|
180
|
+
if (appData.error().getNumber() != 0) {
|
|
181
|
+
// Obtener descripción del error
|
|
182
|
+
var desc = appData.error().getDescription();
|
|
183
|
+
|
|
184
|
+
// Obtener SQL que fallo (si aplica)
|
|
185
|
+
var sql = appData.error().getFailedSql();
|
|
186
|
+
|
|
187
|
+
ui.msgBox("Error: " + desc, "ERROR", 0);
|
|
188
|
+
if (sql) {
|
|
189
|
+
ui.msgBox("SQL fallida: " + sql, "SQL", 0);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Limpiar el error (importante: siempre limpiar después de manejar)
|
|
193
|
+
appData.error().clear();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Patron completo: verificar error después de operación
|
|
197
|
+
var coll = appData.getCollection("ArticulosBuscar");
|
|
198
|
+
var filtroOriginal = coll.getFilter();
|
|
199
|
+
coll.setFilter("CODARTICULO=" + codigoArticulo);
|
|
200
|
+
coll.startBrowse();
|
|
201
|
+
|
|
202
|
+
if (appData.error().getNumber() != 0) {
|
|
203
|
+
ui.msgBox("Error: " + appData.error().getDescription(), "ERROR", 0);
|
|
204
|
+
appData.error().clear();
|
|
205
|
+
} else {
|
|
206
|
+
// Procesar resultados normalmente
|
|
207
|
+
var item = coll.getCurrentItem();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
coll.setFilter(filtroOriginal);
|
|
211
|
+
coll.endBrowse();
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### 2.2.8 Consola de Depuracion
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
// Escribir en la consola de depuracion
|
|
218
|
+
appData.writeConsoleString("App_log_xone->Mensaje de depuracion");
|
|
219
|
+
appData.writeConsoleString("Debug: valor = " + JSON.stringify(datos));
|
|
220
|
+
|
|
221
|
+
// Patron de depuracion condicional con variables de empresa
|
|
222
|
+
function ShowMessageDebug(mode, stmsg) {
|
|
223
|
+
if (appData.getCurrentEnterprise().getVariable("Debug") === true) {
|
|
224
|
+
if (mode === "msgbox")
|
|
225
|
+
ui.msgBox(stmsg, "App_log_xone!", 0);
|
|
226
|
+
else if (mode === "showtoast")
|
|
227
|
+
ui.showToast("App_log_xone->" + stmsg);
|
|
228
|
+
else if (mode === "consola")
|
|
229
|
+
appData.writeConsoleString("App_log_xone->" + stmsg);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### 2.2.9 Ejecución SQL Directa
|
|
235
|
+
|
|
236
|
+
**Firma:** `appData.executeSql(sql)`
|
|
237
|
+
|
|
238
|
+
- **Parámetros:** exactamente **1** — string SQL (no soporta placeholders `?` ni varargs; para parametrizar usar `SqlManager.doRawQuery()`).
|
|
239
|
+
- **Sustitución de macros:** sí, automática. Las macros del framework (`##USERID##`, `##NOW##`, etc.) se sustituyen en el SQL antes de ejecutarlo.
|
|
240
|
+
- **No usar para leer escalares**: para `SELECT` no devuelve el valor — devuelve un cursor inutilizable desde JS. Para leer datos usar `SqlManager.doRawQuery()` + cursor.
|
|
241
|
+
- **Uso recomendado:** sentencias de modificación (`UPDATE`/`INSERT`/`DELETE`) sobre la BBDD local, especialmente útil cuando hay cursores abiertos sobre la misma tabla y `CurrentItem` no puede modificarse desde la coll.
|
|
242
|
+
- **Seguridad:** **NUNCA concatenar input de usuario sin validar** (riesgo de SQL injection). Para consultas con parámetros usar `SqlManager.doRawQuery("... WHERE X=?", valor)`.
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// === UPDATE/DELETE: uso típico de executeSql ===
|
|
246
|
+
// IDUSUARIO viene de self (entero validado); concatenación segura
|
|
247
|
+
appData.executeSql("UPDATE Gen_Rutas SET VISITADO=0 WHERE IDUSUARIO=" + self.IDUSUARIO);
|
|
248
|
+
|
|
249
|
+
// === SELECT: NO usar executeSql para leer escalares ===
|
|
250
|
+
// Esto NO devuelve el número de filas (devuelve un cursor inutilizable desde JS)
|
|
251
|
+
// var resultado = appData.executeSql("SELECT COUNT(*) FROM Gen_Clientes WHERE ACTIVO=1"); // MAL
|
|
252
|
+
|
|
253
|
+
// Forma correcta para leer datos: SqlManager + cursor
|
|
254
|
+
let sqlManager = new SqlManager();
|
|
255
|
+
try {
|
|
256
|
+
sqlManager.openDatabase({ databasePath: "gestion.db", useExistingConnection: true });
|
|
257
|
+
let cursor = sqlManager.doRawQuery("SELECT COUNT(*) AS N FROM Gen_Clientes WHERE ACTIVO=?", 1);
|
|
258
|
+
try {
|
|
259
|
+
cursor.moveToFirst();
|
|
260
|
+
var resultado = cursor.getInteger("N");
|
|
261
|
+
} finally {
|
|
262
|
+
cursor.close();
|
|
263
|
+
}
|
|
264
|
+
} finally {
|
|
265
|
+
sqlManager.close();
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### 2.2.10 Control de Replicación
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
// Desactivar replicacion para operaciones de mantenimiento
|
|
273
|
+
appData.setIsReplicating(false);
|
|
274
|
+
// ... operaciones de mantenimiento que no deben sincronizarse
|
|
275
|
+
appData.setIsReplicating(true);
|
|
276
|
+
|
|
277
|
+
// Verificar estado de replicacion
|
|
278
|
+
var replicando = appData.isReplicating();
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### 2.2.10b Otros métodos de appData
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
// === Conexiones ===
|
|
285
|
+
var conn = appData.getConnection("REMOTA"); // conexión por nombre
|
|
286
|
+
var s = appData.getConnString(); // string de la conexión principal
|
|
287
|
+
|
|
288
|
+
// === Diagnóstico ===
|
|
289
|
+
var nColls = appData.getCollectionCount(); // total de colecciones registradas
|
|
290
|
+
var conds = appData.getVisualConditions(); // string con las condiciones visuales activas
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### 2.2.11 Objeto `replica`
|
|
294
|
+
|
|
295
|
+
Además del control desde `appData`, existe un objeto global `replica` con más control: iniciar/detener el servicio, procesar la cola manualmente, consultar métricas en tiempo real y fijar restricciones.
|
|
296
|
+
|
|
297
|
+
**Catálogo completo de métodos:**
|
|
298
|
+
|
|
299
|
+
| Método | Descripción |
|
|
300
|
+
| --- | --- |
|
|
301
|
+
| **start** | Iniciar el servicio de réplica. |
|
|
302
|
+
| **stop** | Detener la réplica. |
|
|
303
|
+
| **processReplicatorQueue(arg)** | Procesar cola pendiente. El argumento NO es un callback: acepta el `LiveSecureProvisioningResponse` del evento `live`, un `string` con el nombre de la app, o un `{databasePath, appName, taskId}`. Devuelve `boolean`. |
|
|
304
|
+
| **getLog** | Obtener log de la réplica. |
|
|
305
|
+
| **getDatabaseId** | ID de la base de datos. |
|
|
306
|
+
| **getHostname** | Nombre de host del servidor. |
|
|
307
|
+
| **getLicense** | Licencia. |
|
|
308
|
+
| **getMid** | MID (identificador del dispositivo). |
|
|
309
|
+
| **getRecordsPend** | Registros pendientes por enviar. |
|
|
310
|
+
| **getRecordsRX** / **getRecordsTX** | Registros recibidos/enviados en la sesión actual. |
|
|
311
|
+
| **getTotalRecordsRX** / **getTotalRecordsTX** | Totales desde el inicio. |
|
|
312
|
+
| **setRestriction** | Ajustar una restricción de réplica (p.ej. solo wifi). |
|
|
313
|
+
| **clearRestrictions** | Quitar restricciones actuales. |
|
|
314
|
+
| **clearAllRestrictions** | Quitar todas las restricciones. |
|
|
315
|
+
|
|
316
|
+
```javascript
|
|
317
|
+
// Forzar replica manual y reportar metricas al terminar.
|
|
318
|
+
// El argumento es el liveResponse recibido en el evento live, o el nombre de la app.
|
|
319
|
+
function forzarReplica(liveResponse) {
|
|
320
|
+
ui.showWaitDialog("Sincronizando...");
|
|
321
|
+
let ok = replica.processReplicatorQueue(liveResponse);
|
|
322
|
+
ui.hideWaitDialog();
|
|
323
|
+
|
|
324
|
+
if (ok) {
|
|
325
|
+
ui.msgBox(
|
|
326
|
+
"Sincronización OK\n" +
|
|
327
|
+
"TX: " + replica.getRecordsTX() + " / " + replica.getTotalRecordsTX() + "\n" +
|
|
328
|
+
"RX: " + replica.getRecordsRX() + " / " + replica.getTotalRecordsRX() + "\n" +
|
|
329
|
+
"Pendientes: " + replica.getRecordsPend(),
|
|
330
|
+
"Replica", 0
|
|
331
|
+
);
|
|
332
|
+
} else {
|
|
333
|
+
ui.showToast("Error en la replica");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
#### 2.2.12 Carga dinámica de scripts (`loadIncludeFile`) y declaración preferida
|
|
339
|
+
|
|
340
|
+
> **Regla general:** declara los scripts en el nodo `<app>` siempre que puedas. Reserva `loadIncludeFile()` para casos especiales que **realmente** necesiten cargar el fichero en runtime (carga condicional según usuario/empresa, scripts descargados dinámicamente, parches en caliente, etc.).
|
|
341
|
+
|
|
342
|
+
**Forma preferida — declarar en el nodo `<app>` (estática):**
|
|
343
|
+
|
|
344
|
+
```xml
|
|
345
|
+
<app default-language="javascript" ...>
|
|
346
|
+
<!-- functions.js se carga automáticamente, no hace falta declararlo -->
|
|
347
|
+
|
|
348
|
+
<!-- Forma <include>: encoding por defecto ISO-8859-1 -->
|
|
349
|
+
<include file="scripts/utils.js" />
|
|
350
|
+
<include url="scripts/api.js" encoding="UTF-8" />
|
|
351
|
+
|
|
352
|
+
<!-- Forma <script> (alias estilo HTML): encoding por defecto UTF-8 -->
|
|
353
|
+
<script src="scripts/auth.js" />
|
|
354
|
+
</app>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Atributos comunes a `<include>` y `<script>`:
|
|
358
|
+
|
|
359
|
+
| Atributo | Alias | Obligatorio | Default | Descripción |
|
|
360
|
+
|---|---|---|---|---|
|
|
361
|
+
| `file` | `url`, `src` | sí | — | Ruta del fichero |
|
|
362
|
+
| `language` | — | no | `default-language` del `<app>` | `"javascript"` o `"vbscript"` |
|
|
363
|
+
| `encoding` | `charset` | no | `ISO-8859-1` en `<include>` · `UTF-8` en `<script>` | Codificación del fichero |
|
|
364
|
+
| `delay-compilation` | — | no | `false` | Difiere la compilación hasta el primer uso |
|
|
365
|
+
| `compile` | — | no | `true` | Si `false`, registra el fichero pero no lo compila |
|
|
366
|
+
|
|
367
|
+
**Forma dinámica — `appData.loadIncludeFile()` (solo casos especiales):**
|
|
368
|
+
|
|
369
|
+
```javascript
|
|
370
|
+
appData.loadIncludeFile(fileName [, scriptLanguage] [, encoding] [, delayCompilation] [, compile]);
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
| # | Nombre | Obligatorio | Valor por defecto | Descripción |
|
|
374
|
+
|---|---|---|---|---|
|
|
375
|
+
| 1 | `fileName` | sí | — | Ruta del fichero igual que en el nodo XML `<include>` |
|
|
376
|
+
| 2 | `scriptLanguage` | no | `default-language` del nodo `<app>` | `"javascript"` o `"vbscript"` |
|
|
377
|
+
| 3 | `encoding` | no | `"ISO-8859-1"` | Codificación del fichero. **Atención: el default NO es UTF-8** |
|
|
378
|
+
| 4 | `delayCompilation` | no | `false` | Si `true`, difiere la compilación hasta el primer uso |
|
|
379
|
+
| 5 | `compile` | no | `true` | Si `false`, registra el fichero pero no lo compila |
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
// Carga simple (asume default-language=javascript y encoding ISO-8859-1)
|
|
383
|
+
appData.loadIncludeFile("scripts/miModulo.js");
|
|
384
|
+
|
|
385
|
+
// Recomendado si el script tiene tildes/ñ guardadas como UTF-8
|
|
386
|
+
appData.loadIncludeFile("scripts/miModulo.js", "javascript", "UTF-8");
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Advertencia sobre el encoding:** el valor por defecto es `ISO-8859-1`, no UTF-8. Si tu script contiene caracteres no-ASCII (tildes, ñ, símbolos) y está guardado como UTF-8, **se romperán** salvo que pases `"UTF-8"` explícitamente como tercer parámetro.
|
|
390
|
+
|
|
391
|
+
Llamadas posteriores al mismo fichero **no recompilan**: el motor reutiliza el bytecode ya cargado.
|
|
392
|
+
|
|
393
|
+
#### 2.2.13 Carga dinámica de CSS (`loadCssFile` / `unloadCssFile`) y declaración preferida
|
|
394
|
+
|
|
395
|
+
> **Regla general:** declara las hojas de estilo en el nodo `<app>` siempre que puedas. Reserva `loadCssFile()` / `unloadCssFile()` para casos especiales (cambio de tema por usuario, modo oscuro/claro en runtime, A/B testing visual, etc.).
|
|
396
|
+
|
|
397
|
+
**Forma preferida — declarar en el nodo `<app>` (estática):**
|
|
398
|
+
|
|
399
|
+
```xml
|
|
400
|
+
<app ...>
|
|
401
|
+
<style url="estilos.css" />
|
|
402
|
+
<style url="temas/oscuro.css" encoding="UTF-8" conditions="##DEVICE_OS##='android'" strict-mode="true" />
|
|
403
|
+
</app>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Atributos del nodo `<style>`:
|
|
407
|
+
|
|
408
|
+
| Atributo | Obligatorio | Default | Descripción |
|
|
409
|
+
|---|---|---|---|
|
|
410
|
+
| `url` | sí | — | Ruta del fichero CSS |
|
|
411
|
+
| `encoding` | no | (depende del fichero) | Codificación del fichero |
|
|
412
|
+
| `conditions` | no | (sin condición) | Condición de carga evaluada al iniciar (p. ej. macros globales) |
|
|
413
|
+
| `strict-mode` | no | `false` | Si `true`, exige CSS bien formado (avisa de errores como falta de `;`). En modo estricto hay que escapar `:` en valores: `title:Hola\:Mundo;` |
|
|
414
|
+
|
|
415
|
+
**Forma dinámica — `appData.loadCssFile()` / `appData.unloadCssFile()` (solo casos especiales):**
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
// Forma 1: argumentos posicionales
|
|
419
|
+
appData.loadCssFile(name [, encoding] [, conditions] [, strictMode]);
|
|
420
|
+
|
|
421
|
+
// Forma 2: objeto literal
|
|
422
|
+
appData.loadCssFile({ name: "...", encoding: "...", conditions: "...", strictMode: false });
|
|
423
|
+
|
|
424
|
+
// Descarga (un único argumento)
|
|
425
|
+
appData.unloadCssFile(name);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Parámetros de `loadCssFile`:
|
|
429
|
+
|
|
430
|
+
| # / clave | Obligatorio | Valor por defecto | Descripción |
|
|
431
|
+
|---|---|---|---|
|
|
432
|
+
| `name` | sí | — | Ruta del fichero CSS |
|
|
433
|
+
| `encoding` | no | `"UTF-8"` | Codificación del fichero (¡distinto de `loadIncludeFile`!) |
|
|
434
|
+
| `conditions` | no | (sin condición) | Condición de carga |
|
|
435
|
+
| `strictMode` | no | `false` | Modo estricto de parseo |
|
|
436
|
+
|
|
437
|
+
```javascript
|
|
438
|
+
// Ejemplo: cambio de tema en runtime
|
|
439
|
+
function aplicarTemaOscuro() {
|
|
440
|
+
appData.unloadCssFile("temas/claro.css");
|
|
441
|
+
appData.loadCssFile("temas/oscuro.css", "UTF-8");
|
|
442
|
+
// El framework limpia caches de propiedades y refresca la cascada
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`loadCssFile()` y `unloadCssFile()` invalidan automáticamente los caches internos de propiedades visuales (`ClearCollPropValueCaches()`), por lo que los cambios se reflejan en los siguientes renders sin reiniciar la app.
|
|
447
|
+
|
|
448
|
+
**Diferencia de encoding por defecto:**
|
|
449
|
+
|
|
450
|
+
| Método | Default encoding |
|
|
451
|
+
|---|---|
|
|
452
|
+
| `appData.loadCssFile()` | `"UTF-8"` |
|
|
453
|
+
| `appData.loadIncludeFile()` | `"ISO-8859-1"` |
|
|
454
|
+
| `<style>` en `<app>` | depende del fichero |
|
|
455
|
+
| `<include>` en `<app>` | `"ISO-8859-1"` |
|
|
456
|
+
| `<script>` en `<app>` | `"UTF-8"` |
|
|
457
|
+
|