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.
Files changed (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,449 @@
1
+ # XOne JavaScript — self y el DataObject
2
+
3
+ > Fuente: `xone/v2/xone-help-docs/topics/03a-js-self.md` §2. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §2 acceso a campos, getOldValue, getOwnerCollection, getContents, setFieldPropertyValue, executeNode, save, JSON, métodos adicionales del DataObject, selfDataColl y métodos de DataCollection
6
+
7
+ ---
8
+
9
+ ## 2. Objeto Global `self` - El DataObject Actual
10
+
11
+ El objeto `self` representa la instancia actual del DataObject (registro/fila) en el contexto de ejecución del script. Es el puente entre la interfaz XML y la lógica JavaScript.
12
+
13
+ ### 2.1 Acceso a Campos
14
+
15
+ Existen tres formas equivalentes de acceder a los campos del objeto actual:
16
+
17
+ ```javascript
18
+ // Forma 1: Notacion de punto (mas comun y recomendada)
19
+ let nombre = self.MAP_NOMBRE;
20
+ self.MAP_NOMBRE = "Nuevo valor";
21
+
22
+ // Forma 2: Notacion de corchetes (util para nombres dinamicos)
23
+ let campo = "MAP_NOMBRE";
24
+ let nombre = self[campo];
25
+ self[campo] = "Nuevo valor";
26
+
27
+ // Forma 3: Metodos getValue/setValue (mas explicito)
28
+ let nombre = self.getValue("MAP_NOMBRE");
29
+ self.setValue("MAP_NOMBRE", "Nuevo valor");
30
+
31
+ // Asignar diferentes tipos de datos
32
+ self.MAP_TEXTO = "Texto"; // String (tipo T)
33
+ self.MAP_NUMERO = 42; // Numerico (tipo N)
34
+ self.MAP_FECHA = new Date(); // Fecha (tipo D)
35
+ self.MAP_ACTIVO = 1; // Booleano (tipo B, 0 o 1)
36
+ self.MAP_FOTO = "ruta/imagen.jpg"; // Imagen (tipo IMG/PH)
37
+ ```
38
+
39
+ ### 2.2 getOldValue() - Valor Anterior
40
+
41
+ Permite obtener el valor que tenía un campo antes de la última modificación. Muy útil en eventos `<onchange>`:
42
+
43
+ ```javascript
44
+ // Dentro de un <onchange> de la propiedad MAP_PRECIO
45
+ function onPrecioChanged() {
46
+ let precioAnterior = self.getOldValue("MAP_PRECIO");
47
+ let precioNuevo = self.MAP_PRECIO;
48
+
49
+ if (precioNuevo > precioAnterior * 2) {
50
+ ui.showToast("Advertencia: el precio se ha duplicado");
51
+ }
52
+
53
+ // Registrar el cambio
54
+ console.log("Precio cambio de " + precioAnterior + " a " + precioNuevo);
55
+ }
56
+ ```
57
+
58
+ ### 2.3 getOwnerCollection() - Coleccion Propietaria
59
+
60
+ Permite obtener la coleccion a la que pertenece el objeto:
61
+
62
+ ```javascript
63
+ // Obtener la coleccion propietaria
64
+ let coll = self.getOwnerCollection();
65
+ let nombreColl = coll.getName();
66
+ console.log("Este objeto pertenece a: " + nombreColl);
67
+
68
+ // Obtener la aplicación propietaria
69
+ let app = self.getOwnerApp();
70
+
71
+ // Verificar si el objeto es nuevo o existente
72
+ if (self.isNew()) {
73
+ console.log("Es un registro nuevo, sin guardar en BD");
74
+ }
75
+
76
+ // Verificar si hay cambios sin guardar
77
+ if (self.getDirty()) {
78
+ console.log("Hay cambios pendientes de guardar");
79
+ }
80
+
81
+ // Obtener indice del objeto en la coleccion
82
+ let indice = self.getObjectIndex();
83
+ ```
84
+
85
+ ### 2.4 getContents("nombre") - Acceso a Contents
86
+
87
+ Los contents son colecciones hijas (relación maestro-detalle) embebidas en un objeto:
88
+
89
+ ```javascript
90
+ // Obtener un content
91
+ let lineas = self.getContents("@LineasPedido");
92
+
93
+ // Cargar datos del content
94
+ lineas.unlock();
95
+ lineas.clear();
96
+ lineas.loadAll();
97
+ lineas.lock();
98
+
99
+ // Contar items
100
+ let total = lineas.getCount();
101
+ console.log("Hay " + total + " lineas");
102
+
103
+ // Iterar los items
104
+ for (let i = 0; i < lineas.getCount(); i++) {
105
+ let linea = lineas.get(i);
106
+ console.log("Línea " + i + ": " + linea.MAP_DESCRIPCION);
107
+ }
108
+
109
+ // Agregar un item al content
110
+ lineas.unlock();
111
+ let nuevaLinea = lineas.createObject();
112
+ nuevaLinea.MAP_DESCRIPCION = "Producto nuevo";
113
+ nuevaLinea.MAP_CANTIDAD = 1;
114
+ nuevaLinea.MAP_PRECIO = 25.50;
115
+ lineas.addItem(nuevaLinea);
116
+ lineas.lock();
117
+ lineas.saveAll();
118
+
119
+ // Obtener todos los nombres de contents disponibles
120
+ let nombresContents = self.getAllContentNames();
121
+ ```
122
+
123
+ ### 2.5 setFieldPropertyValue() - Cambiar Atributos en Runtime
124
+
125
+ Permite modificar atributos visuales de las propiedades (controles) en tiempo de ejecución.
126
+
127
+ > ⚠️ **Método de último recurso.** Antes de usar `setFieldPropertyValue` valora siempre alternativas más limpias: cambiar la clase CSS con `getControl(...).setClass(...)`/`addClass(...)`, usar métodos específicos del control (p. ej. `control.setFlashMode(...)`), o expresar el comportamiento directamente en el XML/CSS. Sobrescribir atributos por cache rompe la trazabilidad respecto al XML original y obliga a recordar el `ui.refresh()` manual; úsalo solo cuando no exista una vía declarativa o un método de control equivalente.
128
+
129
+ **Firma:**
130
+
131
+ ```javascript
132
+ self.setFieldPropertyValue(fieldName, attrName, value); // 3 strings, devuelve null
133
+ self.getFieldPropertyValue(fieldName, attrName); // 2 strings, devuelve string
134
+ ```
135
+
136
+ - `fieldName`: nombre del prop (p. ej. `"MAP_TITULO"`). Obligatorio, string.
137
+ - `attrName`: atributo visual (`"width"`, `"img"`, `"visible"`, `"bgcolor"`, …). Obligatorio, string. Acepta alias CSS3 (p. ej. `"background-color"` se canonicaliza a `"bgcolor"`, así que escribir con uno y leer con el otro alias devuelven el mismo valor cacheado).
138
+ - `value`: valor como string. Pasar `null` borra el override y restaura el valor original del XML/CSS.
139
+
140
+ Lanza excepción si falta un parámetro o si alguno no es string.
141
+
142
+ **El cambio NO repinta solo — hay que llamar a `ui.refresh()`:**
143
+
144
+ `setFieldPropertyValue` actualiza la caché de atributos del objeto, pero el control en pantalla no se redibuja hasta llamar a `ui.refresh(prop)` (con el nombre del prop afectado) o `ui.refresh()` (refresca todo).
145
+
146
+ ```javascript
147
+ // Cambiar la imagen de un botón
148
+ self.setFieldPropertyValue("MAP_BOTON", "img", "nuevo_icono.png");
149
+ ui.refresh("MAP_BOTON"); // <-- imprescindible para ver el cambio
150
+
151
+ // Cambiar el ancho de un campo
152
+ self.setFieldPropertyValue("MAP_TITULO", "width", "200p");
153
+ ui.refresh("MAP_TITULO");
154
+
155
+ // Leer un atributo actual
156
+ let ancho = self.getFieldPropertyValue("MAP_TITULO", "width");
157
+
158
+ // Cambiar visibilidad de un campo (ver topico 01 para valores bitmask)
159
+ self.setFieldPropertyValue("MAP_CAMPO_OCULTO", "visible", "7");
160
+ ui.refresh("MAP_CAMPO_OCULTO");
161
+
162
+ // Restaurar el valor original del XML/CSS (borrar el override)
163
+ self.setFieldPropertyValue("MAP_TITULO", "width", null);
164
+ ui.refresh("MAP_TITULO");
165
+
166
+ // Ejemplo real del wiki: togglear icono de flash de camara
167
+ function doToggleFlashMode() {
168
+ let control = getControl("MAP_CAMERA");
169
+ if (!control) return;
170
+
171
+ let sFlashMode = control.getFlashMode();
172
+ if (sFlashMode == "on") {
173
+ control.setFlashMode("off");
174
+ self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-off.png");
175
+ } else if (sFlashMode == "off") {
176
+ control.setFlashMode("auto");
177
+ self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-auto.png");
178
+ } else if (sFlashMode == "auto") {
179
+ control.setFlashMode("torch");
180
+ self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-torch.png");
181
+ } else if (sFlashMode == "torch") {
182
+ control.setFlashMode("on");
183
+ self.setFieldPropertyValue("MAP_TOGGLE_FLASH_MODE", "img", "flash-on.png");
184
+ }
185
+ ui.refresh("MAP_TOGGLE_FLASH_MODE");
186
+ }
187
+ ```
188
+
189
+ ### 2.6 executeNode("nodo") - Ejecutar Eventos Custom
190
+
191
+ Permite ejecutar nodos `<script>` con nombre definido en el XML:
192
+
193
+ ```javascript
194
+ // En el XML:
195
+ // <script nodeName="applyfilter">
196
+ // <script language="javascript">aplicarFiltro();</script>
197
+ // </script>
198
+
199
+ // Desde JavaScript:
200
+ self.executeNode("applyfilter");
201
+
202
+ // Ejemplo real del wiki: filtrar por texto
203
+ function FiltraMarcados(e) {
204
+ self.MAP_BUSCAR_TEXT = e.newText;
205
+ self.executeNode("applyfilter");
206
+ }
207
+ ```
208
+
209
+ ### 2.7 save() - Guardar Cambios
210
+
211
+ ```javascript
212
+ // Guardar el objeto actual en la base de datos
213
+ self.save();
214
+
215
+ // Patron seguro con verificación de error
216
+ function guardarSeguro() {
217
+ try {
218
+ self.save();
219
+ ui.showToast("Guardado correctamente");
220
+ } catch(ex) {
221
+ ui.showToast("Error al guardar: " + ex);
222
+ }
223
+ }
224
+
225
+ // Verificar errores después de guardar
226
+ self.save();
227
+ let error = appData.error();
228
+ if (error.getNumber() != 0) {
229
+ ui.showToast("Error: " + error.getDescription());
230
+ error.clear();
231
+ }
232
+ ```
233
+
234
+ ### 2.8 Conversion a/desde JSON
235
+
236
+ ```javascript
237
+ // Convertir el objeto actual a JSON
238
+ let jsonObj = self.toJson(); // Retorna objeto JS nativo
239
+ let jsonStr = self.toJsonString(); // Retorna string JSON
240
+
241
+ // Cargar datos desde JSON
242
+ self.loadFromJson('{"MAP_NOMBRE": "Test", "MAP_ACTIVO": 1}');
243
+
244
+ // Clonar un objeto
245
+ let copia = self.clone();
246
+ ```
247
+
248
+ ### 2.9 Métodos Adicionales del DataObject
249
+
250
+ ```javascript
251
+ // === getParent() - Obtener el objeto padre (relacion maestro-detalle) ===
252
+ var padre = self.getParent();
253
+ if (padre) {
254
+ console.log("Padre: " + padre.MAP_NOMBRE);
255
+ }
256
+
257
+ // === refresh() / refresh(sqlSentence) - Recargar los valores desde BD ===
258
+ // Vuelve a leer el registro de la base de datos (descarta cambios en memoria no guardados).
259
+ // NO refresca la UI — para eso usa ui.refresh(prop).
260
+ // Con argumento, ejecuta esa sentencia SQL en lugar de la del mapping.
261
+ self.refresh();
262
+ self.refresh("SELECT * FROM PRODUCTOS WHERE ID=" + self.MAP_ID);
263
+
264
+ // === setVariable(name, value) / getVariable(name) ===
265
+ // Variables de scope del objeto (en memoria, no se persisten en BD).
266
+ // Útil para pasar datos entre scripts del mismo objeto sin tocar la base.
267
+ self.setVariable("estadoCalculo", "ok");
268
+ var estado = self.getVariable("estadoCalculo");
269
+
270
+ // === isPropertyDirty(name) / getDirtyProperties() ===
271
+ // Para saber qué campos han cambiado desde la última carga/guardado.
272
+ if (self.isPropertyDirty("MAP_PRECIO")) {
273
+ console.log("El precio ha cambiado");
274
+ }
275
+ var camposCambiados = self.getDirtyProperties(); // Array de nombres
276
+
277
+ // === Contents: metadatos ===
278
+ var nContents = self.getContentsCount();
279
+ var sql = self.getContentAttr("@LineasPedido", "sql"); // atributo XML del content
280
+
281
+ // === getOldItem(name) ===
282
+ // Como getOldValue, pero sin conversion de tipos Date/Calendar (devuelve el valor crudo).
283
+ var valorAntes = self.getOldItem("MAP_FECHA");
284
+
285
+ // === setNodePropertyValue / getNodePropertyValue ===
286
+ // Cambia en runtime un atributo de un nodo del layout, localizándolo por su TAG
287
+ // (frame, group, prop...) y el valor de su atributo "name". Para FRAMES es la vía
288
+ // correcta: setFieldPropertyValue solo actúa sobre props/campos, NO sobre frames.
289
+ // ⚠️ Método de último recurso: mismo criterio que setFieldPropertyValue (sección 2.5)
290
+ // — antes valora cambiar la clase CSS, usar métodos del control, o dejarlo resuelto
291
+ // en el XML/CSS desde el inicio. Sobrescribir atributos por caché obliga a refrescar
292
+ // a mano y rompe la trazabilidad respecto al XML original.
293
+ // El cambio se aplica al renderizar; si la vista ya está creada, refrescar después
294
+ // (window.refresh / ui.refresh).
295
+ // Firma: (tagDelNodo, valorDelAtributoName, nombreAtributo, valor)
296
+ self.setNodePropertyValue("frame", "frmCabecera", "bgcolor", "#7C3AED"); // <frame name="frmCabecera">
297
+ var v = self.getNodePropertyValue("frame", "frmCabecera", "bgcolor");
298
+
299
+ // === bind(controlName, eventName, callback) / unbind(controlName, eventName) ===
300
+ // Vincula un callback a un evento de un control concreto del objeto.
301
+ self.bind("MAP_BOTON", "onclick", function(e) {
302
+ ui.showToast("Pulsado");
303
+ });
304
+ self.unbind("MAP_BOTON", "onclick");
305
+
306
+ // === Metadatos de campos ===
307
+ var titulo = self.getPropertyTitle("MAP_NOMBRE"); // título visible del campo
308
+ var grupo = self.getPropertyGroup("MAP_NOMBRE"); // grupo al que pertenece
309
+ var conValor = self.getPropertyNames(); // nombres de los campos que tienen valor cargado
310
+ // (no incluye los declarados sin valor)
311
+
312
+ // === clearCaches() - Vacía la caché de atributos resueltos ===
313
+ // Util si has cambiado atributos en el XML/CSS y quieres forzar re-evaluación
314
+ // la próxima vez que se lean.
315
+ self.clearCaches();
316
+ ```
317
+
318
+ ### 2.10 selfDataColl - Referencia Directa a la Coleccion
319
+
320
+ `selfDataColl` proporciona acceso directo a la coleccion contenedora del objeto `self`, sin necesidad de llamar a `getOwnerCollection()`:
321
+
322
+ ```javascript
323
+ selfDataColl.loadAll();
324
+ var count = selfDataColl.count();
325
+ console.log("Total registros: " + count);
326
+ ```
327
+
328
+ ### 2.11 DataCollection - Métodos Adicionales
329
+
330
+ #### startBrowse() / endBrowse() - Navegación Browse
331
+
332
+ Inicia y finaliza una sesión de navegación por la coleccion. **Siempre** usar `endBrowse()` en un bloque `finally`:
333
+
334
+ ```javascript
335
+ var coll = appData.getCollection("Datos");
336
+ coll.startBrowse();
337
+ try {
338
+ coll.moveFirst();
339
+ while (coll.getCurrentItem() != null) {
340
+ var obj = coll.getCurrentItem();
341
+ // procesar obj...
342
+ coll.moveNext();
343
+ }
344
+ } finally {
345
+ coll.endBrowse(); // SIEMPRE en finally
346
+ }
347
+ ```
348
+
349
+ #### deleteItem(index) - Eliminar Item por Índice
350
+
351
+ ```javascript
352
+ var coll = appData.getCollection("Productos");
353
+ coll.deleteItem(2); // Elimina el tercer elemento
354
+ ```
355
+
356
+ #### findAllObjects(filter) - Buscar Todos los Objetos
357
+
358
+ Busca todos los objetos que cumplen un filtro. Retorna un array de DataObject:
359
+
360
+ ```javascript
361
+ var encontrados = coll.findAllObjects("TIPO = 'A' AND ACTIVO = 1");
362
+ for (var i = 0; i < encontrados.length; i++) {
363
+ console.log(encontrados[i].MAP_NOMBRE);
364
+ }
365
+ ```
366
+
367
+ #### setMacro(name, value) / getMacro(name) - Macros de Coleccion
368
+
369
+ Las macros de coleccion permiten parametrizar filtros y consultas SQL definidos en el XML de la `<coll>`. Son distintas de las macros globales (`appData.setGlobalMacro`/`getGlobalMacro`): estas viven dentro de **una sola coleccion** y solo afectan a su SQL; las globales son variables de aplicación accesibles desde cualquier punto del código (equivalentes a `localStorage` del navegador).
370
+
371
+ > **API correcta:** `setMacro("##NOMBRE##", valor)` y `getMacro("##NOMBRE##")`. **NUNCA** `coll.macro(...)` — esa forma no existe en XOne y produce error.
372
+
373
+ > **Requisito XML:** Para que `setMacro` tenga efecto, la macro debe estar declarada en el XML de la coll con un nodo `<macro name="##NOMBRE##" value="..." default="true" />` **al mismo nivel que los `<group>`** (hijo directo de `<coll>`, no anidado). Si la macro no existe en el XML, `setMacro` no inyecta nada en el SQL. Ver el tópico 02, sección 7.5 para el detalle completo.
374
+
375
+ ```javascript
376
+ // === Sobre un content de la pantalla actual ===
377
+ var contentGastos = self.getContents("Gastos");
378
+ contentGastos.setMacro("##TIPO##", "tg.NOMBRE LIKE '%" + self.MAP_FTTIPOGASTO + "%'");
379
+
380
+ // === Sobre una coleccion global ===
381
+ var coll = appData.getCollection("Ordenes");
382
+ coll.setMacro("##MACRO1##", "IDORDEN=" + numOrden);
383
+
384
+ // === Lectura ===
385
+ var filtroActual = contentGastos.getMacro("##TIPO##");
386
+ ```
387
+
388
+ El **valor** que pasas a `setMacro` se inyecta tal cual en el SQL — puede ser un literal (`"1"`), un fragmento de WHERE (`"FILTRO='A'"`), o incluso una query SELECT entera si el atributo donde aparece la macro lo permite. Para "desactivar" un filtro sin reescribir la coll, el patron habitual es `coll.setMacro("##TIPO##", "1=1")`.
389
+
390
+ **Tip:** Después de un `setMacro`, suele hacer falta `ui.refresh()` (o `ui.refresh("nombreContent")`) para que el content recargue su SQL con el nuevo valor de la macro.
391
+
392
+ #### createSearchIndex(fields) / doSearch(query) - Busqueda Indexada
393
+
394
+ Permite busqueda rápida en memoria sobre campos indexados:
395
+
396
+ ```javascript
397
+ // Crear indice sobre los campos deseados
398
+ coll.createSearchIndex(["NOMBRE", "DESCRIPCION"]);
399
+
400
+ // Buscar en el indice (tipicamente desde un evento onTextChanged)
401
+ function onBusquedaTexto(evento) {
402
+ coll.doSearch(evento.newText);
403
+ }
404
+ ```
405
+
406
+ #### lock() / unlock() - Bloqueo de Coleccion
407
+
408
+ Activa/desactiva el **modo solo lectura** de la coleccion:
409
+
410
+ - `lock()` activa la bandera de solo lectura. Con la bandera activa, `clear()`, `loadAll()` y similares son **no-ops silenciosos**: devuelven `true` sin hacer nada.
411
+ - `unlock()` desbloquea para poder modificar (vaciar, cargar, añadir items, etc.).
412
+ - `lock()`/`unlock()` son métodos de la **coleccion**; NO existen en `self` (DataObject).
413
+
414
+ Las colecciones **nacen desbloqueadas**, pero el convenio del proyecto es operar en bloque `unlock(); try {...} finally { lock(); }` para dejar la coll bloqueada después y evitar mutaciones accidentales desde código posterior:
415
+
416
+ ```javascript
417
+ var coll = appData.getCollection("Clientes");
418
+ coll.unlock();
419
+ try {
420
+ var obj = new Clientes({ MAP_NOMBRE: "Nuevo" });
421
+ coll.addItem(obj);
422
+ } finally {
423
+ coll.lock(); // SIEMPRE en finally
424
+ }
425
+ ```
426
+
427
+ #### setVariable(name, value) / getVariable(name) - Variables de Coleccion
428
+
429
+ Almacena y recupera variables temporales asociadas a la coleccion (en memoria):
430
+
431
+ ```javascript
432
+ coll.setVariable("totalProcesados", 0);
433
+ var total = coll.getVariable("totalProcesados");
434
+ ```
435
+
436
+ #### Binding de Eventos en Coleccion
437
+
438
+ ```javascript
439
+ var coll = appData.getCollection("MiColeccion");
440
+
441
+ coll.bind("onbeforeedit", function(e) {
442
+ // Se ejecuta antes de entrar en edicion
443
+ });
444
+
445
+ coll.bind("ongroupselected", function(e) {
446
+ // Se ejecuta al cambiar de pestana/grupo
447
+ });
448
+ ```
449
+