Centro de Consultores
Consultor
0 • Menú de la plataforma
0 • Menú de la plataforma
1 • Organización
1 • Organización
2 • Operaciones
2 • Operaciones
3 • Áreas de operación
3 • Áreas de operación
4 • Usuarios
4 • Usuarios
5 • Perfil de usuarios
5 • Perfil de usuarios
6 • Actores
6 • Actores
7 • Eventos
7 • Eventos
8 • Fichas de actores
8 • Fichas de actores
9 • Flujos de trabajo o proceso
9 • Flujos de trabajo o proceso
10 • Formularios
10 • Formularios
11 • Configuración de datos
11 • Configuración de datos
12 • Carga masiva de datos
12 • Carga masiva de datos
13 • Hojas de cálculo
13 • Hojas de cálculo
14 • Reportes PDF de Flujos y Formularios
14 • Reportes PDF de Flujos y Formularios
15 • Dashboards dinámicos
15 • Dashboards dinámicos
16 • Gestor documental
16 • Gestor documental
17 • Notificaciones
17 • Notificaciones
Configuraciones avanzadas
1. Regex
Este parámetro permite colocar expresiones regulares para limitar o validar carácteres.
Estos son algunos ejemplos de los más comunes
Función | inputRegex |
Para permitir que se ingresen solo letras | “^[a-zA-ZñÑáéíóúÁÉÍÓÚ]+$”. |
Para impedir que se ingresen letras | “”, |
Para impedir que se ingresen números | “[^0-9]*”. |
Para que se valide una dirección de correo electrónico según el Estándar Oficial: RFC 5322 | “^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$” |
Para comprender mejor cómo funcionan revisa estos links:
Para validar el funcionamiento del Regex creado:
2. AutomatedMapping
Automated Mapping permite autocompletar los valores de uno o todos los campos de un formulario al seleccionar un registro de actor configurado en el header del formulario. Esto es útil, por ejemplo, en formularios de registro o edición de actores. La primera vez se completan todos los campos y se envía el formulario para crear el registro en la base de datos. Al editar, el mismo formulario puede autocompletar los campos con la información almacenada, si
automatedMapping
está configurado en true
.Para que funcione correctamente, los key de los campos en el formulario deben coincidir con el código del atributo del actor.
Además se deben tener dos consideraciones:
- Header del Formulario: En el header del formulario debe configurarse que se pueda seleccionar y mostrar los registros del actor. La query al actor se coloca en el objeto
inputElement
, junto a"automatedMapping"
o"debugMode"
, dentro de"head"
y"template"
.
"template": { "head": { "inputElement": { "query": "element.AGRICULTOR", "options": [], "active": true, "label": "Para editar un registro, seleccione un agricultor de la lista" } "automatedMapping": true "debugMode": false, ...} }
- Ocultar el Atributo Principal: Se debe ocultar el campo que define el atributo principal para evitar la creación de copias del registro debido a keys distintas. Esto se realiza en el objeto
renderCondition
del campo del formulario.
{ "visible": true, "max": "15", "errortext": "Debe ingresar el número de documento del agricultor", "query": "", "update": "", "label": "Número de documento", "type": "STRING", "callRefresh": false, "regex": "", "inputRegex": "^[0-9]+$", "min": "0", "defaultColor": "", "activeColor": "", "renderCondition": "cond(isNaN(parseInt('#_ELEMENT.id#')))", "helptext": "Ingrese sólo números. Lo puede encontrar en: ...", "decimals": "", "options": [], "formulla": "", "dataSource": "", "id": 3, "value": "", "key": "NRO_DOC_AGRI", "validate": true, "validateCondition": "exist(element.AGRICULTOR[(@.nro_doc_agri =! '#info_basi.NRO_DOC_AGRI#')])" },
3. Tipos de Datasources
Los datasource o fuentes de datos son conexiones a la base de datos que trae los valores almacenados, al realizar una consulta (
query
).Existen varios tipos de datasources que se pueden usar en la configuración de Sepiia, estos varían dependiendo del tipo de dato a consultar.
Tipo | Función | Configuración / Ejemplos |
sepiia. | Se usa para datasources publicados por la plataforma y que funcionan de forma transversal para todos los clientes. Como los usuarios de la plataforma, los cargos de esos usuarios. | sepiia.USUARIO
sepiia.CARGO |
custom. | Se usa para datasources de los configuradores de datos creados para la organización. | custom.CODIGO_CONFIGURADOR_DATOS |
element. | Se usa para datasources de los actores creados para la organización. | element.CODIGO_ACTOR |
view. | Se usa para datasources de los vistas creadas mediante el QueryManager o la API SSQL para la organización. | view.CODIGO_VISTA |
Los datasources por sí solos, traen todos los registros que coinciden con el código. Sin embargo, la cantidad de registros puede filtrarse agregando alguna condición, ejemplo:
element.COMP[?(@.cod_atributo == ‘valor’ && @.cod_atributo_2 == ‘valor2’)]
. Se puede agregar y u o usando los siguientes símbolos y = &&
, o = ||
.4. QueryClones
Es una propiedad que se usa en el parámetro
query
de los elementos de un formulario, el cual permite clonar campos según la cantidad de opciones que traiga la query
dentro de queryClones
. Esta propiedad es especialmente útil cuando se quiere mostrar X cantidad de campos dependiendo de X selecciones en algún campo tipo
MULTIPLE
, MULTIPLE_REORDER
, CHECKBOX
o TABLE
. Esta propiedad requiere también una configuración especial en Flujo de trabajo.
Configuración
Para configurarlo se debe colocar en el objeto
query
de la siguiente manera:{ "errortext": "Invalid Numeros", "update": "", "type": "NUMBER", "callRefresh": false, "min": "0", "defaultColor": "", "renderCondition": "", "validStatus": true, "helptext": "Ingrese un valor de % entre 0 y 100", "options": [], "formulla": "", "id": 2, "value": "", "key": "niv", "validate": false, "visible": true, "max": "100", "query": {"queryClones":"custom.TIPO_ACT"}, "label": "template", "validateCondition": "", "tags": "", "regex": "", "activeColor": "", "inputRegex": "", "decimals": "2" }
Variaciones en la configuración
- La cantidad y las opciones que traiga la
query
delqueryClones
pueden filtrarse según se requiera como se muestra en el siguiente ejemplo:
{ "visible": true, "max": "100", "errortext": "", "query": {"queryClones":"element.PLT_COMPONENTE[?(@.key IN [#general.COMPS_RECE.keys#])]"}, "update": "", "label": "Lo toma desde el label de la query", "type": "NUMBER", "callRefresh": true, "regex": "", "min": "0", "defaultColor": "", "activeColor": "", "renderCondition": "", "helptext": "", "decimals": "1", "options": [], "formulla": "", "id": 1, "value": "", "key": "INCL_CRE", "validate": false }
- Si el campo a clonar es de tipo
SELECTION
, se pueden colocar un datasource después delqueryClones
, como en el siguiente ejemplo:
"query": {"queryClones":"element.PLT_COMPONENTE[?(@.key IN [#general.COMPS_RECE.keys#])]", "query": "custom.TIPO_TAREA"},
En la sección del formulario los campos repetidos aparecerán según el orden en que se encuentren. Por ejemplo, si se tienen 2 campos con el
queryClone
configurado, el campo A seguido del B, aparecerán en primer lugar todos los clones del campo A y luego los clones del campo B.5. DebugMode
Este objeto se configura en el Header del formulario, tiene valores
true
/ false
, permite que los errores que tenga el formulario se muestren. Se recomienda usar cuando se está configurando y probando el formulario. Una vez esté productivo, es recomendable colocarlo en false
.Una vez se este probando el formulario al ejecutarse, en la primera sección del mismo formulario aparecerá una tabla con los mensajes de errores encontrados. Si se desea ver más detalle de los errores se puede hacer clic y mostrará el detalle.
6. Render Condition
Permite controlar que una sección o campo se muestre en el formulario si se cumple una condición.
Sección del formulario
Para controlar la visualización de una sección, se debe colocar la condición en el
renderCondition
del encabezado de la sección. En el ejemplo, se muestran dos secciones (información clave en color azul). En la primer sección, hay un campo de tipo Switch; si se marca "Sí", la siguiente sección se muestra, de lo contrario, no. La condición para que se muestre la sección es la siguiente:"renderCondition": "cond(#tipo_pesaje.decision# == true || #tipo_pesaje.decision# == 1)"
.........{ "label": "Tipo de pesaje", "key": "tipo_pesaje", "template": false, "dataExpansionPanel": true, "renderCondition": "", "elements": [ { "visible": true, "max": "", "query": "", "label": "¿Es el primer pesaje del animal en el predio?", "type": "SWITCH", "callRefresh": true, "regex": "", "min": "", "renderCondition": "", "helptext": "Marque Si si el primer pesaje, NO si es pesaje de seguimiento de ganancia de peso", "errortext": "", "options": [], "formulla": "", "value": "false", "key": "decision", "validate": true, "id": 1, "update": "", "defaultColor": "", "activeColor": "", "decimals": "", "dataSource": "" }] }, { "label": "Primer pesaje de animal", "key": "pesaje_inicio", "template": false, "dataExpansionPanel": false, "renderCondition": "cond(#tipo_pesaje.decision# == true || #tipo_pesaje.decision# == 1)", "elements": [ { "visible": true, "max": "2090-01-01", "query": "", "label": "Fecha pesaje seguimiento", "type": "DATE", "callRefresh": true, "regex": "", "min": "2020-01-01", "renderCondition": "", "helptext": "Seleccione la fecha en la que se realizó el pesaje", "errortext": "", "options": [], "formulla": "", "value": "", "key": "fecha", "validate": false, "id": 2, "update": "", "defaultColor": "", "activeColor": "", "decimals": "", "dataSource": "" },{.........
Campo del formulario
Para controlar la visualización de un campo, se debe colocar la condición en el
renderCondition
que aparece en cada elemento del formulario. En el ejemplo, se muestran dos elementos. El primero es un SELECTION
, y que si se selecciona la opción Feedlot, se mostrará el siguiente elemento que es de tipo LABEL
, de lo contrario, no. La condición para que se muestre el elemento es la siguiente:"renderCondition": "cond('#pesaje_inicio.un_prod.label#' == 'Feedlot')"
............},{ "visible": true, "max": "", "query": "custom.UN_PROD", "label": "Unidad productiva", "type": "SELECTION", "callRefresh": true, "regex": "", "min": "", "renderCondition": "", "helptext": "Seleccione la unidad productiva donde se ingresa el lote", "errortext": "", "options": [], "formulla": "", "value": "", "key": "un_prod", "validate": false, "id": 2, "update": "", "defaultColor": "", "activeColor": "", "decimals": "", "dataSource": "" }, { "visible": true, "max": "", "query": "", "label": "Fecha feedlot", "type": "LABEL", "callRefresh": false, "regex": "", "min": "", "renderCondition": "cond('#pesaje_inicio.un_prod.label#' == 'Feedlot')", "helptext": "", "errortext": "", "options": [], "formulla": "js('#pesaje_inicio.un_prod.label#' == 'Feedlot' ? '#_CURRENT.date#': '')", "value": "", "key": "fecha_feedlot", "validate": false, "id": 4, "update": "", "defaultColor": "", "activeColor": "", "decimals": "", "dataSource": "" }, {........
7. Validaciones de datos
completeCondition
Se utiliza para validar un formulario. Se configura una condición y un mensaje. Si la condición no se cumple, el formulario no se podrá enviar y se mostrará el mensaje configurado.
En el ejemplo, la condición es que el Actor "Número de factura" no debe existir. Si ya existe, el formulario no será válido y se mostrará el mensaje "La factura de venta ya existe". Es decir no se puede ingresar dos veces el mismo número de factura.
.........], "template": { "head": { "automatedMapping": false, "debugMode": false, "elementId": "", "elementKey": "", "completeCondition": {"condition": "notExist(element.FACTURA[?(@.key == '#venta.fact_sell#')])", "message": "La factura de venta ya existe.", }, "titleAcive": false, "output": { "query": "", "active": false, "fields": [] }, ...........
validateCondition
Se utiliza para validar un campo específico, se configura una condición y un mensaje de error. Si la condición no se cumple, saldrá el mensaje de error y el campo del formulario no será válido.
En el ejemplo, la condición es que la diferencia entre dos fechas debe ser mayor a cero, si esto no se cumple se mostrará el mensaje de error “Fecha del evento no puede ser menor a la fecha de ingreso del animal al predio”. Esto obliga a corregir la fecha ingresada.
.................... "elements": [ { "visible": true, "max": "2090-12-31", "query": "", "label": "Fecha del evento", "type": "DATE", "callRefresh": false, "regex": "", "min": "2020-01-01", "renderCondition": "", "helptext": "Seleccione la fecha del evento", "errortext": "Fecha del evento no puede ser menor a la fecha de ingreso del animal al predio.", "options": [], "formulla": "", "value": " ", "validateCondition": "daysBetweenDates('#_ELEMENT.data.ani_diain#', '#ev_salud.salud_date#', 'dd-MM-yyyy');cond($result > 0)", "key": "salud_date", "validate": true, "id": 1, "update": "", "defaultColor": "", "activeColor": "", "decimals": "", "dataSource": "" }, {..............
8. Global
La variable
GLOBAL
se utiliza para mantener valores fuera del flujo, permitiendo su acceso en cualquier paso del proceso. Normalmente, los valores dentro de un flujo de trabajo se buscan con la nomenclatura #_TRIGGER.KEY_SECCION.KEY_CAMPO# o #_TASK.KEY_TAREA.KEY_SECCION.KEY_CAMPO#
.Uso de las variables GLOBAL
En casos especiales, como cuando el flujo retrocede a un paso anterior (ver diagrama abajo), se necesita una variable
GLOBAL
para mantener la consistencia de ciertos valores. Por ejemplo, el "Título de la solución" se crea en el TRIGGER
, se muestra en T2
, y puede modificarse en T3
. Para asegurar su consistencia, esta variable debe mantenerse fuera del flujo.Configuración de una variable GLOBAL
Las variables
GLOBAL
se configuran en el objeto condition
, dentro de completeCondition
en el head
del template
. Las variables globales deben tener la siguiente estructura, sin ##
y utilizando ->>
:global(key_seccion.key_campo ->> _GLOBAL.nombre_variable)
"template": { "head": { "completeCondition": { "condition": "global(identi.nombre ->> _GLOBAL.nombre) && global(estado.estado ->> _GLOBAL.estado) && global(estado.motivo_cierre.id ->> _GLOBAL.motivo_estado_id) && global(catego.catego_0.id ->> _GLOBAL.catego_0_id) && global(catego.catego_1.id ->> _GLOBAL.catego_1_id)", "message":"" }, "automatedMapping": false, "debugMode": true, "elementId": "", "elementKey": "", "titleAcive": false, ...} }
Uso de la Variable GLOBAL
Una vez creada y guardada correctamente, la variable
GLOBAL
puede usarse en cualquier paso del flujo. En el ejemplo el objeto formulla
está llamando a la variable _GLOBAL
denominada “nombre”.{ "visible": true, "max": "", "errortext": "", "query": "", "update": "", "label": "Nombre de la solución", "type": "LABEL", "callRefresh": false, "regex": "", "min": "", "defaultColor": "", "activeColor": "", "renderCondition": "", "helptext": "", "decimals": "", "options": [], "formulla": "js('#_GLOBAL.nombre#')", "dataSource": "", "id": 0, "value": "", "key": "nombre", "validate": false }
Sobrescribir una Variable GLOBAL en campo STRING
Es posible sobrescribir una variable
GLOBAL
con otro valor, configurándola en el value
en lugar de formulla
y debe estar configurada la variable GLOBAL
en el condition
, como en el primer ejemplo.{ "visible": true, "max": "100", "errortext": "", "query": "", "update": "", "label": "Nombre de la solución", "type": "STRING", "callRefresh": false, "regex": "", "min": "0", "defaultColor": "", "activeColor": "", "renderCondition": "", "helptext": "", "decimals": "", "options": [], "formulla": "", "dataSource": "", "id": 0, "value": "#_GLOBAL.nombre#", "key": "nombre", "validate": false }
Usar Variables GLOBAL en Campos SELECTION
Para preseleccionar una opción guardada en una variable
GLOBAL
en un campo tipo SELECTION
, se usa la función selectId()
en el objeto formulla
.{ "visible": true, "max": "", "errortext": "", "query": "custom.MOTI_EST_SOLU", "update": "", "label": "Motivo del estado", "type": "SELECTION", "callRefresh": true, "regex": "", "min": "", "defaultColor": "", "activeColor": "", "renderCondition": "cond('#estado.estado#' == 'Retirado')", "helptext": "", "decimals": "", "options": [], "formulla": "selectId(#_GLOBAL.motivo_estado_id#) ->> _GLOBAL.motivo_estado_id", "dataSource": "", "id": 0, "value": "", "key": "motivo_cierre", "validate": false }
9. Formulla
Se utiliza para realizar cálculos, funciones matemáticas, o realizar operaciones.
Funciones de String
Funciones | Ejemplo de uso | Descripción |
subStr(<String>, <int from>, [int to]) | subStr('Hola, como estás?',7,4) = 'como' | Corta un String con los parámetros from (comenzando desde 0) y opcionalmente to . |
strLeng(<String>) | ㅤ | Retorna el largo de un String . |
strUp(<String>) | ㅤ | Convierte todos los caracteres de un String a mayúscula. |
strLow(<String>) | ㅤ | Convierte todos los caracteres de un String a minúscula. |
strReplace(<String>,<String>,<String>) | strReplace('Hola @nombre@','@nombre@','Juan') = 'Hola Juan' | Reemplaza un valor dentro de un String . |
strIndexOf(<String>,<String>) | strIndexOf('Hola Juan','Juan'): 5 | Retorna la posición de un String dentro de otro String , partiendo desde 0. |
strTrim(<String>) | ㅤ | Quita los espacios en blanco del comienzo y el final de un String . |
Funciones de fecha
Funciones | Ejemplo de uso | Descripción |
currentDate | “getCurrentDate()” | Retorna la fecha actual en el formato predeterminado del sistema. |
getTime(<String>) | "getTime('2024-08-01')" | Retorna el valor epoch de una fecha string determinada. |
getNowTime() | "getNowTime()" | Retorna la fecha / hora actual del sistema en un valor de tipo EPOCH . |
newDate | "js('#cambio_diio.date_reing#' !== '' ? (new Date().getTime()) - (new Date('#cambio_diio.date_reing#').getTime()) : 0) / (1000*60*60*24)" | Calcula la diferencia en días entre la fecha actual y una fecha específica proporcionada. |
getDate(<String>, [String format]) | "getDate('08-08-2024', 'dd-MM-yyyy')" | Retorna un valor de tipo Date , a partir de una fecha String . Opcionalmente enviando el formato en que se encuentra. |
dateFormat(<Date>, <String format>) | “dateFormat(<Date>, 'dd-MMM-yy HH:mm:ss')” | Retorna una fecha formateada a partir de un valor tipo Date . |
dateFormatLocale(<Date>, <String>, <String>, <String>) | “dateFormatLocale(<Date>, 'dd-MMM-yy HH:mm:ss', 'ES', 'cl')” | Retorna una fecha / hora correspondiente a una localidad en formato ISO 639 |
getNowDate() | ㅤ | Retorna la fecha / hora actual del sistema en un valor de tipo Date . |
addSecconds(<Date>, <int>) | ㅤ | Suma segundos a una fecha/hora determinada. |
addMinutes(<Date>, <int>) | ㅤ | Suma minutos a una fecha/hora determinada. |
addHours(<Date>, <int>) | ㅤ | Suma horas a una fecha/hora determinada. |
addDays(<Date>, <int>) | ㅤ | Suma días a una fecha/hora determinada. |
addMonts(<Date>, <int>) | ㅤ | Suma meses a una fecha/hora determinada. |
addYears(<Date>, <int>) | ㅤ | Suma años a una fecha/hora determinada. |
daysBetweenDates(<String>,<String>, [String format]) | "getDate('#reingani.baja_date#');dateFormat($result,'yyyy-MM-dd');daysBetweenDates($result,'#reingani.date_reing#');js($result < 0? $result * -1: $result)", | Retorna los días entre dos fecha/hora notificadas en formato String , opcionalmente informando el formato en que se encuentran. |
secondsBetweenDates(<String>,<String>) | ㅤ | Retorna los segundos entre dos fecha/hora notificadas en formato String . |
secondsBetweenTimes(Long, Long) | ㅤ | Retorna los segundos entre dos valores EPOCH . |
minBetweenDates(<String>,<String>) | ㅤ | Retorna los minutos entre dos fecha/hora notificadas en formato String . |
elapsedTime(<Long>) | ㅤ | Retorna los milisegundos transcurridos entre un valor EPOCH y el momento actual. |
dateCompare(<String>,<String>, [String format]) | ㅤ | Retorna la diferencia entre dos fechas/hora notificadas en String , opcionalmente informando el formato en que se encuentran. Si las dos fechas son iguales, la respuesta será 0. Si la de la izquierda es menor, será -1 y si la derecha es mayor, será 1. |
calculateAge(>String>) | ㅤ | Calcula la edad con la fecha informada por parámetro, en formato String . |
Otras funciones
Funciones | Ejemplo de uso | Descripción |
math (<String>) | "math(((#descrip_compra.kgpredio_buy# / #descrip_compra.kgtot_buy#) - 1)*100);js($result.toFixed(2) + '%')", | Realiza cálculos matemáticos específicos, como porcentajes, sumas, restas o diferencias relativas. |
js(<String>) | "js('#_ELEMENT.data.animal_cod#')" | Ejecuta una línea de código Javascript, retornando su resultado. En este caso se aplica a un Actor ( ELEMENT ), trayendo el valor en base de datos (data) del atributo “animal_cod” . |
selectId() | "selectId('#_GLOBAL.matader.id#') ->> _GLOBAL.matader_id", | Selecciona un ID específico de un elemento global. |
calcStockExpenses(String(query), String(price field), String(remaining field), int(required quantity)) | "calcStockExpenses('element.LOIT[?<@.loit_item_cod == '#peso_consumo.ingred1.key#'>]','loit_unitgto','loit_stock', 0#peso_consumo.peso_ingred1#) ->> _GLOBAL.stock1", | Calcula los gastos de stock basándose en criterios específicos, como el peso del ingrediente. No se pueden ocupar paréntesis dentro de la query . |
numberFormat(<Double>) | "numberFormat(#_GLOBAL.stock0.price#)" | Retorna un número formateado en #,##0.00. |
toFixed(<number>) | js($result.toFixed(2) + '%') | El resultado lo retorna con dos decimales y en porcentaje. |
elevenModuleValidate(<String>) | elevenModuleValidate('13488595-6') = false | Valida un RUT chileno o un número con dígito verificador, basado en la función Módulo 11. |
cond(<String>) | "cond(#tipo_pesaje.decision# == true || #tipo_pesaje.decision# == 1)" | Evalúa una condición lógica. |
forceEval: fx1; fx2 | "formulla": "forceEval: js('#section.field.key#')" | Si la fórmula parte con forceEval : se evaluaron el resto de funciones aun si no se han reemplazado todos los parámetros. Si #section.field.key# no se ha reemplazado, la función se evalúa igual, resultando el value y las propiedades correspondientes del caché con '#section.field.key#' . |
fallbackFx(dFx1; dFx2) <-> fx1; fx2 | "formulla": "fallbackFx(js('null')) <-> js('#section.field.key#')" | Si la formula parte con fallbackFx se separa la formula en 2 partes, la parte fallback (izquierda) que es lo que está dentro del paréntesis de fallbackFx antes del <-> y la parte default (derecha) que es lo que está después del <->
Si la parte default tiene todos los parámetros reemplazados, entonces se evalúa esa parte de la fórmula. Si la parte default no tiene todos los parámetros reemplazados, entonces se evalúa la parte fallback. Si #section.field.key# no se ha reemplazado, se evalúa el js('null') , resultando el value y las propiedades correspondientes del caché con 'null'. |
10. Deshacer (Undo)
La función deshacer permite eliminar los flujos creados devolviendo los cambios efectuados en la base de datos. Si el actor en cuestión fue modificado por varios flujos y se intenta borrar un flujo anterior Z, todos los cambios efectuados desde Z se deshacen.
Para que esta funcionalidad se ejecute correctamente, se deben considerar estas dos configuraciones:
- En el Perfil de usuarios: Perfil → Funciones → Trabajo → Escritorio → Las casillas “Puede deshacer flujo” y “Puede deshacer flujo con múltiples transacciones” deben estar marcadas.
- En el Formulario: A través de una llave colocada en el JSON del formulario como botón llamado
“undoButton”: true
.
11. Sequence
El tag
"_SEQUENCE"
genera un número secuencial único para cada organización, lo que permite asignar un número propio a cada flujo, útil para crear casos como órdenes de trabajo, guías de despacho, lotes de compra, etc.Para usarlo, simplemente coloca el tag en el título del flujo de esta manera:
#_SEQUENCE.<nombre_de_la_secuencia>#
. Por ejemplo: "Orden de trabajo ##_SEQUENCE.ot#"
.El "nombre_de_la_secuencia" se creará automáticamente si no existe, permitiendo tener múltiples secuencias por organización. Este número puede seguir utilizándose dentro del flujo de la misma forma:
#_SEQUENCE.<nombre_de_la_secuencia>#
, por ejemplo: #_SEQUENCE.ot#
o mediante la variable #_FLOW.publicId#
.Ten en cuenta que, aunque puedes usar más de una secuencia en el título del flujo, no es recomendable. Esto se debe a que el ID público del flujo será el último tag de secuencia utilizado. Por ejemplo, en
"Orden de trabajo ##_SEQUENCE.ot# -> #_SEQUENCE.id_generacion#"
, el ID público será #_SEQUENCE.id_generacion#
.En el siguiente ejemplo, en el formulario de tipo
TASK
, se nombra al _SEQUENCE.lote
, que se generó al ejecutarse el "#_TRIGGER._SEQUENCE.lote#"
{ "code": "FOINGANI2", "userId": 391, "name": "Ingreso a predio", "operationId": 15, "type": "TASK", "icon": "0xf817;#3FC633", "duration": 0, "flowTemplateCode": "FLUINGANI", "operationAreasTrigger": [57], "template": { "head": { "automatedMapping": false, "debugMode": false, "elementId": "", "elementKey": "", "titleAcive": false, "output": { "query": "", "active": true, "fields": [ {"label": "Lote asignado", "value": "#_TRIGGER._SEQUENCE.lote#" } ] }, .................
12. Secciones dinámicas
Para que aparezcan igual número de secciones que elementos seleccionados en un campo de tipo
MULTIPLE
, sigue estos pasos:- Primero, asegúrate de tener una sección con un campo de tipo
MULTIPLE
.
- Al configurar las nuevas secciones que deseas mostrar, ten en cuenta dos elementos:
key
yquery
. key
: Agrega@id@
al final del nombre del key para que cada sección sea única (por ejemplo:asistentes@id@
).query
: Configura la query de la sección delMULTIPLE
de la siguiente manera: la query original seguida de[@.id in [#keysección.keycampo.ids#]]
.
- A los campos dentro de estas nuevas secciones, también agrega
@id@
al final de sus keys.
Ejemplo: Si deseas que aparezca una sección por cada colaborador seleccionado en el
MULTIPLE
, tu query podría ser custom.COLABORADOR
. En cada sección, podrías mostrar su nombre y pedirles que firmen.Esta configuración se ve de la siguiente manera, al seleccionarse dos colaboradores, aparecen dos campos tipo
SIGNATURE
para que cada uno pueda firmar.Tabla de contenido
Configuraciones avanzadas1. Regex2. AutomatedMapping3. Tipos de Datasources4. QueryClonesConfiguraciónVariaciones en la configuración5. DebugMode6. Render ConditionSección del formularioCampo del formulario7. Validaciones de datoscompleteConditionvalidateCondition8. GlobalUso de las variables GLOBALConfiguración de una variable GLOBALUso de la Variable GLOBALSobrescribir una Variable GLOBAL en campo STRINGUsar Variables GLOBAL en Campos SELECTION9. FormullaFunciones de StringFunciones de fechaOtras funciones10. Deshacer (Undo)11. Sequence12. Secciones dinámicas