Esta documentación está en fase de desarrollo y puede contener errores.

Recetas de scripts

Patrones de script listos para adaptar, extraídos del comportamiento real de las secciones del núcleo Ready-To-Go de Dinaup.

Cada receta resuelve una necesidad concreta con un script real: son los mismos patrones que ejecutan las secciones del núcleo de Dinaup (Ventas, Tareas de Proyectos, líneas de factura…), adaptados para que los copies y cambies los campos por los tuyos. Los conceptos (eventos, ámbitos, tipos) están en Scripts y eventos; la sintaxis de C. en el registro del formulario.

Un detalle que verás repetido: salir corta la ejecución del script en ese punto. Es la guarda habitual para salir pronto cuando el script no aplica.

Rellenar valores por defecto al iniciar un alta

Evento: Formulario para agregar iniciado — se dispara al abrir el formulario de un registro nuevo, antes de que el usuario escriba.

@ La clave definitiva la asigna el servidor al guardar
C.Clave = 'DRAFT'

F.Field_SetFocus(S.Fields.TareasDeProyectos.Resumen.ID, 0)

@ La tarea hereda el tipo inicial definido en el flujo del proyecto
C.ReferenciaTipo = F.GetRowById(S.Sections.TiposDeTareaDeProyectos.ID, C.ReferenciaProyecto.ReferenciaFlujo.ReferenciaTipo)

@ Y el bono de horas del proyecto, si no trae uno
if C.ReferenciaBono = ''
    C.ReferenciaBono = F.GetRowById(S.Sections.BonosHoras.ID, C.ReferenciaProyecto.ReferenciaBono)
    C.ImporteBonoPrecioHorasinImpuestos = C.ReferenciaProyecto.ImporteBonoPrecioHorasinImpuestos
end if

Así arranca una tarea de Proyectos: foco en el campo que toca escribir primero y los campos heredados del proyecto ya puestos.

Autorrellenar campos al elegir una relación

Evento: Campo cambiado, sobre el campo de relación. Al seleccionar el cliente, la venta copia sus condiciones y calcula el vencimiento.

txt condicionesDePago = C.ReferenciaCliente.CondicionesPagoVenta
num condicionesDePagoDias = C.ReferenciaCliente.PlazoDiasCobroVentas

if v.condicionesDePago <> ''
    C.CondicionesDePago = v.condicionesDePago
end if

if v.condicionesDePagoDias <> 0 or v.condicionesDePago <> ''
    C.FechaDeVencimiento = F.Date_AddDays(D.DatosEspeciales.FechaActual, v.condicionesDePagoDias)
end if

El script lee la ficha del cliente a través de la relación y solo pisa los campos cuando la ficha aporta valor. El autorrellenado declarativo cubre el caso simple (copiar campo a campo); el script entra cuando hay condiciones o cálculo por medio.

Derivar campos cuando cambia el estado

Evento: Campo cambiado, sobre el campo de estado. El registro mantiene solos sus indicadores y fechas reales.

if C.ReferenciaEstado.EstadoTarea = S.Enums.tareaestado.enproceso
    C.EnProceso = 1
    ¿C.FechaInicioConfirmado = '' ? C.FechaInicioConfirmado = D.DatosEspeciales.FechaActual
else
    C.EnProceso = 0
end if

@ Volver al backlog borra la fecha de inicio real
if C.ReferenciaEstado.EstadoTarea = S.Enums.tareaestado.backlog or C.ReferenciaEstado.EstadoTarea = S.Enums.tareaestado.pendiente
    C.FechaInicioConfirmado = ''
end if

¿C.ReferenciaEstado.EstadoTarea = S.Enums.tareaestado.completado ? C.ProgresoPorciento = 100

La comparación no es contra el nombre del estado, sino contra el enum de su ficha: el usuario puede renombrar estados sin romper el script.

Bloquear el guardado si algo no cuadra

Evento: Antes de aceptar. Es el último control antes de que el registro se guarde: si la validación falla, F.CancelEvent() lo impide.

if C.ReferenciaDepartamento <> '' and C.ReferenciaSubdepartamento <> ''
    if C.ReferenciaSubdepartamento.ReferenciaDepartamentoQuePertenece <> C.ReferenciaDepartamento
        F.MsgBox('El subdepartamento seleccionado no pertenece al departamento.', 1)
        F.CancelEvent()
    end if
end if

El mensaje dice qué está mal y el guardado no ocurre. El segundo parámetro de F.MsgBox es la acción en emulación REST, para cuando el script lo dispara una escritura por API en vez de un usuario; ver funciones de interacción.

Pedir confirmación en vez de bloquear

Evento: Antes de aceptar. Cuando la situación es sospechosa pero puede ser legítima, pregunta en lugar de prohibir.

if C.ImportePrecioMinimoUnidad > 0 and C.ImportePrecioMinimoUnidad > C.ImportePrecioUnidad
    if F.PromptYesNo('Precio demasiado bajo', 'El precio de venta por unidad es inferior al precio de venta mínimo. ¿Desea continuar?', 1) = 0
        F.CancelEvent()
    end if
end if

Así protegen las líneas de venta el precio mínimo: vender por debajo se permite, pero nunca sin querer.

Un botón que crea un registro relacionado

Evento: Click, sobre un campo que actúa como botón. Guarda el registro actual y abre el alta del relacionado con los campos clave ya puestos.

F.Save()

if C.ReferenciaTipo.SeLePuedeImputarTiempo = 0
    F.MsgBox('No se le puede imputar tiempo al tipo ' + C.ReferenciaTipo.TextoPrincipal, 1)
else
    F.AddElement_Begin(S.Sections.ActividadEnTareasDeProyectos.ID)
    F.AddElement_SetValue(S.Fields.ActividadEnTareasDeProyectos.ReferenciaTarea.ID, C.ID)
    F.AddElement_SetValue(S.Fields.ActividadEnTareasDeProyectos.ReferenciaProyecto.ID, C.ReferenciaProyecto)
    F.AddElement_Commit()
end if

El F.Save() inicial importa: un registro nuevo aún no tiene C.ID utilizable hasta que se guarda. Este patrón (guardar, validar, AddElement_BeginSetValueCommit) es el botón "Agregar" de media interfaz de Dinaup: tickets desde el proyecto, actividades desde la tarea, asientos desde el cobro.

Filtrar las opciones de un desplegable

Evento: Aplicar filtro desplegable, sobre el campo de relación. Antes de mostrar opciones, el script acota qué registros aparecen.

F.Field_ListDropdownWarning('Mostrando direcciones activas del cliente seleccionado.', 1)
F.Field_DropdownApplyFilter(S.Fields.DireccionesDeEnviosBase.ReferenciaEntidad.ID, '=', C.ReferenciaCliente)
F.Field_DropdownApplyFilter(S.Fields.DireccionesDeEnviosBase.Activa.ID, '=', 1)

Los filtros se encadenan y pueden depender de otros campos del formulario: aquí las direcciones se filtran por el cliente ya elegido. Es el evento más usado del núcleo: casi todo desplegable filtra por activos, por tipo o por el registro padre.

Bloquear campos con el motivo a la vista

Evento: Tick de recálculo o Recalcular listado. F.Field_SetLockedWithReason bloquea o desbloquea según una condición, y el usuario ve el porqué al pasar por el campo.

txt motivo = 'Únicamente puede seleccionar 1: Recurso o Producto'
num bloquearRecurso = 0
num bloquearProducto = 0

¿C.ReferenciaProducto <> '' ? v.bloquearRecurso = 1
¿C.ReferenciaRecurso <> '' ? v.bloquearProducto = 1

F.Field_SetLockedWithReason(S.Fields.VentasIngresosLista.ReferenciaProducto.ID, v.motivo, v.bloquearProducto)
F.Field_SetLockedWithReason(S.Fields.VentasIngresosLista.ReferenciaRecurso.ID, v.motivo, v.bloquearRecurso)

El tercer parámetro activa (1) o levanta (0) el bloqueo, así que el mismo script sirve para los dos sentidos: se ejecuta en cada tick y el formulario siempre queda coherente. La variante F.Field_SetRequiredWithReason hace lo mismo con la obligatoriedad.

Recalcular un importe mientras se edita

Evento: Tick de recálculo. Mantiene un campo derivado al día sin esperar al guardado.

if C.TiempoDeActividad_AutoCalculo = 0 or C.ImporteBonoPrecioHorasinImpuestos = 0
    C.ImporteBonoCosteDeTareaACliente = 0
else
    @ Minutos de actividad a precio/hora del bono
    C.ImporteBonoCosteDeTareaACliente = F.Round(C.TiempoDeActividad_AutoCalculo * (C.ImporteBonoPrecioHorasinImpuestos / 60), 2)
end if

Redondea siempre los importes derivados (F.Round(..., 2)): el usuario ve el mismo número que se guardará.

Ofrecer autocompletado en un campo de texto

Evento: Formulario Cargado. Sugiere valores canónicos en un campo de texto libre, sin convertirlo en desplegable cerrado.

F.Field_TextAddAutoComplete(S.Fields.ActividadesDeEmpresas.Clave.ID, '1 - Actividades sujetas al Impuesto sobre Actividades Económicas')
F.Field_TextAddAutoComplete(S.Fields.ActividadesDeEmpresas.Clave.ID, '2 - Actividades sujetas al IAE (Profesionales y Artísticas)')
F.Field_TextAddAutoComplete(S.Fields.ActividadesDeEmpresas.Clave.ID, '3 - Arrendadores de Locales de Negocios y garajes')

El usuario puede escribir cualquier cosa, pero las opciones esperadas están a un clic. En el núcleo alimenta desde claves de la AEAT hasta tipos de vía de direcciones.


Scripts y eventosC.: el registro del formularioFunciones (F.)Buenas prácticas de DinaScript

On this page